7

したがって、次のコードが与えられます

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# には (暗黙的に) タプル パラメーター、カリー化されたパラメーター、および BCL パラメーターの概念があり、カリー化されたスタイルとタプル スタイルを区別する方法を知っているため、どうすれば 3 番目のスタイルを強制できますか (a la BCL メソッド) )?

これが不明な場合はお知らせください。

4

2 に答える 2

8

TryGetValueには out パラメーターがあるため、F# で同じことを行う必要があります ( でbyrefマークされた を介してOutAttribute):

open System.Runtime.InteropServices 
type MyDict<'K,'V when 'K : equality>() =  // '
    let d = new System.Collections.Generic.Dictionary<'K,'V>()
    member this.TryGetValue(k : 'K, [<Out>] v: byref<'V>) =
        let ok, r = d.TryGetValue(k)
        if ok then
            v <- r
        ok            

let d = new MyDict<string,int>()
let ok, i = d.TryGetValue("hi")
let mutable j = 0
let ok2 = d.TryGetValue("hi", &j)

F# では、サフィックスの out パラメーターを戻り値に自動的に変換できるため、out パラメーターで終わるメソッドを作成するだけで済みます。

于 2010-04-27T22:10:31.017 に答える
4

bool TryXXX(stringToParseOrKeyToLookup, out parsedInputOrLookupValue_DefaultIfParseFailsOrLookupNotFound)個人的には、BCL 全体で使用されているパターンが好きではありませんでした。また、タプルを返す 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 = ()
于 2010-12-06T20:40:09.563 に答える