In diesem Beitrag werden wir uns Bindungen in F # ansehen, insbesondere Let / Use / Do. Jetzt fragen Sie sich vielleicht, was Bindungen sind, und da wir sie noch nicht untersucht haben, ist es jetzt an der Zeit, darüber zu sprechen.
Einfach ausgedrückt, eine Bindung verknüpft einen Bezeichner mit einem Wert oder einer Funktion.
Lass
Mit dem Schlüsselwort let verknüpfen Sie einen Namen mit einem Wert oder einer Funktion. Tatsächlich gibt es eine subtil andere Verwendung von Let, bei der eine auf der obersten Ebene des Moduls deklariert wird und die andere, bei der wir einen lokalen Kontext definieren. Hier ist ein Beispiel für beide:
module DemoModule = let someFunction = let a = 1 let b = 2 a * b
Wir könnten mit einem vollständig qualifizierten Namen wie DemoModule.someFunction auf someFunction zugreifen, aber verschachtelte Let (a, b) -Bindungen sind nur für Let der obersten Ebene verfügbar. Normalerweise sehen Sie mehr Fälle, wenn wir die Let-Bindung verwenden, um einige Werte des internen Moduls zu deklarieren. Konzentrieren wir uns also darauf (obwohl es wichtig ist zu wissen, dass Sie Let auf Modulebene verwenden können).
Schauen wir uns also noch ein paar Beispiele an.
let aString ="this is a string" let aInt = 12 let aDecimal = 12.444 let aPiFunction () = Math.PI let aSquareRootFunction (x) = Math.Sqrt(x) let aFullyTypedSquareRootFunction (x :float) = Math.Sqrt(x) let a,b = "a","tuple"
Sie können sehen, dass wir die Let-Bindung verwenden können, um an mehrere Werte zu binden, die von verschiedenen Typen sein können, wie z.
- Ganze Zahl
- Dezimal
- Funktion ohne Eingabeparameter
- Funktion mit Eingabeparametern (wobei das logische Inferenzsystem vom Typ F # den Typ korrekt auswählt)
- Eine Funktion mit vollständig definierten Parametertypen
- Tupel (in diesem Fall String * String Tupel)
An anderer Stelle können Sie die Let-Bindung in der Klasse sehen, aber wir werden dies im nächsten Artikel in dieser Reihe genauer diskutieren.
Sie können mehr über Let Binding auf MSDN lesen.Verwenden Sie
Die Use-Bindung ist der Let-Bindung sehr ähnlich, da sie den Wert an das Ergebnis des Ausdrucks bindet. Der Hauptunterschied besteht darin, dass die Use-Bindung für die Verwendung mit IDisposable-Typen ausgelegt ist und einen Wert automatisch löscht, wenn er nicht mehr im Gültigkeitsbereich liegt. Dies ist dem Schlüsselwort .NET using sehr ähnlich, obwohl ich nicht glaube, dass die F # Use-Bindung genau mit der Verwendung in .NET identisch ist, da das Schlüsselwort using in .NET tatsächlich ein Versuch / Endlich mit einem Aufruf von Dispose ( ) endlich.
Wir haben bereits im letzten Beitrag ein Beispiel für die Verwendung der Bindung zur Textformatierung gesehen, aber um uns daran zu erinnern, schauen wir uns das noch einmal an.
use sw = new StreamWriter(@"c:\temp\fprintfFile.txt") fprintf sw "This is a string line %s\r\n" "cat" fprintf sw "This is a int line %i" 10 sw.Close()
In diesem Beispiel garantiert die Use-Bindung, dass die StreamWriter-Methode nach dem Aufrufen von sw.Close () die oben gezeigte Dispose () -Methode aufruft.
Die Verwendung funktioniert nur mit IDisposables, und Sie erhalten einen Kompilierungsfehler, wenn Sie versuchen, sie mit etwas anderem zu verwenden, wie unten gezeigt:

Da die Dispose () -Methode am Ende der Use-Bindung aufgerufen wird, sollte darauf geachtet werden, den mit Let verknüpften Wert nicht zurückzugeben.
let Write = use sw = new StreamWriter(@"c:\temp\fprintfFile.txt") sw
Wenn Sie IDisposable, die Teil der Use-Bindung sind, unbedingt zurückgeben müssen, können Sie stattdessen den Rückruf verwenden. So etwas wird funktionieren, aber ich würde aufhören und mich fragen, ob Sie Ihr Design richtig entworfen haben, wenn Sie solche Dinge tun:
let Write callback = use sw = new StreamWriter(@"c:\temp\fprintfFile.txt") fprintf sw "Write is writing to the StreamWriter" callback sw sw let callback sw = fprintf sw "sw is the StreamWriter" let disp = Write callback
Tun Sie
Die do-Bindung wird verwendet, um Code auszuführen, ohne eine Funktion oder einen Wert zu definieren. Eine Bindung MUSS immer die Einheit zurückgeben (kein Wert / ungültig). In vielen Fällen können Sie die Do-Bindung weglassen, und alles funktioniert wie erwartet.
Hier sind einige Beispiele für die Verwendung von Do-Bindungen.
do printf "doing the do" //oh oh not a unit do printf "print a sum %i" 1 + 1 do 1 + 1
Wenn ich Ihnen stattdessen einen Screenshot mit dem obigen Code zeige, werden Sie feststellen, dass sich der Compiler beschwert, wenn Sie versuchen, Do mit einem Nicht-Unit-Ergebnis zu verwenden.

Sie haben zwei Möglichkeiten:
- Verwenden Sie einen Pipeline-Operator, um das Ergebnis zu ignorieren
- Let-Bindung erstellen
Ich habe unten jeweils ein Beispiel gezeigt:
let x = 1 + 1 do printf "print a sum %i" x do (1+1 |> ignore)
Lass! Verwenden Sie! Tun Sie!
Obwohl ich sie noch nicht diskutieren möchte, sehen Sie manchmal versehentlich Let! Verwenden Sie! Do!, Und wenn Sie dies tun, ist dies Teil eines sogenannten rechnerischen Ausdrucks. Sie werden dies höchstwahrscheinlich in asynchronen F # -Workflows sehen, die wir in einem der letzten Artikel behandeln werden. Wenn ich genug verstehe, kann ich sogar versuchen zu erklären, wie Sie Ihren eigenen „Computerausdruck“ erstellen können, obwohl es sich um ein eher abstraktes Konzept und ein ziemlich kompliziertes Thema handelt. Jetzt ist nicht die richtige Zeit dafür.