Freigeben über


Strukturen

Eine Struktur ist ein kompakter Objekttyp, der für Typen, die nur eine geringe Datenmenge und ein einfaches Verhalten aufweisen, effizienter als eine Klasse sein kann.

Syntax

[ attributes ]
type [accessibility-modifier] type-name =
    struct
        type-definition-elements-and-members
    end
// or
[ attributes ]
[<StructAttribute>]
type [accessibility-modifier] type-name =
    type-definition-elements-and-members

Bemerkungen

Strukturen sind Werttypen, d. h., sie werden direkt im Stapel oder, wenn sie als Felder oder Array-Elemente verwendet werden, inline im übergeordneten Typ gespeichert. Im Gegensatz zu Klassen und Datensätzen verfügen Strukturen über eine Übergabewertsemantik. Dies bedeutet, dass sie hauptsächlich für kleine Datenaggregate sinnvoll sind, die häufig aufgerufen und kopiert werden.

In der vorherigen Syntax werden zwei Formen gezeigt. Die erste ist nicht die einfache Syntax, aber sie wird trotzdem häufig verwendet, da Sie bei Verwendung der Schlüsselwörter struct und end das StructAttribute-Attribut auslassen können, das in der zweiten Form angezeigt wird. Sie können StructAttribute zu Struct abkürzen.

Die Zeile type-definition-elements-and-members in der obigen Syntax steht für Memberdeklarationen und -definitionen. Strukturen können über Konstruktoren sowie änderbare und unveränderliche Felder verfügen, und sie können Member und Schnittstellenimplementierungen deklarieren. Weitere Informationen finden Sie unter Member.

Strukturen können nicht an der Vererbung beteiligt sein, sie können keine let- oder do-Bindungen enthalten und können nicht rekursiv Felder des eigenen Typs enthalten (obwohl sie Verweiszellen enthalten können, die auf den eigenen Typ verweisen).

Da Strukturen keine let-Bindungen zulassen, müssen Sie Felder in Strukturen mit dem val-Schlüsselwort deklarieren. Das val-Schlüsselwort definiert ein Feld und den Typ, es lässt jedoch keine Initialisierung zu. In diesem Fall werden val-Deklarationen mit 0 oder null initialisiert. Aus diesem Grund erfordern Strukturen, die über einen impliziten Konstruktor verfügen (d. h. Parameter, die direkt nach dem Strukturnamen in der Deklaration angegeben werden), dass val-Deklarationen mit dem DefaultValue-Attribut gekennzeichnet werden. Strukturen, die über einen definierten Konstruktor verfügen, unterstützen weiterhin die Initialisierung mit 0 (null). Aus diesem Grund ist das DefaultValue-Attribut eine Deklaration, dass der Wert 0 (Null) für das Feld gültig ist. Implizite Konstruktoren für Strukturen führen keine Aktionen aus, da let- und do-Bindungen für den Typ nicht zulässig sind, aber die übergebenen impliziten Konstruktorparameterwerte sind als private Felder verfügbar.

Explizite Konstruktoren können eine Initialisierung von Feldwerten beinhalten. Wenn Sie eine Struktur mit einem expliziten Konstruktor haben, unterstützt sie weiterhin die Initialisierung mit 0 (Null); Sie verwenden jedoch nicht das DefaultValue-Attribut auf den val-Deklarationen, da es mit dem expliziten Konstruktor in Konflikt steht. Weitere Informationen zu val-Deklarationen finden Sie unter Explizite Felder: Das val-Schlüsselwort.

Attribute und Zugriffsmodifizierer sind für Strukturen zulässig und folgen denselben Regeln wie jene für andere Typen. Weitere Informationen finden Sie unter Attribute und Zugriffssteuerung.

Die folgenden Codebeispiele veranschaulichen Strukturdefinitionen.

// In Point3D, three immutable values are defined.
// x, y, and z will be initialized to 0.0.
type Point3D =
    struct
        val x: float
        val y: float
        val z: float
    end

// In Point2D, two immutable values are defined.
// It also has a member which computes a distance between itself and another Point2D.
// Point2D has an explicit constructor.
// You can create zero-initialized instances of Point2D, or you can
// pass in arguments to initialize the values.
type Point2D =
    struct
        val X: float
        val Y: float
        new(x: float, y: float) = { X = x; Y = y }

        member this.GetDistanceFrom(p: Point2D) =
            let dX = (p.X - this.X) ** 2.0
            let dY = (p.Y - this.Y) ** 2.0

            dX + dY |> sqrt
    end

ByRefLike-Strukturen

Sie können eigene Strukturen definieren, die eine Semantik ähnlich byrefeinhalten können. Weitere Informationen finden Sie unter Byrefs. Verwenden Sie dazu das IsByRefLikeAttribute-Attribut:

open System
open System.Runtime.CompilerServices

[<IsByRefLike; Struct>]
type S(count1: Span<int>, count2: Span<int>) =
    member x.Count1 = count1
    member x.Count2 = count2

IsByRefLike impliziert nicht Struct. Beides muss im Typ vorhanden sein.

Eine byref-ähnliche Struktur in F# ist ein stapelgebundener Werttyp. Sie wird niemals für den verwalteten Heap zugeordnet. Eine byref-ähnliche Struktur ist bei der Hochleistungsprogrammierung hilfreich, da sie mit einer Reihe strenger Überprüfungen der Lebensdauer und der Nichterfassung erzwungen wird. Die Regeln lauten:

  • Sie können als Funktionsparameter, Methodenparameter, lokale Variablen und Methodenrückgaben verwendet werden.
  • Sie können nicht statisch oder Instanzmember einer Klasse oder normalen Struktur sein.
  • Sie können nicht von einem Abschlusskonstrukt (async-Methoden oder Lambdaausdrücke) erfasst werden.
  • Sie können nicht als generischer Parameter verwendet werden.

Diese Regeln schränken die Nutzung zwar sehr stark ein, dies geschieht jedoch, um sicheres Hochleistungscomputing zu ermöglichen.

ReadOnly-Strukturen

Sie können Strukturen mithilfe des Attributs IsReadOnlyAttribute mit Anmerkungen versehen. Zum Beispiel:

[<IsReadOnly; Struct>]
type S(count1: int, count2: int) =
    member x.Count1 = count1
    member x.Count2 = count2

IsReadOnly impliziert nicht Struct. Sie müssen beide hinzufügen, um eine IsReadOnly-Struktur zu erhalten.

Die Verwendung dieses Attributs gibt Metadaten aus, die F# und C# darüber informieren, dass es als inref<'T> bzw. in ref behandelt werden soll.

Das Definieren eines veränderbaren Werts innerhalb einer ReadOnly-Struktur erzeugt einen Fehler.

Strukturdatensätze und diskriminierte Vereinigungen

Sie können Datensätze und diskriminierte Vereinigungen als Struktur mit dem Attribut [<Struct>] darstellen. Weitere Informationen finden Sie in den einzelnen Artikeln.

Weitere Informationen