Ссылочные ячейки

Ссылочные ячейки — это места хранения, которые позволяют создавать изменяемые значения с семантикой ссылок.

Синтаксис

ref expression

Remarks

Для создания новой ссылочной ячейки, инкапсулирующей значение, перед значением ставится оператор ref. Базовое значение затем можно изменить, так как оно является изменяемым.

Ссылочная ячейка содержит фактическое значение; это не просто адрес. При создании ссылочной ячейки с помощью оператора ref создается копия базового значения в качестве инкапсулированного изменяемого значения.

Разыменовать ссылочную ячейку можно с помощью оператора ! (восклицательного знака).

Следующий пример кода иллюстрирует объявление и использование ссылочных ячеек.

// Declare a reference.
let refVar = ref 6

// Change the value referred to by the reference.
refVar := 50

// Dereference by using the ! operator.
printfn "%d" !refVar

Результат выглядит так: 50.

Ссылочные ячейки являются экземплярами универсального типа записей Ref, который объявляется следующим образом.

type Ref<'a> =
{ mutable contents: 'a }

Тип 'a ref является синонимом Ref<'a>. В интегрированной среде разработки в компиляторе и в IntelliSense отображается первое обозначение данного типа, однако базовым определением является второе.

Оператор ref создает новую ссылочную ячейку. Следующий код представляет собой объявление оператора ref.

let ref x = { contents = x }

В следующей таблице перечислены возможности, доступные для ссылочной ячейки.

Оператор, член или поле Описание Тип Определение
! (оператор разыменования) Возвращает базовое значение. 'a ref -> 'a let (!) r = r.contents
:= (оператор присваивания) Изменяет базовое значение. 'a ref -> 'a -> unit let (:=) r x = r.contents <- x
ref (оператор) Инкапсулирует значение в новую ссылочную ячейку. 'a -> 'a ref let ref x = { contents = x }
Value (свойство) Получает или задает базовое значение. unit -> 'a member x.Value = x.contents
contents (поле записи) Получает или задает базовое значение. 'a let ref x = { contents = x }

Существует несколько способов доступа к базовому значению. Значение, возвращаемое оператором разыменования (!), не является присваиваемым значением. Следовательно, при изменении базового значения нужно вместо этого оператора использовать оператор присваивания (:=).

И свойство Value, и поле contents являются присваиваемыми значениями. Следовательно, их можно использовать для доступа к базовому значению или его изменения, как показано в следующем коде.

let xRef : int ref = ref 10

printfn "%d" (xRef.Value)
printfn "%d" (xRef.contents)

xRef.Value <- 11
printfn "%d" (xRef.Value)
xRef.contents <- 12
printfn "%d" (xRef.contents)

Выходные данные выглядят следующим образом.

10
10
11
12

Поле contents предусмотрено для совместимости с другими версиями языка ML, и его наличие приводит к выводу предупреждения в процессе компиляции. Для отключения этого предупреждения используется параметр компилятора --mlcompatibility. Дополнительные сведения см. в разделе параметры компилятора.

Программистам на c# следует помнить, что ref в c# это не то же самое, что и ref в F #. Эквивалентными конструкциями в F # являются ByRef, которые отличаются концепцией ссылочных ячеек.

Значения, помеченные как, mutable могут быть автоматически повышены до, 'a ref Если захватывается замыканием; см. значения.

См. также