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 .