F 程式構造

2022-02-23 15:45:35 字數 3719 閱讀 5041

大多語言比如c#,需要乙個明確的入口點,這就是最常見的main函式。但是我們的f#程式目前為止還沒有乙個特別明確的標記來說明程式要從這兒開始。在f#裡,對乙個個單一的檔案程式來說(.fs),**檔案裡的內容自上而下已經可以執行(不需要定義乙個明確的main方法)

然而對多檔案的工程來說,**需要被分成乙個個叫做modules或者namespaces的模組單元裡去。

下面先介紹modules

目前為止我們所有的**都寫在module裡,預設情況下,f#將我們的**放置在乙個和**檔案名字相同並將首字母大寫的匿名module裡。所以,如果我們有乙個叫做value1的值,我們的**檔案是file1.fs,那麼就可以用合法的全路徑來指向它:file1.value1。

建立乙個modules

我們可以在**檔案的第一行使用關鍵字module明確的指定**的module。

然後,每乙個變數,函式,或者是型別定義將都屬於這個module。

例子:

1

module

alpha

//定義乙個模組alpha

2letx=1

//使用alpha.x

巢狀的modules

modules是可以巢狀的。定義乙個巢狀的module,也是使用module關鍵字。

在定義巢狀的module時一定要注意縮排,這將直接影響到module的巢狀級別。下面演示了有縮排和無縮排的module

1

module

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那樣巢狀。那麼替代的做法就是可以在同乙個檔案裡定義多個命名空間。

例子:

1

namespace

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後將看不到任何輸出,因為他執行的是你新新增的檔案。而你的新檔案裡面還沒有**。

先看一下下面乙個簡單的程式。

1

2let

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型別的值,以表示程式退出**

重寫上面的**就是:

1

open

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...