2012-05-17 33 views
9

F#既有輸入類型也有非類型化的代碼引用,我想知道哪個用例會選擇哪一個用例?何時支持在F#中輸入未鍵入的引號?

區別僅僅是便利性和無類型和鍵入的引用是否可以在所有情況下轉換爲每個引用或是鍵入引號e。 G。可能有無類型引用的子集?

是否有任何只適用於打字的例子,但不適用於無類型的引語 - 或者相反?

回答

7

一般來說,我建議儘可能使用打字引號。像往常一樣,這些類型將允許您靜態地執行一些正確性條件,否則這些條件可能會在運行時導致失敗。試想一下:

let one = <@@ "one" @@> 
// exception at runtime 
let two = <@@ 1 + %%one @@> 

,而不是

let one = <@ "one" @> 
// compile time error: the type 'string' does not match the type 'int' 
let two = <@ 1 + %one @> 

此外,有時無類型的報價需要在案件的更多類型的註釋,其中鍵入報價並不:

// ok 
let l = <@ [1] @> 
let l2 = <@ List.map id %l @> 

// fails at runtime (obj list assumed instead of int list) 
let l = <@@ [1] @@> 
let l2 = <@@ List.map id %%l @@> 

// ok 
let l = <@@ [1] @@> 
let l2 = <@@ List.map (id:int->int) %%l @@> 

不過,如果你是用引號構建非常通用的東西,可能無法使用鍵入的引號(例如,因爲這些類型不是靜態已知的)。從這個意義上說,無類型的引用給你更多的靈活性。

另請注意,根據需要在打字和未打字的報價之間進行轉換非常容易(將Expr<_>改爲Expr以從打字轉換爲無類型;使用Expr.Cast轉換爲其他方式)。

3

通常,消費者的報價處理庫將使用打字引號。而報價處理作者需要使用無類型的報價。

也就是說,你不會經常直接創建一個使用(<@@ @@>)操作類型化的報價。但是,爲了使用不同的F#核心庫活動模式,如Quotations.Patterns模塊遞歸處理一個報價,你在他們的類型化形式的報價工作。

注意Expr<'T>延伸Expr並沒有太大的信息真的添加到它。也就是說,鍵入的引用實際上只是一種幻覺,所有捕獲的元數據都位於Expr對象中,並且僅在運行時纔可用。

相關問題