Ключевое слово Ref Да, когда вы пишете let a = ref 10
, вы по существу пишете let a = new Ref<int>(10)
, где тип Ref<T>
имеет изменяемое поле Value
.
Значение доступа Операторы :=
и !
являются просто ярлыками для записи:
a.Value <- 10 // same as writing: a := 10
a.Value // same as writing: !a
ByRef - это специальный тип, который (разумно) можно использовать только в методепараметры.Это означает, что аргумент должен быть по существу указателем на некоторую область памяти (выделенную в куче или стеке).Это соответствует модификаторам out
и ref
в C #.Обратите внимание, что вы не можете создать локальную переменную этого типа.
Оператор & - это способ создания значения (указателя), которое можно передать в качестве аргумента ожидающей функции / методуbyref
тип.
Вызов функций пример с byref
работает, потому что вы передаете методу ссылку на локальную переменную.С помощью ссылки метод может изменить значение, хранящееся в этой переменной.
Следующее не работает:
let a = 10 // Note: You don't even need 'mutable' here
bar.Increment(ref a)
Причина в том, что вы создаете новый экземпляр Ref<int>
и вы копируете значение a
в этот экземпляр.Затем метод Increment
изменяет значение, хранящееся в куче в экземпляре Ref<int>
, но у вас больше нет ссылки на этот объект.
let a = ref 10
bar.Increment(a)
Это работает, потому что a
значение типа Ref<int>
и вы передаете указатель на экземпляр, выделенный в куче, в Increment
, а затем получаете значение из выделенной в куче ссылочной ячейки, используя !a
.
(вы можете использоватьзначения, созданные с использованием ref
в качестве аргументов для byref
, потому что компилятор обрабатывает этот случай специально - он автоматически примет ссылку на поле Value
, потому что это полезный сценарий ...).