我想我理解這裏發生了什麼,但是我真的很感謝有人對它發生的原因有所瞭解。我有一個S類,它除了別的以外還有一個符號表,它將名稱與類的對象相關聯。所以,在類中,我定義:可變參考單元不適用於靜態成員
static member (names:Map<string,S> ref) = ref Map.empty
...再後來,也是在S,我定義:
member this.addSymbol (table: Map<string,S> ref) (name:string)
table := (!table).Add(name, this)
this
我把這種從其他地方,這樣的:
ignore (s.addSymbol S.names "newname")
...
Inside S.addSymbol我可以看到新的鍵/值被添加到表中,但S.names沒有得到更新。相反,如果我叫addSymbol這樣的:
ignore (
let tmp = S.names
s.addSymbol tmp "newName"
)
然後我可以看到TMP正與新的鍵/值對更新,但仍S.names沒有更新。
下面是我認爲我知道的:ref機制沒有什麼錯 - 它正確地更新了函數內部和外部的指示對象。但是對於靜態成員來說似乎有點奇怪 - 就像,每次都只給我一個相同的靜態引用,而是複製'a',然後爲此創建一個新的引用。
我有這個權利嗎?如果是這樣,爲什麼它這樣做?我能做些什麼來使其表現得更明智?
在此先感謝。
@Vandroiy已經診斷出你的直接問題,但是這裏有一個額外的想法:如果你要改變一個集合,那麼使用標準的.NET可變集合而不是包含一個不可變集合的引用通常會更有意義,你更新到位。在你的情況下,這意味着使用'System.Collections.Generic.Dictionary <_,_>'而不是'Map <_,_> ref'。 – kvb 2014-11-24 21:33:54
我確實考慮過使用.net集合,但決定不採用這種方式,部分是出於架構原因(我有很多表需要保持同步,所以我不想公開Add方法),但也是因爲它感覺就像一個警察 - 我剛剛開始F#,並且我試圖以「正確」的方式來做事,而不是僅僅爲了C#而努力。我從指導中注意到,應該使用對象來表示大事物和功能。不知道我的問題是什麼,但我認爲我表達的意識缺乏明智的判斷:-)。 – 2014-11-25 09:26:18