Celdas de referencia

Las celdas de referencia son ubicaciones de almacenamiento que permiten crear valores mutables con semántica de referencia.

Sintaxis

ref expression

Comentarios

Se utiliza el operador ref antes de un valor para crear una nueva celda de referencia que encapsula el valor. A continuación, se puede cambiar el valor subyacente, porque es mutable.

Una celda de referencia contiene un valor real; no una mera dirección. Al crear una celda de referencia mediante el operador ref, se crea una copia del valor subyacente como valor mutable encapsulado.

Se puede desreferenciar una celda de referencia mediante el operador ! (bang).

En el ejemplo de código siguiente se muestran la declaración y el uso de celdas de referencia.

// 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

La salida es 50.

Las celdas de referencia son instancias del tipo de registro genérico Ref, que se declara como sigue.

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

El tipo 'a ref es un sinónimo de Ref<'a>. Tanto el compilador como IntelliSense en el IDE, muestran el primero para este tipo, pero la definición subyacente es el segundo.

El operador ref crea una nueva celda de referencia. El código siguiente es la declaración del operador ref.

let ref x = { contents = x }

En la tabla siguiente se muestran las características que están disponibles en la celda de referencia.

Operador, miembro o campo Descripción Tipo Definición
! (operador de desreferencia) Devuelve el valor subyacente. 'a ref -> 'a let (!) r = r.contents
:= (operador de asignación) Cambia el valor subyacente. 'a ref -> 'a -> unit let (:=) r x = r.contents <- x
ref (operador) Encapsula un valor en una nueva celda de referencia. 'a -> 'a ref let ref x = { contents = x }
Value (propiedad) Obtiene o establece el valor subyacente. unit -> 'a member x.Value = x.contents
contents (campo de registro) Obtiene o establece el valor subyacente. 'a let ref x = { contents = x }

Hay varias maneras de tener acceso al valor subyacente. El valor devuelto por el operador de desreferencia (!) no es un valor asignable. Por consiguiente, si se va a modificar el valor subyacente, se debe utilizar el operador de asignación (:=) en su lugar.

Tanto la propiedad Value como el campo contents son valores asignables. Así pues, se pueden utilizar para obtener acceso al valor subyacente o cambiarlo, como se muestra en el código siguiente.

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)

La salida es la siguiente.

10
10
11
12

El campo contents se proporciona por motivos de compatibilidad con otras versiones de ML y generará una advertencia durante la compilación. Para deshabilitar la advertencia, utilice la opción --mlcompatibility del compilador. Para obtener más información, vea Opciones del compilador.

Los programadores de C# deben saber ref que en C# no es lo mismo que ref en F#. Las construcciones equivalentes de F# son byrefs, que son un concepto diferente de las celdas de referencia.

Los valores mutable marcados como se pueden promover automáticamente 'a ref a si se capturan mediante un cierre;vea Valores .

Vea también