Dot-Net
在 F# 中使用 Lambda 表達式創建委託
為什麼…
type IntDelegate = delegate of int -> unit type ListHelper = static member ApplyDelegate (l : int list) (d : IntDelegate) = l |> List.iter (fun x -> d.Invoke x) ListHelper.ApplyDelegate [1..10] (fun x -> printfn "%d" x)不編譯,當:
type IntDelegate = delegate of int -> unit type ListHelper = static member ApplyDelegate (l : int list, d : IntDelegate) = l |> List.iter (fun x -> d.Invoke x) ListHelper.ApplyDelegate ([1..10], (fun x -> printfn "%d" x))做?
唯一的區別是在第二個中,
ApplyDelegate將其參數作為一個元組。此函式接受太多參數,或在不期望函式的上下文中使用
我沒有查看規範來確認,但我猜測從“lambda”到“命名委託類型”的隱式轉換只發生在“成員呼叫”中。
您始終可以使轉換顯式:
ListHelper.ApplyDelegate [1..10] (IntDelegate(fun x -> printfn "%d" x))(錯誤診斷很差;我會送出一個錯誤。)
編輯:
對於笨蛋…
是的,規範說
8.13.6 成員呼叫中的類型導向轉換 如方法應用解決方案(參見第 14.4 節)中所述,在方法呼叫中應用了兩種類型導向的轉換。
如果形式參數是委託類型 DelegateType,而實際參數在語法上是函式值 (fun …),則該參數被解釋為好像它已被編寫為 new DelegateType(fun …)。
lambda 僅在“成員呼叫”時自動轉換為委託類型。在 curried 成員的情況下,傳遞的第一個參數是成員呼叫,但隨後返回一個函式值以應用第二個參數,並且函式呼叫沒有此隱式轉換規則。