.net f# reference parameter-passing byref

.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:

  1. 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 que

    let myref = ref 10

    Esto significa que F # creará un objeto de tipo Ref<int> poniendo allí (en el campo mutable) my int 10 .

    DE ACUERDO. Así que supongo que ref se usa para crear instancias del tipo Ref<''a> . ¿Es correcto?

  2. 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.

  3. 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 & .

  4. 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 editar x usando el operador <- significa que x no es una referencia, ¿verdad?

    Si supongo que x no es una referencia, también supongo que, en las funciones, cuando se usa byref 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é es x ?

  5. 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