Verstehen von byref, ref und &
-
14-11-2019 - |
Frage
Nun, ich habe verstanden, dass F # Referenzen verwalten kann (eine Art C ++ - ähnliche Referenzen).Dies ermöglicht die Möglichkeit, den Wert von Parametern zu ändern, die in Funktionen übergeben werden, und ermöglicht es dem Programmierer auch, mehr als einen einzelnen Wert zurückzugeben.Aber hier ist, was ich wissen muss:
Ref Stichwort:Schlusselwort
ref
wird verwendet, um aus einem Wert einen Verweis auf diesen Wert des abgeleiteten Typs zu erstellen.Solet myref = ref 10
Dies bedeutet, dass F # ein Objekt vom Typ erstellt
Ref<int>
dort (im veränderlichen Feld) meineint 10
.Okay.Also gehe ich davon aus, dass
ref
wird verwendet, um Instanzen des zu erstellenRef<'a>
Art.Ist es richtig?Zugriffswert:Um auf einen in Referenz gespeicherten Wert zuzugreifen, kann ich Folgendes tun:
let myref = ref 10 let myval = myref.Value let myval2 = !myref
Während die
:=
der Operator lässt mich den Wert einfach so bearbeiten:let myref = ref 10 myref.Value <- 30 myref := 40
So
!
(Knall) dereferenziert meine Referenz.Und:=
bearbeiten Sie es.Ich nehme an, das ist auch richtig.Betreiber:Was macht dieser Operator?Soll es auf einen Referenztyp angewendet werden?Nein, ich denke, es muss auf einen veränderlichen Wert angewendet werden und das gibt was zurück?Die Referenz?Die Adresse?Bei Verwendung von interaktiven:
let mutable mutvar = 10;; &a;;
Die letzte Zeile gibt einen Fehler aus, so dass ich nicht verstehe, was die
&
betreiber ist für.Nachname:Was ist mit
byref
?Das ist mir sehr wichtig, aber mir ist klar, dass ich es nicht verstehe.Ich verstehe, dass es in der Funktion bezüglich der Parameterübergabe verwendet wird.Man verwendet byref, wenn er möchte, dass der übergebene Wert bearbeitet werden kann (dies widerspricht ein wenig der Philosophie der funktionalen Sprachen, aber f # ist etwas mehr als das).Betrachten Sie Folgendes:let myfunc (x: int byref) = x <- x + 10
Das ist seltsam.Ich weiß das, wenn Sie eine Referenz haben
let myref = ref 10
und dann tun Sie dies, um den Wert zu bearbeiten:myref <- 10
es entsteht ein Fehler, weil es so sein sollte:myref := 10
.Die Tatsache, dass ich in dieser Funktion bearbeiten kannx
mit dem<-
operator bedeutet, dassx
ist keine Referenz, oder?Wenn ich das annehme
x
ist keine Referenz, dann gehe ich auch davon aus, dass in Funktionen bei der Verwendungbyref
auf einen Parameter kann auf diesen Parameter die veränderliche Syntax angewendet werden.Es ist also nur eine Frage der Syntax, wenn ich davon ausgehe, dass es mir gut geht und tatsächlich alles funktioniert (keine Compilerfehler).Was ist jedochx
?Funktionen aufrufen:Wie kann ich eine Funktion verwenden, die byref-Parameter verwendet?
Der
&
der Betreiber ist involviert, aber könnten Sie das bitte besser erklären?In diesem Artikel: MSDN-Parameter und -Argumente das folgende Beispiel wird bereitgestellt: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
Lösung
Ref Stichwort Ja, wenn du schreibst let a = ref 10
du schreibst im Wesentlichen let a = new Ref<int>(10)
wo die Ref<T>
typ hat ein veränderliches Feld Value
.
Zugriffswert Der :=
und !
operatoren sind nur Abkürzungen zum Schreiben:
a.Value <- 10 // same as writing: a := 10
a.Value // same as writing: !a
Nachname ist ein spezieller Typ, der (vernünftigerweise) nur in Methodenparametern verwendet werden kann.Dies bedeutet, dass das Argument im Wesentlichen ein Zeiger auf einen Speicherort sein sollte (auf Heap oder Stack zugewiesen).Es entspricht out
und ref
Modifikatoren in C #.Beachten Sie, dass Sie keine lokalen Variablen dieses Typs erstellen können.
Betreiber ist eine Möglichkeit, einen Wert (einen Zeiger) zu erstellen, der als Argument an eine Funktion / Methode übergeben werden kann, die a erwartet byref
Art.
Funktionen aufrufen das Beispiel mit byref
funktioniert, weil Sie der Methode einen Verweis auf eine lokale veränderbare Variable übergeben.Über die Referenz kann die Methode den in dieser Variablen gespeicherten Wert ändern.
Folgendes funktioniert nicht:
let a = 10 // Note: You don't even need 'mutable' here
bar.Increment(ref a)
Der Grund dafür ist, dass Sie eine neue Instanz von erstellen Ref<int>
und Sie kopieren den Wert von a
in diese Instanz.Der Increment
methode ändert dann den auf dem Heap gespeicherten Wert in der Instanz von Ref<int>
, aber Sie haben keinen Verweis mehr auf dieses Objekt.
let a = ref 10
bar.Increment(a)
Das funktioniert, weil a
ist ein Wert vom Typ Ref<int>
und Sie übergeben einen Zeiger auf die Heap-zugewiesene Instanz an Increment
und dann holen Sie sich den Wert aus der Heap-zugewiesenen Referenzzelle mit !a
.
(Sie können Werte verwenden, die mit erstellt wurden ref
als Argumente für byref
weil der Compiler diesen Fall speziell behandelt - er nimmt automatisch Bezug auf die Value
feld, weil dies ein nützliches Szenario ist...).