F# 基礎文法—關鍵字和結構[z]

來源:互聯網
上載者:User

原文出處: http://lorgonblog.spaces.live.com/blog/cns!701679AD17B6D310!887.entry

Translated by Mike

我已經寫過很多關於F#的博文,但至今為止還沒有描述過F#語言的基本文法.所以今天我將儘力彌補這個缺憾,描述一些在F# 代碼中常見的一些關鍵字和文法結構.這篇博文不會覆蓋所有的F# 文法,但是差不多能覆蓋75%左右的常見文法.為了使本文儘可能的簡單,我可能故意在整體的準確性上犯一點兒小錯.

#light

大部分的F#檔案以”#light”開頭

(譯者注:在當前的Dev10版本中已經把”#light”設定為預設開啟,所以當前的F#檔案不需要再顯示的調用”#light”)

#light

這個是用來開啟”輕量級文法(lightweight syntax)”選項的.我在這裡不會討論和” 輕量級文法”對應的選項是什麼,因為人們總是使用”輕量級文法”這個選項.而且在下一個F#版本中”” 輕量級文法”將成為預設選項(譯者注:當前的F#版本已經這樣做了). 現在還是要確保”#light”總是出現在F#代碼檔案的開頭.

Comments

共有兩種類型的注釋,看下面的代碼

// a one-line comment

(* a multi-line
   comment (* these can nest *) *)

“open” --開啟一個命名空間

“open”關鍵字是用來開啟一個命名空間或者模組.

// must fully qualify the name System.Console
System.Console.WriteLine("Hello, world!")

// after opening the namespace, don't need to
open System

Console.WriteLine("Hello, world!")

“let” – 定義函數和值

“let” 關鍵字用來定義函數和值.這裡是使用”let”定義值的一些例子:

let x = 42 // immutable, x is always 42
let mutable y = 0 // mutable, can re-assign y's value with <- operator
let z : string = null // ": string" is type annotation to declare type

你很少會用到類型說明(F#是一種類型推斷語言),但是在最後一個例子當中,類型推斷還是很有必要的(如果不使用類型說明,’z’將被推斷為”obj”(System.Object)類型;這裡的類型說明會告訴編譯器我們需要’z’是一個”string”類型).

下面是一些使用’let’定義函數的一些例子:

let F x = x + 1
let G x y = x + y
let G2 (x:float) (y:float) : float = x + y
let H(x,y) = x + y
let rec Kaboom x = Kaboom (x+1)

“F”是帶一個參數的函數.”G”和”G2”有兩個柯裡化的參數(後來”G2”中為參數指定的類型說明和為函數傳回值指定的類型說明,展示了這種文法),但是”H”使用的是元組(tuple)參數;想知道更多關於元組和柯裡化的資訊,你一定得讀一讀這篇博文. 另外,‘let rec’關鍵字可以定義一個遞迴函式.

輕量級文法(lightweight syntax)使空格符/縮排顯得更有意義,而且縮排是界定函數(和其他結構體)範圍最常用的方法.另外,函數可以定義在任何地方.下面這段代碼可以說明以上觀點:

let Area diameter = // define a function
// everything indented under here is the body of "Area"
let pi = 3.14 // define a value inside the function
let Radius d =  // define another function inside here
// this is the body of the "Radius" function
        d / 2.0
let r = Radius diameter
    pi * r * r

// use the function
let answer = Area 5.0

“fun” -- lambda 運算式在這裡是”fun”

“fun”關鍵字是用來定義lambda(匿名函數)的.文法是”fun 參數 -> 函數體”,而且優先規則往往會強制你把所有的定義放在一對小括弧內,請看下面這個例子:

let nums = [1; 2; 3; 4; 5]
let odds = List.filter (fun x -> x%2 = 1) nums
printfn "odds = %A" odds // odds = [1; 3; 5]

在這個例子中,請注意’%’是一個求模操作符,用在這裡是為了確定數字’x’是不是奇數, List.filter是對一個列表應用了斷言的函數(傳回值為布爾型的函數),它返回的是一個通過斷言函數傳回值為真的元素的 一個列表.

“|>” 管道操作符

一個使用非常頻繁的內建操作符就是:pipe. “x |> f” 就是”f x”.因此,上面的例子更習慣於寫成下面這個樣子:

let nums = [1; 2; 3; 4; 5]
let odds = nums |> List.filter (fun x -> x%2 = 1)
printfn "odds = %A" odds // odds = [1; 3; 5]

其實在這個小例子中使用管道操作符並沒有什麼實質性的好處, 但是這個操作符經常用來在一系列具有轉化性功能函數中”傳遞”資料.更詳細的說明請看這裡.

“match” 模式比對

模式比對是一個非常強大的語言特徵,在很多環境下都可以使用它,但是他最常使用的地方是在’match’運算式中.

match expr with
| pat_1 -> body_1
...
| pat_n -> body_n

這個運算式會測試每一個模式,第一個被匹配上的模式後面的方法體會得到執行.最常見的模式包括簡單的代數資料類型,比如可識別聯合(Discriminate Union), 特別是針對一個”列表”或者一個”可選值”的匹配;關於可識別聯合的描述和怎樣針對可識別聯合的匹配請看這篇文章的前半部分.(我最後大概會寫至少兩篇完整的關於模式比對的文章,不過上面的一段和連結文章中的描述對你來說已經足夠了,因為在這你只需要對語言有一個快速的瞭解.).

條件和迴圈

雖然在F#中使用的比在其他語言中用的少(一般會用模式比對和遞迴替代),F#中還是有if-then-else, while迴圈,for迴圈. 由於F#是一門函數式語言,所以這些都屬於帶傳回值的運算式.

下面是if-then-else文法的通式

if cond1 then

expr1
elif cond2 then

expr2
else

expr3

‘elif’和’else’部分是可選的,而且你想使用多少個’elif’(else if)都可以.所有的exprn都必須是同一個類型,這也是整個運算式傳回值的類型.如果’else’部分被省略了,exprn必須是’unit’類型(它是”void”的近親).

While的文法是:

while cond do
expr

整個while運算式總是返回”unit”.在F#語言中並沒有像”break”或者”continue”這樣的東西.

for pat in expr do
bodyexpr

在這裡,expr是一個你可以遍曆的東西(比如: Ienumerable<T>, F#中的seq<’a>),pat是任何一個模式(但是最常見的是一個新的標識符名稱),bodyexpr在遍曆的過程中針對每一個元素執行一遍.舉個例子:

for x in someArray do
    printfn "%d" x

列印出”someArray”中的所有整數. 和’while’一樣,整個’for’運算式返回’unit’類型.

“new” – 用”new”來建立對象

你可以像在C#中一樣使用”new”來建立一個對象.

let x = new System.Uri("http://hello.world/")

然而,在F#中’new’關鍵字通常是一個可選項.

Literals(該詞在翻譯上存在爭議,具體可參閱這裡,本文中為避免誤解,不翻譯該詞)

在F#語言中有很多種Literal,其中最常見的是下面這些:

let b : bool = true // or false
let i : int = 42
let s : string = "hi"
let x : float = 3.14 // "3." same as "3.0"
let ai : int array = [| 1; 2; 3 |] // "int array"=="array<int>"
let lf : float list = [ 1.1; 2.2; 3.3 ] // "float list"=="list<float>"

(這裡所有的類型說明都不是必要的,不過他們對我的講解很有協助.)布爾,整數,字串Literal會像你期待的那樣正常工作.”浮點型”相當於 System.Double, 它是一種包含小數點的數字常量.常數陣列用[|括弧|]來書寫,而列表常量用[括弧]來書寫;他們都使用分號(或者另起一行)來區分集合中的元素.這裡只展示了最常用的一些類型.我將在新的博文中詳細的討論更多F#內建類型.

Exception constructs

F#有一種”try-catch-finally”結構,並且使用C#中的IDisposable.它的基礎文法是:

try
expr
with
| pat_i -> body_i
try
expr
finally
cleanup
use ident = expr

更多描述請看這裡.

還有什麼沒有描述到的?

除了 類型(定義新的類型,類,成員等;包括描述不常見的內建類型)和pervasives(內建操作符和函數),這篇簡介幾乎囊括了95%的F#常用文法結構. 類型和pervasives我打算在我將來的博文中講解.

原帖:http://blog.joycode.com/fscti/archive/2009/10/21/115741.joy

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.