Domanda

Bene, ho capito che F# è in grado di gestire i riferimenti (una sorta di C++ come riferimenti).Questo consente la possibilità di cambiare il valore dei parametri passati in funzioni e, inoltre, consente al programmatore di restituire più di un valore singolo.Tuttavia, ecco che cosa ho bisogno di sapere:

  1. Parola chiave Ref:La parola chiave ref viene utilizzato per creare, da un valore, un riferimento a tale valore di tipo derivato.Così

    let myref = ref 10
    

    Questo significa che F# crea un oggetto di tipo Ref<int> mettere in una mutevole campo) il mio int 10.

    OK.Quindi suppongo che ref viene utilizzato per creare istanze di Ref<'a> tipo.È corretto?

  2. Valore di accesso:Per accedere a un valore memorizzato in riferimento posso fare questo:

    let myref = ref 10
    let myval = myref.Value
    let myval2 = !myref
    

    Mentre il := operatore solo mi permette di modificare il valore come questo:

    let myref = ref 10
    myref.Value <- 30
    myref := 40
    

    Così ! (Bang) risolve il mio punto di riferimento.E := la modifica.Suppongo che questo sia corretta.

  3. L'operatore&:Che cosa significa questo operatore che fare?È per essere applicato a un tipo di riferimento?No, credo che deve essere applicata ad una mutevole valore e restituisce cosa?Il riferimento?L'indirizzo?Se si utilizza interattiva:

    let mutable mutvar = 10;;
    &a;;
    

    L'ultima riga genera un errore così non capisco che cosa l' & operatore per.

  4. ByRef:Che dire byref?Questo è molto importante per me, ma mi rendo conto di non capire.Capisco che è utilizzata in funzione per quanto riguarda il passaggio del parametro.Utilizza byref quando vuole che il valore passato può essere modificato (questo è un po 'contro i linguaggi funzionali' filosofia, ma f# è qualcosa di più).Si consideri il seguente:

    let myfunc (x: int byref) =
        x <- x + 10
    

    Questo è strano.So che se si dispone di un riferimento let myref = ref 10 e poi per modificare il valore: myref <- 10 essa si pone in un errore, in quanto dovrebbe essere come questo: myref := 10.Tuttavia, il fatto che in quella funzione che è possibile modificare x utilizzando il <- operatore significa che x non è un riferimento, giusto?

    Se si considera che x non è un riferimento, quindi presumo anche che, nelle funzioni, quando si utilizza byref su un parametro, il parametro può avere la mutevole sintassi applicata.Quindi è solo una questione di sintassi, se assumo io sono OK, e, infatti, tutto funziona (non errori del compilatore).Tuttavia, ciò che è x?

  5. Funzioni di chiamata:Come posso utilizzare una funzione utilizzando parametri byref?

    Il & l'operatore è stato coinvolto, ma potresti spiegare meglio per favore?In questo articolo: MSDN Parametri e Argomenti il seguente esempio:

    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
    
È stato utile?

Soluzione

Parola chiave Ref Sì, quando si scrive let a = ref 10 essenzialmente si scrittura let a = new Ref<int>(10) dove il Ref<T> il tipo ha una mutevole campo Value.

Valore di accesso Il := e ! gli operatori sono solo scorciatoie per la scrittura:

a.Value <- 10  // same as writing: a := 10
a.Value        // same as writing: !a

ByRef è un tipo speciale che può essere (ragionevolmente), utilizzata solo nei parametri del metodo.Significa che l'argomento deve essere essenzialmente un puntatore a qualche posizione di memoria (allocato su heap stack).Corrisponde a out e ref modificatori in C#.Si noti che non è possibile creare una variabile locale di questo tipo.

L'operatore & è un modo per creare un valore (un puntatore) che può essere passato come argomento di una funzione/metodo attesa di un byref tipo.

Funzioni di chiamata l'esempio con byref funziona perché si stanno passando il metodo di un riferimento a un locale mutevole variabile.Via di riferimento, il metodo può modificare il valore memorizzato nella variabile.

Il seguente non funziona:

let a = 10            // Note: You don't even need 'mutable' here
bar.Increment(ref a)  

Il motivo è che si sta creando una nuova istanza di Ref<int> e si copia il valore di a in questa istanza.Il Increment metodo, quindi, modifica il valore memorizzato sul heap nell'istanza di Ref<int>, ma non è un riferimento a questo oggetto più.

let a = ref 10
bar.Increment(a)  

Questo funziona, perché a è un valore di tipo Ref<int> e stai passando un puntatore all'allocazione heap istanza di Increment e quindi ottenere il valore allocazione heap di riferimento di cella utilizzando !a.

(È possibile utilizzare i valori creati utilizzando ref come argomenti per byref perché il compilatore gestisce questo caso speciale, questo verrà automaticamente di riferimento del Value campo, perché questo è uno scenario utile...).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top