考虑以下 F#:-
type TestClass() =
let getValFromMap m k = Map.find k m
let addToMap map k i = map |> Map.add k i
let mutable someMap : Map<string,int> = Map.empty
let getValFromMapPartial key = getValFromMap someMap key
let getValFromMapPartialAndTacit = getValFromMap someMap
member this.AddThenGet() =
someMap <- addToMap someMap "A" 10
let value = getValFromMapPartial "A"
printfn "Value from partial = %i" value // prints out
let value = getValFromMapPartialAndTacit "A" // throws
printfn "Value from partial and tacit = %i" value
[<EntryPoint>]
let main argv =
let test = TestClass()
test.AddThenGet()
0
在我看来,功能getValFromMapPartial
和是相同的。getValFromMapPartialAndTacit
F# 说它们具有完全相同的类型:(string -> int)
. 然而它们的行为非常不同,它们的编译方式也非常不同。使用 dotPeek 进行反编译,我看到这getValFromMapPartial
是一个方法,而getValFromMapPartialAndTacit
它是一个在 ctor 中初始化的字段。
F# 不会抱怨getValFromMapPartialAndTacit
,即使在最高警告级别(在 VS 2012 和 2013 中)。然而在我上面的示例中调用这个函数失败了,大概是因为它已经包装了初始的空版本someMap
,尽管它是可变的。
为什么这两个功能有区别?F# 是否应该警告默认/无点版本可能会失败?