Struktury
Struktura je kompaktní typ objektu, který může být efektivnější než třída pro typy, které mají malé množství dat a jednoduché chování.
Syntaxe
[ 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
Poznámky
Struktury jsou typy hodnot, což znamená, že jsou uloženy přímo v zásobníku nebo, pokud se používají jako pole nebo maticové prvky, vložené do nadřazeného typu. Na rozdíl od tříd a záznamů mají struktury sémantiku pass-by-value. To znamená, že jsou užitečné hlavně pro malé agregace dat, ke kterým se přistupuje a kopíruje často.
V předchozí syntaxi jsou zobrazeny dvě formy. První není jednoduchá syntaxe, ale je však často používána, protože při použití struct
a end
klíčových slov můžete vynechat StructAttribute
atribut, který se zobrazí ve druhém formuláři. Můžete se zkrátit StructAttribute
na jen Struct
.
Typ-definition-elements-and-members v předchozí syntaxi představuje deklarace a definice členů. Struktury mohou mít konstruktory a proměnlivá a neměnná pole a mohou deklarovat členy a implementace rozhraní. Další informace najdete v tématu Členové.
Struktury se nemohou účastnit dědičnosti, nemohou obsahovat let
ani do
vazby a nemohou rekurzivně obsahovat pole vlastního typu (i když mohou obsahovat odkazové buňky, které odkazují na vlastní typ).
Vzhledem k tomu, že struktury neumožňují let
vazby, je nutné deklarovat pole ve strukturách pomocí klíčového val
slova. Klíčové val
slovo definuje pole a jeho typ, ale neumožňuje inicializaci. val
Místo toho se deklarace inicializují na nulu nebo null. Z tohoto důvodu vyžadují struktury, které mají implicitní konstruktor (tj. parametry, které jsou uvedeny bezprostředně za názvem struktury v deklaraci) vyžadují, aby val
deklarace byly anotovány atributem DefaultValue
. Struktury, které mají definovaný konstruktor, stále podporují inicializaci nula. Atribut je proto deklarace, DefaultValue
že taková nulová hodnota je pro pole platná. Implicitní konstruktory pro struktury neprovádějí žádné akce, protože let
u do
typu nejsou povoleny vazby, ale hodnoty parametrů implicitního konstruktoru jsou k dispozici jako soukromá pole.
Explicitní konstruktory můžou zahrnovat inicializaci hodnot polí. Pokud máte strukturu, která má explicitní konstruktor, stále podporuje nulovou inicializaci; však nepoužívejte DefaultValue
atribut u val
deklarací, protože je v konfliktu s explicitním konstruktorem. Další informace o deklaracích naleznete v val
tématu Explicitní pole: Klíčové val
slovo.
Atributy a modifikátory přístupnosti jsou povoleny u struktur a řídí se stejnými pravidly jako u jiných typů. Další informace naleznete v tématu Atributy a řízení přístupu.
Následující příklady kódu ilustrují definice struktury.
// 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 – struktury
Můžete definovat vlastní struktury, které můžou dodržovat byref
sémantiku -like: další informace najdete v tématu Byrefs . To se provádí pomocí atributu 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
neznamená Struct
. Oba musí být přítomné na typu.
Struktura "byref
-like" v jazyce F# je typ hodnoty vázané na zásobník. Na spravované haldě se nikdy nepřiděluje. Struktura byref
podobná je užitečná pro programování s vysokým výkonem, protože se vynucuje se sadou silných kontrol o životnosti a nezachytávání. Pravidla jsou:
- Mohou být použity jako parametry funkce, parametry metody, místní proměnné, metoda vrací.
- Nemohou být statické nebo instance členy třídy nebo normální struktury.
- Nelze je zachytit žádným konstruktorem uzavření (
async
metodami nebo výrazy lambda). - Nelze je použít jako obecný parametr.
I když tato pravidla velmi silně omezují využití, dělají to tak, aby splňovaly příslib vysokovýkonného výpočetního prostředí bezpečným způsobem.
ReadOnly – struktury
Strukturám poznámek IsReadOnlyAttribute můžete přiřadit atribut. Příklad:
[<IsReadOnly; Struct>]
type S(count1: int, count2: int) =
member x.Count1 = count1
member x.Count2 = count2
IsReadOnly
neznamená Struct
. Pokud chcete IsReadOnly
mít strukturu, musíte přidat obojí.
Použití tohoto atributu generuje metadata, která F# a C# znají, aby s ním zacházeli jako inref<'T>
s jazykem F# a in ref
v uvedeném pořadí.
Definování proměnlivé hodnoty uvnitř struktury jen pro čtení způsobí chybu.
Záznamy struktury a diskriminované sjednocení
Záznamy a diskriminované sjednocení můžete znázorňovat jako struktury s atributem [<Struct>]
. Další informace najdete v jednotlivých článcích.