大多語言比如c#,需要乙個明確的入口點,這就是最常見的main函式。但是我們的f#程式目前為止還沒有乙個特別明確的標記來說明程式要從這兒開始。在f#裡,對乙個個單一的檔案程式來說(.fs),**檔案裡的內容自上而下已經可以執行(不需要定義乙個明確的main方法)
然而對多檔案的工程來說,**需要被分成乙個個叫做modules或者namespaces的模組單元裡去。
下面先介紹modules
目前為止我們所有的**都寫在module裡,預設情況下,f#將我們的**放置在乙個和**檔案名字相同並將首字母大寫的匿名module裡。所以,如果我們有乙個叫做value1的值,我們的**檔案是file1.fs,那麼就可以用合法的全路徑來指向它:file1.value1。
建立乙個modules
我們可以在**檔案的第一行使用關鍵字module明確的指定**的module。
然後,每乙個變數,函式,或者是型別定義將都屬於這個module。
例子:
1module
alpha
//定義乙個模組alpha
2letx=1
//使用alpha.x
巢狀的modules
modules是可以巢狀的。定義乙個巢狀的module,也是使用module關鍵字。
在定義巢狀的module時一定要注意縮排,這將直接影響到module的巢狀級別。下面演示了有縮排和無縮排的module
1module
utilities2//
將使用utilities.conversionutils.inttostring
3module
conversionutils =
4let
inttostring (x :
int)= x.tostring()56
module
convertbase=7//
將使用utilities.conversionutils.convertbase.converttohex
8let
converttohex x = sprintf "%x
"x9//
將使用utilities.conversionutils.convertbase.converttooct
10let
converttooct x = sprintf "%o
"x1112
module
datatypes =
13//
將使用utilities.datatypes.point
14type
point = point
offloat
* float
* float
命名空間
modules的替代品那麼就是namespaces了。。命名空間也是像module一樣組織**,僅僅的不同之處是無法包含值,而只能有型別定義。並且命名空間不能像modules那樣巢狀。那麼替代的做法就是可以在同乙個檔案裡定義多個命名空間。
例子:
1namespace
playingcards2//
playingcards.suit
3type
suit =4|
spade5|
club6|
heart78
9type
playingcard =10|
ace
ofsuit11|
king
ofsuit12|
queen
ofsuit13|
jack
ofsuit
1415
namespace
playingcards.poker
1617
18type
pokerplayer =
可能在f#裡namespaces和modules看上去都不太習慣。這裡想說的是modules
是最佳化的解決方案,至少目前是這樣。從另一方面說命名空間可能將用於以後大規模的專案。
下面還有f#程式是如何啟動的還沒寫。晚上補上。
下面討論f#程式的啟動
f#的啟動順序是從你新新增的fs檔案開始。比如說最開始的f#專案中有乙個program.fs,如果你這裡面寫了**,f5後可以執行,你將會看到輸出結果,此時你再重新新增乙個空白fs檔案,直接f5後將看不到任何輸出,因為他執行的是你新新增的檔案。而你的新檔案裡面還沒有**。
先看一下下面乙個簡單的程式。
12let
numbers = [
1.. 10]
3let
square x = x * x
4let
squarednumbers = list.map square numbers
5printfn
"squarednumbers = %a
"squarednumbers
6open
system
7printfn
"(press any key to continue)"8
ignore(console.readkey(
true
))
這段**第二行定義了乙個numbers函式,他將產生乙個[1;2;3;4;5;6;7;8;9;10]這樣乙個陣列
第三行定義了乙個square函式,這個函式會返回乙個引數的乘積運算
第四行的**呼叫了list.map函式,這個函式的意思是產生乙個新的集合,其中的元素是將給定的函式應用於集合的每乙個元素的結果。
那麼在具體到這行**裡面就是將返回由函式numbers產生的1到10的元素分別做平方運算的結果。也就是[1;4;9;...100]
這種執行方式如果看不習慣會覺得很混亂很彆扭,為什麼要從最後乙個檔案開始執行,這很讓人受不了。下面我們看看如何使用module執行乙個真正的程式。
當然在f#裡我們也可以使用特性來寫類似main函式的方法來定義程式的入口點。
為了執行通過,必須確保以下幾點:
1,必須確保是在編譯序列中的最後乙個檔案的最後乙個宣告,並且只能在編譯為.exe時才可以使用。
2,要定義單一的乙個string型別的引數。
3,返回乙個int型別的值,以表示程式退出**
重寫上面的**就是:
1open
system
2[>]
3let
main (args :
string
) =4
letnumbers = [
1.. 10]
5let
square x = x * x
6let
squarednumbers = list.map square numbers
7printfn
"squarednumbers = %a
"squarednumbers
8printfn
"(press any key to continue)")
9console.readkey(true)
|> ignore
10//
return 0
110
現在我們已經知道了f#是如何執行的了,不用在新增乙個新檔案後忽然發現執行不了了,原因就在於此。
以後的章節讓我們用f#寫出更強大的功能!
有問題請在下面提問。我會把所知道的告訴大家。
F 的建構函式
f 的建構函式 f 是.net中的函式程式語言,雖然,為了跟其它.net語言有更好的協作關係,f 本身也有相當的物件導向的功能,但是並不完整,有一些功能限制。譬如,不支援 protected 訪問控制。再如,或算是一種特色,多建構函式中,必須其中乙個為主建構函式,而其他建構函式只能呼叫主建構函式,這...
程式構造方法設計
在專案中用到過一些類似的流程,特做一些總結 在上乙個專案中,當時因為會跟銀行或第三方有大量的互動動作,經過一些考慮,提煉出了一些共同的構造路程。一 每個互動過程包括有支付和同步,特寫出介面pay 支付資料 querypay 同步資料 二 主要的構造類 在構造類中定義構造方法 定義各個步驟的構造方法,...
F 開發環境配置 HelloWorld程式
筆者使用的系統是opensuse tumbleweed,這篇文章的.net開發環境配置方案是dotnet sdk visual studio code 在終端中依次輸入這些命令 opensuse sudo zypper install libicu sudo rpm import wget sudo...