Я думаю, что я понимаю, что здесь происходит, но я бы очень признателен, если кто-то проливает свет на то, почему это происходит.Mutable опорные ячейки не работают со статическими элементами
В принципе (и я кодирую на лету здесь, чтобы дать простейшую возможную иллюстрацию) У меня есть класс 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")
...
Внутри S.addSymbol Я вижу новый ключ/значение, добавляемое в таблицу, но S.names не обновляется. Если, вместо этого, я называю addSymbol так:
ignore (
let tmp = S.names
s.addSymbol tmp "newName"
)
, то я могу видеть TMP обновляется с новой пары ключ/значение, но S.names еще не обновляется.
Вот что я думаю, что знаю: нет ничего плохого в рефлекторе - это исправление референта правильно как внутри, так и снаружи функции. Но, похоже, что-то странное в статическом члене - это похоже на то, что он просто не передавал мне один и тот же статический ref 'каждый раз, он копирует' a, а затем создает новый ref для этого.
Есть ли у меня это право? Если да, то почему он это делает? И что я могу сделать, чтобы заставить себя вести себя более разумно?
Заранее спасибо.
@ Vandroiy поставил диагноз вашей непосредственной проблемы, но вот еще одна мысль: если вы собираетесь мутировать коллекцию, то часто имеет смысл использовать стандартные изменчивые коллекции .NET, а не ссылку, обернутую неизменной коллекцией, которая вы обновляетесь. В вашем случае это будет означать использование 'System.Collections.Generic.Dictionary <_,_>' вместо 'Map <_,_> ref'. – kvb
Я действительно рассматривал использование коллекции .net, но решил против этого, частично по архитектурным причинам (у меня есть много таблиц, которые нужно синхронизировать, поэтому я не хотел раскрывать метод Add), но также и потому, что мне показалось, что это коп-аут - я только начинаю F #, и я пытаюсь сделать что-то «правильным», а не просто для C# -alike. Я отмечаю из руководства, что нужно использовать объекты для большого материала и функции для тонких вещей. Не знаю, в чем мой вопрос, но я думаю, что я чувствую недостаток информированного мнения :-). –