所以,然后给出以下代码
type MyClass () =
let items = Dictionary<string,int>()
do
items.Add ("one",1)
items.Add ("two",2)
items.Add ("three",3)
member this.TryGetValue (key,value) =
items.TrygetValue (key,value)
let c = MyClass ()
let d = Dictionary<string,int> ()
d.Add ("one",1)
d.Add ("two",2)
d.Add ("three",3)
以下测试代码
let r1,v1 = d.TryGetValue "one"
let r2,v2 = c.TryGetValue "one"
r1,v1行正常工作。 r2,v2线炸弹;抱怨c.TryGetValue必须给出一个元组。有趣的是,在每行中,TryGetValue的签名是不同的。如何让我的自定义实现显示与BCL版本相同的行为?或者,问另一种方式,因为F#具有(隐式)元组参数,curried参数和BCL参数的概念,而且我知道如何区分curried和tuple-style,我怎么能强制第三种样式(a la BCL方法) )?
如果不清楚,请告诉我。
答案 0 :(得分:8)
TryGetValue
有一个out参数,因此您需要在F#中执行相同操作(通过标有byref
的{{1}}):
OutAttribute
F#自动允许您将后缀输出参数转换为返回值,因此您只需要创建一个以out参数结尾的方法。
答案 1 :(得分:4)
就个人而言,我从未喜欢整个BCL使用的bool TryXXX(stringToParseOrKeyToLookup, out parsedInputOrLookupValue_DefaultIfParseFailsOrLookupNotFound)
模式。虽然返回元组的F#技巧很好,但是如果解析或查找失败,我很少需要默认值。事实上,Some
/ None
模式将是完美的(如Seq.tryFind
):
type MyClass () =
let items = System.Collections.Generic.Dictionary<string,int>()
do
items.Add ("one",1)
items.Add ("two",2)
items.Add ("three",3)
member this.TryGetValue (key) =
match items.TryGetValue(key) with
| (true, v) -> Some(v)
| _ -> None
let c = MyClass()
let printKeyValue key =
match c.TryGetValue(key) with
| Some(value) -> printfn "key=%s, value=%i" key value
| None -> printfn "key=%s, value=None" key
//> printKeyValue "three";;
//key=three, value=3
//val it : unit = ()
//> printKeyValue "four";;
//key=four, value=None
//val it : unit = ()