3 1 1 值的宣告和作用域

2021-06-25 12:29:07 字數 2028 閱讀 2970

3.1.1 值的宣告和作用域

我們已經知道,可以使用 let 關鍵字宣告不可變值。但尚未討論值的範圍域(scope),不過很容易用乙個具體的示例來解釋。清單 3.1 非常簡單,但是,在這四行**的後面到底隱藏了多少奧秘,我想你也一定會很驚訝。

清單 3.1 值的作用域 (f#)

let number = 42    [1]

printfn "%d" number

let message = "answer: " +number.tostring()    [2]

printfn "%s" message

清單 3.1 非常簡單:它宣告了兩個值,第二個值[2]是由第乙個值[1]計算出來的;然後,將它們輸出到控制台。這裡,我們著重想說的是值的作用域,即值可以被訪問的**區域。可以預料,值 number 在第一行宣告了以後就可以訪問;而值 message 只在最後一行才可以訪問。可以看一下**,並驗證我們使用的值,都在作用域內,因此,**是正確的。

這段**還說明了另外一件事。清單 3.1 中的示例看上去很像 c# **,[看出相同不難,但能看出不同,就難了。]但要了解 f# 不同的處理**方式才是重要的。在第二章(2.2.4 節),嘗試在 c# 中只用表示式來寫**時,涉及過這個主題。我們知道,如果想讓每個有效 f# **都成為表示式,值繫結必須特別處理。確實,如果用 c# 寫**,實現與清單 3.1 同樣的功能,編譯器會四個語句看作乙個序列。我們現在來看看 f# 是如何理解這段**的。為了演示,我們在語法上做了些小改動(見清單 3.2)。

清單 3.2 有顯式作用域的 let 繫結(f#)

let number = 42 in

printfn "%d" number;   [2]      |

let message =                  |       |

"answer: " + number.tostring() in  |  [1]  |

(                             |       |  [3]

printfn "%s" message           |       |

清單 3.2 最明顯的變化是布局,還有一點值得關注的是引入了關鍵字 in,出現在每個 let 繫結後。如果我們要關閉預設語法,即空白是有意義的1,那麼,新增關鍵字 in 就是必須的;另乙個變化是,跟在let 繫結後的**塊都括在括號中。這樣做是可選的,但它更接近 f# 編譯器對我們所寫**的理解。有趣的是,清單 3.2 中的**仍然是有效 f# **,且與前面的**功能完全相同。有時,我們可能希望**更明確,使用關鍵字 in 和額外的括號,把想要處理的表示式括起來。

清單 3.2 中更明顯的變化,是 let 繫結把值賦給符號,指定在表示式內可以使用這個符號。第乙個 let 繫結宣告了符號 number 表示 42,用於跟在 in 關鍵字後面用括號括起來的表示式中[1],整個 let 繫結就當成是乙個表示式,它返回內部表示式的值。例如,定義值 message 的 let 繫結[3]是返回 printfn結果的表示式,這個函式的返回型別是 unit,因此,整個表示式的結果也是 unit。

注意單獨一行**以let 開始、以 in 結束,不可能是有效的表示式,因為它缺少 let 繫結的主體。因此,必須為主體指定一些表示式。

再乙個有趣的事情是表示式順序。表示式[2]在表示式[3]之前,如你所見,我們在個表示式之間加了分號。分號是 f# 的順序運算子(sequencing operator),它指定分號前面的表示式計算應先計算,後面的後計算。在這個示例中,[2]應該在[3]之前計算。在順序運算子前面的表示式還應該返回 unit,否則返回值也會丟失。

注意使用輕量級語法,就不必使用分號,只要分行就行了。編譯器通過縮排**找到哪些行是表示式,並自動在行尾處插入分號。

到目前為止,我們還是只看到宣告普通值的普通let 繫結,但是,同樣的let  繫結還能用於宣告函式和巢狀繫結,下一節將學習。

1 預設設定是有時也稱為輕量級語法(lightweightsyntax)。f# 還支援相容 ocaml 的語法,它更嚴謹,如我們在這個示例中使用的。本書的後面我們不會使用,如果你想嘗試使用這種語法,在f# 原始檔的開頭新增#light "off" 指令,就可以開啟。

3 11函式 作用域

在python中,乙個函式就是乙個作用域,區域性變數放置在其作用域中 定義完成後,作用域已經生成,呼叫時會根據作用域鏈條向上查詢,無論在哪呼叫,都是按之前定義的作用域了 作用域age 18 deffunc1 print alex deffunc2 print eric return func2 va...

python 變數宣告和作用域

a 3 1.建立name a 2.建立object 3 3.將name 關聯到3 這個object上 name在建立時必須關聯到乙個object name可以在建立以後指向任何乙個object 包括不同型別 全域性變數和區域性變數 1.globals 返回當前模組的全域性變數,locals返回當前所...

變數的宣告和作用域 VB

一 宣告變數 變數在使用前,必須在 中進行宣告,即建立該變數。在使用變數之前,首先需要宣告變數。就是說,必須事先告訴編譯器在程式中使用了哪些變數,及這些變數的資料型別以及變數的長度。這是因為在編譯程式執行 之前編譯器需要知道如何給語句變數開闢儲存區,這樣可以優化程式的執行。宣告變數有兩種方式 隱式宣...