Freigeben über


Strukturen

Eine Struktur ist ein kompakter Objekttyp, der effizienter sein kann als eine Klasse für Typen mit einer kleinen Menge an Daten und einfachem Verhalten.

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, was bedeutet, dass sie direkt im Stapel gespeichert werden oder, wenn sie als Felder oder Arrayelemente verwendet werden, inline im übergeordneten Typ. Im Gegensatz zu Klassen und Datensätzen weisen Strukturen pass-by-Value-Semantik auf. Dies bedeutet, dass sie in erster Linie für kleine Datenaggregate nützlich sind, auf die häufig zugegriffen und kopiert wird.

In der vorherigen Syntax werden zwei Formulare angezeigt. Die erste ist nicht die einfache Syntax, aber es wird trotzdem häufig verwendet, da Sie, wenn Sie die struct Schlüsselwörter end verwenden, das StructAttribute Attribut weglassen können, das in der zweiten Form angezeigt wird. Sie können einfach StructabkürzenStructAttribute.

Die Type-definition-elements-and-members in the previous syntax represents member declarations and definitions. Strukturen können Konstruktoren und veränderliche und unveränderliche Felder aufweisen, und sie können Member und Schnittstellenimplementierungen deklarieren. Weitere Informationen finden Sie unter "Member".

Strukturen können nicht an der Vererbung teilnehmen, dürfen keine Bindungen enthalten letdo und können felder ihres eigenen Typs nicht rekursiv enthalten (obwohl sie Referenzzellen enthalten können, die auf ihren eigenen Typ verweisen).

Da Strukturen keine Bindungen zulassen let , müssen Sie Felder in Strukturen mithilfe des val Schlüsselworts deklarieren. Das val Schlüsselwort definiert ein Feld und seinen Typ, lässt die Initialisierung jedoch nicht zu. val Stattdessen werden Deklarationen auf Null oder Null initialisiert. Aus diesem Grund erfordern Strukturen, die über einen impliziten Konstruktor verfügen (d. h. Parameter, die unmittelbar nach dem Strukturnamen in der Deklaration angegeben werden), dass val Deklarationen mit dem DefaultValue Attribut kommentiert werden. Strukturen, die einen definierten Konstruktor haben, unterstützen weiterhin die Nullinitialisierung. Daher ist das DefaultValue Attribut eine Deklaration, dass ein solcher Nullwert für das Feld gültig ist. Implizite Konstruktoren für Strukturen führen keine Aktionen aus, da letdo Bindungen für den Typ nicht zulässig sind, aber die übergebenen impliziten Konstruktorparameterwerte sind als private Felder verfügbar.

Explizite Konstruktoren können die Initialisierung von Feldwerten umfassen. Wenn Sie über eine Struktur mit einem expliziten Konstruktor verfügen, unterstützt sie weiterhin die Nullinitialisierung. Sie verwenden das DefaultValue Attribut jedoch nicht für die val Deklarationen, da es mit dem expliziten Konstruktor in Konflikt kommt. Weitere Informationen zu val Deklarationen finden Sie unter Explicit Fields: The val Keyword.

Attribute und Barrierefreiheitsmodifizierer sind für Strukturen zulässig und folgen den gleichen Regeln wie 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 sich an -ähnliche Semantik halten byrefkönnen: Weitere Informationen finden Sie unter Byrefs . Dies geschieht mit dem attribut IsByRefLikeAttribute:

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, Methodenrückkehrer verwendet werden.
  • Sie können weder statische noch Instanzmitglieder einer Klasse oder einer 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.

Obwohl diese Regeln die Nutzung sehr stark einschränken, tun sie dies, um das Versprechen von Hochleistungscomputing auf sichere Weise zu erfüllen.

ReadOnly-Struktur

Sie können mit dem IsReadOnlyAttribute Attribut Anmerkungen erstellen. 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 über eine IsReadOnly Struktur zu verfügen.

Die Verwendung dieses Attributs gibt Metadaten zurück, die F# und C# wissen lassen, dass sie als inref<'T> bzw in ref. behandelt werden.

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 [<Struct>] Attribut darstellen. Weitere Informationen finden Sie in den einzelnen Artikeln.

Siehe auch