構造体 (F#)
構造体はコンパクトなオブジェクト型であり、データが少量で動作が簡単な型に対しては、クラスよりも効率が良い場合があります。
[ attributes ]
type [accessibility-modifier] type-name =
struct
type-definition-elements
end
// or
[ attributes ]
[<StructAttribute>]
type [accessibility-modifier] type-name =
type-definition-elements
解説
構造体は値型です。つまり、スタックに直接格納されるか、または、フィールドまたは配列要素として使用される場合は、親の型にインラインで格納されます。クラスやレコードとは異なり、構造体のセマンティクスは値渡しです。つまり、構造体は、主にアクセスやコピーの頻度が高いデータの小規模な集約に対して役立ちます。
上記の構文では、2 つの形式が示されています。最初の形式は軽量構文ではありませんが、頻繁に使用されます。これは、struct キーワードと end キーワードの使用時に、2 番目の形式に示されている StructAttribute 属性を省略できるためです。StructAttribute は Struct と省略できます。
上記の構文の type-definition-elements は、メンバーの宣言と定義を表します。構造体にはコンストラクター、変更できるフィールド、および変更できないフィールドを含めることができ、メンバーおよびインターフェイス実装を宣言できます。詳細については、「メンバー (F#)」を参照してください。
構造体は継承に関与できず、let 束縛にも do 束縛にも含めることができません。また、自身の型のフィールドを再帰的に含めることもできません (自身の型を参照する参照セルを含めることはできます)。
構造体では let 束縛を使用できないため、構造体でフィールドを宣言するには、val キーワードを使用する必要があります。val キーワードでは、フィールドとその型が定義されますが、初期化は実行できません。代わりに、val 宣言はゼロまたは null に初期化されます。このため、暗黙のコンストラクター (宣言で構造体名の直後に指定されるパラメーター) を含む構造体では、val 宣言に DefaultValue 属性が指定されている必要があります。コンストラクターが定義されている構造体でもゼロ初期化はサポートされます。したがって、DefaultValue 属性は、このようなゼロの値がフィールドで有効になる宣言です。let 束縛と do 束縛を型で使用できますが、渡される暗黙のコンストラクターのパラメーター値はプライベート フィールドとして使用できるため、構造体の暗黙のコンストラクターではアクションがまったく実行されません。
明示的なコンストラクターでは、フィールド値の初期化が実行される場合があります。明示的なコンストラクターを含む構造体がある場合も、ゼロ初期化はサポートされます。ただし、DefaultValue 属性は明示的なコンストラクターと競合するため、この属性を val 宣言で使用しないでください。val 宣言の詳細については、「明示的なフィールド: val キーワード (F#)」を参照してください。
構造体では属性およびアクセシビリティ修飾子を使用できます。その他の型の規則と同じ規則に従います。詳細については、「属性 (F#)」および「アクセス制御 (F#)」を参照してください。
構造体の定義について次のコード例で説明します。
// 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.
// 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 }
end