Tupel
Ein Tupel ist eine Gruppierung von unbenannten, aber geordneten Werten, möglicherweise mit unterschiedlichen Typen. Tupel können Verweistypen oder Strukturen sein.
Syntax
(element, ... , element)
struct(element, ... ,element )
Bemerkungen
Jedes Element in der vorherigen Syntax kann ein beliebiger gültiger F#-Ausdruck sein.
Beispiele
Beispiele für Tupel sind Paare, Triples usw. mit demselben oder einem unterschiedlichen Typ. Beispiele werden im folgenden Code veranschaulicht.
(1, 2)
// Triple of strings.
("one", "two", "three")
// Tuple of generic types.
(a, b)
// Tuple that has mixed types.
("one", 1, 2.0)
// Tuple of integer expressions.
(a + 1, b + 1)
// Struct Tuple of floats
struct (1.025f, 1.5f)
Abrufen einzelner Werte
Sie können Musterabgleich verwenden, um auf Namen für Tupelelemente zuzugreifen und diese zuzuweisen, wie im folgenden Code gezeigt.
let print tuple1 =
match tuple1 with
| (a, b) -> printfn "Pair %A %A" a b
Sie können ein Tupel auch über einen Musterabgleich außerhalb eines match
-Ausdrucks über eine let
-Bindung dekonstruieren:
let (a, b) = (1, 2)
// Or as a struct
let struct (c, d) = struct (1, 2)
Oder Sie können einen Musterabgleich für Tupel als Eingaben für Funktionen vornehmen:
let getDistance ((x1,y1): float*float) ((x2,y2): float*float) =
// Note the ability to work on individual elements
(x1*x2 - y1*y2)
|> abs
|> sqrt
Wenn Sie nur ein Element des Tupels benötigen, kann das Platzhalterzeichen (der Unterstrich) verwendet werden, um zu vermeiden, dass ein neuer Name für einen Wert erstellt wird, den Sie nicht benötigen.
let (a, _) = (1, 2)
Das Kopieren von Elementen aus einem Verweistupel in ein Strukturtupel ist ebenfalls einfach:
// Create a reference tuple
let (a, b) = (1, 2)
// Construct a struct tuple from it
let struct (c, d) = struct (a, b)
Die Funktionen fst
und snd
(nur Verweistupel) geben jeweils das erste bzw. das zweite Element eines Tupels zurück.
let c = fst (1, 2)
let d = snd (1, 2)
Es gibt keine integrierte Funktion, die das dritte Element eines Triples zurückgibt, aber Sie können sie problemlos wie folgt schreiben.
let third (_, _, c) = c
Im Allgemeinen ist es besser, Musterabgleich zu verwenden, um auf einzelne Tupelelemente zuzugreifen.
Verwenden von Tupeln
Tupel bieten eine bequeme Möglichkeit, mehrere Werte aus einer Funktion zurückzugeben, wie im folgenden Beispiel gezeigt. In diesem Beispiel wird eine ganzzahlige Division durchgeführt und das gerundete Ergebnis des Vorgangs als erster Member eines Tupelpaars und der Rest als zweiter Member des Paars zurückgegeben.
let divRem a b =
let x = a / b
let y = a % b
(x, y)
Tupel können auch als Funktionsargumente verwendet werden, wenn Sie implizites Currying von Funktionsargumenten vermeiden möchten, das von der üblichen Funktionssyntax impliziert wird.
let sumNoCurry (a, b) = a + b
Mit der üblichen Syntax zum Definieren der Funktion let sum a b = a + b
können Sie eine Funktion definieren, die die teilweise Anwendung des ersten Arguments der Funktion darstellt, wie im folgenden Code gezeigt.
let sum a b = a + b
let addTen = sum 10
let result = addTen 95
// Result is 105.
Die Verwendung eines Tupels als Parameter deaktiviert Currying. Weitere Informationen zu Currying finden Sie im Abschnitt „Teilweise Anwendung von Argumenten“ unter Funktionen.
Namen von Tupeltypen
Wenn Sie den Namen eines Typs ausschreiben, der ein Tupel ist, verwenden Sie das *
-Symbol, um Elemente zu trennen. Für ein Tupel, das aus einem int
-, einem float
- und einem string
-Wert besteht, z. B. (10, 10.0, "ten")
, wird der Typ wie folgt geschrieben.
int * float * string
Beachten Sie, dass äußere Klammern beim Erstellen eines Typalias für einen Strukturtupeltyp obligatorisch sind.
type TupleAlias = string * float
type StructTupleAlias = (struct (string * float))
Interoperation mit C#-Tupeln
Tupel in C# sind Strukturen und entsprechen Strukturtupeln in F#. Wenn Sie mit C# zusammenarbeiten müssen, müssen Sie Strukturtupel verwenden.
Dies geht ganz einfach. Stellen Sie sich beispielsweise vor, Sie müssen ein Tupel an eine C#-Klasse übergeben und dann das Ergebnis nutzen, das ebenfalls ein Tupel ist:
namespace CSharpTupleInterop
{
public static class Example
{
public static (int, int) AddOneToXAndY((int x, int y) a) =>
(a.x + 1, a.y + 1);
}
}
In Ihrem F#-Code können Sie dann ein Strukturtupel als Parameter übergeben und das Ergebnis als Strukturtupel nutzen.
open TupleInterop
let struct (newX, newY) = Example.AddOneToXAndY(struct (1, 2))
// newX is now 2, and newY is now 3
Konvertieren zwischen Referenztupeln und Strukturtupeln
Weil Verweistupel und Strukturtupel eine völlig andere zugrunde liegende Darstellung aufweisen, sind sie nicht implizit konvertierbar. Das heißt, Code wie der folgende wird nicht kompiliert:
// Will not compile!
let (a, b) = struct (1, 2)
// Will not compile!
let struct (c, d) = (1, 2)
// Won't compile!
let f(t: struct(int*int)): int*int = t
Sie müssen Musterabgleich für ein Tupel verwenden und das andere Tupel aus seinen Bestandteilen konstruieren. Beispiel:
// Pattern match on the result.
let (a, b) = (1, 2)
// Construct a new tuple from the parts you pattern matched on.
let struct (c, d) = struct (a, b)
Kompilierte Form von Referenztupeln
In diesem Abschnitt wird die Form von Tupeln beschrieben, wenn sie kompiliert werden. Sie müssen die hier aufgeführten Informationen nur lesen, wenn .NET Framework 3.5 oder früher als Ziel verwendet wird.
Tupel werden in Objekte mit einem von mehreren generischen Typen kompiliert, die alle den Namen System.Tuple
tragen. Sie werden je nach Arität oder der Anzahl von Typparametern überladen. Tupeltypen werden in dieser Form angezeigt, wenn Sie sie aus einer anderen Sprache anzeigen (z. B. C# oder Visual Basic) oder wenn Sie ein Tool verwenden, das keine F#-Konstrukte kennt. Die Tuple
-Typen wurden in .NET Framework 4 eingeführt. Wenn Sie eine frühere Version von .NET Framework als Ziel verwenden, nutzt der Compiler Versionen von System.Tuple
aus Version 2.0 der F#-Kernbibliothek. Die Typen in dieser Bibliothek werden nur für Anwendungen verwendet, die die Versionen 2.0, 3.0 und 3.5 von .NET Framework als Ziel verwenden. Typweiterleitung wird verwendet, um Binärkompatibilität zwischen .NET Framework 2.0- und .NET Framework 4-F#-Komponenten sicherzustellen.
Kompilierte Form von Strukturtupeln
Strukturtupel (z. B. struct (x, y)
) unterscheiden sich grundlegend von Verweistupeln. Sie werden in den ValueTuple-Typ kompiliert, nach Arität oder der Anzahl der Typparameter überladen. Sie entsprechen C#-Tupeln und Visual Basic-Tupeln und arbeiten bidirektional miteinander.