.net - Comprender byref, ref y &
f# reference (1)
Palabra clave de Ref. Sí, cuando escribe let a = ref 10
esencialmente escribe let a = new Ref<int>(10)
donde el tipo Ref<T>
tiene un campo mutable Value
.
Valor de acceso The :=
and !
los operadores son solo atajos para escribir:
a.Value <- 10 // same as writing: a := 10
a.Value // same as writing: !a
ByRef es un tipo especial que puede usarse (razonablemente) solo en parámetros de método. Significa que el argumento debería ser esencialmente un puntero a alguna ubicación de memoria (asignada en montón o pila). Corresponde a out
modificadores out
y ref
en C #. Tenga en cuenta que no puede crear una variable local de este tipo.
El operador & es una forma de crear un valor (un puntero) que se puede pasar como argumento a una función / método que espera un tipo byref
.
Llamar a las funciones del ejemplo con byref
funciona porque está pasando al método una referencia a una variable mutable local. A través de la referencia, el método puede cambiar el valor almacenado en esa variable.
Lo siguiente no funciona:
let a = 10 // Note: You don''t even need ''mutable'' here
bar.Increment(ref a)
La razón es que está creando una nueva instancia de Ref<int>
y está copiando el valor de a
en esta instancia. El método Increment
luego modifica el valor almacenado en heap en la instancia de Ref<int>
, pero ya no tiene una referencia a este objeto.
let a = ref 10
bar.Increment(a)
Esto funciona, porque a
es un valor de tipo Ref<int>
y está pasando un puntero a la instancia asignada al montón para Increment
y luego obtiene el valor de la celda de referencia asignada al montón utilizando !a
(Puede usar valores creados usando ref
como argumentos para byref
porque el compilador maneja este caso especialmente; tomará automáticamente la referencia del campo Value
porque es un escenario útil ...).
Bueno, llegué a entender que F # es capaz de administrar referencias (algún tipo de C ++ como referencias). Esto permite las posibilidades de cambiar el valor de los parámetros pasados en funciones y también permite que el programador devuelva más de un valor individual. Sin embargo, esto es lo que necesito saber:
Palabra clave de referencia: la palabra clave
ref
se usa para crear, a partir de un valor, una referencia a ese valor del tipo inferido. Asi quelet myref = ref 10
Esto significa que F # creará un objeto de tipo
Ref<int>
poniendo allí (en el campo mutable) myint 10
.DE ACUERDO. Así que supongo que
ref
se usa para crear instancias del tipoRef<''a>
. ¿Es correcto?Valor de acceso: para acceder a un valor almacenado en la referencia, puedo hacer esto:
let myref = ref 10 let myval = myref.Value let myval2 = !myref
Mientras que el operador
:=
me permite editar el valor de esta manera:let myref = ref 10 myref.Value <- 30 myref := 40
Entonces
!
(Bang) desreferencia mi referencia. Y:=
editarlo. Supongo que esto también es correcto.El operador &: ¿Qué hace este operador? ¿Se aplicará a un tipo de referencia? No, supongo que debe aplicarse a un valor mutable y esto devuelve qué? ¿La referencia? ¿La dirección? Si usa interactiva:
let mutable mutvar = 10;; &a;;
La última línea arroja un error, así que no entiendo para qué sirve el operador
&
.ByRef: ¿Qué hay de
byref
? Eso es muy importante para mí, pero me doy cuenta de que no lo entiendo. Entiendo que se usa en función del paso de parámetros. Uno usa byref cuando quiere que el valor pasado pueda ser editado (esto es un poco contrario a la filosofía de los lenguajes funcionales, pero f # es algo más que eso). Considera lo siguiente:let myfunc (x: int byref) = x <- x + 10
Esto es extraño. Sé que si tiene una referencia,
let myref = ref 10
y luego haga esto para editar el valor:myref <- 10
se produce un error porque debería ser así:myref := 10
. Sin embargo, el hecho de que en esa función pueda editarx
usando el operador<-
significa quex
no es una referencia, ¿verdad?Si supongo que
x
no es una referencia, también supongo que, en las funciones, cuando se usabyref
en un parámetro, ese parámetro puede tener aplicada la sintaxis mutable. Entonces es solo una cuestión de sintaxis, si asumo que estoy bien, y, de hecho, todo funciona (no hay errores de compilación). Sin embargo, ¿qué esx
?Funciones de llamada: ¿Cómo puedo usar una función que utiliza parámetros byref?
El operador
&
está involucrado, pero ¿podría explicar esto mejor por favor? En este artículo: Parámetros y argumentos de MSDN, se proporciona el siguiente ejemplo:type Incrementor(z) = member this.Increment(i : int byref) = i <- i + z let incrementor = new Incrementor(1) let mutable x = 10 // A: Not recommended: Does not actually increment the variable. (Me: why?) incrementor.Increment(ref x) // Prints 10. printfn "%d" x let mutable y = 10 incrementor.Increment(&y) (* Me: & what does it return? *) // Prints 11. printfn "%d" y let refInt = ref 10 incrementor.Increment(refInt) (* Why does it not work in A, but here it does? *) // Prints 11. printfn "%d" !refInt