Struktur
Struktur adalah jenis objek ringkas yang bisa lebih efisien dibandingkan kelas untuk jenis yang memiliki sejumlah kecil data dan perilaku sederhana.
Sintaks
[ 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
Keterangan
Struktur adalah jenis nilai, yang berarti bahwa struktur disimpan langsung di tumpukan atau, ketika digunakan sebagai bidang atau elemen array, sejajar dalam jenis induk. Tidak seperti kelas dan rekaman, struktur memiliki semantik pass-by-value. Ini berarti bahwa data tersebut berguna terutama untuk agregat kecil data yang sering diakses dan disalin.
Dua bentuk ditampilkan dalam sintaks sebelumnya. Bentuk pertama bukan sintaks ringan, tetapi tetap sering digunakan karena, ketika menggunakan kata kunci struct
dan end
, Anda dapat menghilangkan atribut StructAttribute
yang muncul dalam bentuk kedua. Anda dapat menyingkat StructAttribute
menjadi Struct
.
Type-definition-elements-and-members dalam sintaks sebelumnya mewakili deklarasi dan definisi anggota. Struktur dapat memiliki konstruktor serta bidang yang dapat diubah dan tidak dapat diubah, struktur juga dapat mendeklarasikan anggota dan implementasi antarmuka. Untuk informasi selengkapnya, lihat Anggota.
Struktur tidak dapat berpartisipasi dalam pewarisan, tidak boleh berisi pengikatan let
atau do
, dan tidak dapat secara rekursif berisi bidang dengan tipenya sendiri (meski dapat berisi sel referensi yang mereferensikan jenisnya sendiri).
Karena struktur tidak mengizinkan pengikatan let
, Anda harus mendeklarasikan bidang dalam struktur menggunakan kata kunci val
. Kata kunci val
menentukan bidang dan jenisnya tetapi tidak mengizinkan inisialisasi. Sebaliknya, deklarasi val
diinisialisasi ke nol atau null. Karena alasan ini, struktur yang memiliki konstruktor implisit (yaitu, parameter yang diberikan segera setelah nama struktur dalam deklarasi) mengharuskan deklarasi val
dianotasikan dengan atribut DefaultValue
. Struktur yang memiliki konstruktor yang ditentukan masih mendukung inisialisasi nol. Oleh karena itu, atribut DefaultValue
adalah deklarasi bahwa nilai nol tersebut valid untuk bidang. Konstruktor implisit untuk struktur tidak melakukan tindakan apa pun karena pengikatan let
dan do
tidak diizinkan di jenis tersebut, tetapi nilai parameter konstruktor implisit yang diteruskan tersedia sebagai bidang privat.
Konstruktor eksplisit mungkin melibatkan inisialisasi nilai bidang. Ketika Anda memiliki struktur dengan konstruktor eksplisit, struktur tersebut masih mendukung inisialisasi nol; tetapi Anda tidak menggunakan atribut DefaultValue
pada deklarasi val
karena bertentangan dengan konstruktor eksplisit. Untuk informasi selengkapnya tentang deklarasi val
, lihat Bidang Eksplisit: Kata Kunci val
.
Pengubah atribut dan aksesibilitas diizinkan pada struktur, dan mengikuti aturan yang sama seperti untuk jenis lainnya. Untuk informasi selengkapnya, lihat Atribut dan Access Control.
Contoh kode berikut mengilustrasikan definisi struktur.
// 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
Struct ByRefLike
Anda dapat menentukan struct Anda sendiri yang dapat mematuhi semantik byref
-like: lihat Byrefs untuk informasi selengkapnya. Hal ini dilakukan dengan atribut 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
tidak menyiratkan Struct
. Keduanya harus ada pada jenisnya.
Struktur "mirip byref
" di F# adalah jenis nilai yang terikat tumpukan. Struktur ini tidak pernah dialokasikan pada tumpukan yang terkelola. Struktur mirip byref
berguna untuk pemrograman performa tinggi, karena diberlakukan dengan serangkaian pemeriksaan yang kuat terkait masa pakai dan non-pengambilan. Aturannya adalah:
- Dapat digunakan sebagai parameter fungsi, parameter metode, variabel lokal, dan pengembalian metode.
- Tidak boleh menjadi anggota statis atau instans dari suatu kelas atau struktur normal.
- Tidak dapat diambil oleh konstruksi penutupan apa pun (metode
async
atau ekspresi lambda). - Tidak dapat digunakan sebagai parameter generik.
Meski aturan ini sangat membatasi penggunaan, hal ini dilakukan untuk memenuhi janji komputasi performa tinggi dengan cara yang aman.
Struct ReadOnly
Anda dapat membuat anotasi struct dengan atribut IsReadOnlyAttribute. Misalnya:
[<IsReadOnly; Struct>]
type S(count1: int, count2: int) =
member x.Count1 = count1
member x.Count2 = count2
IsReadOnly
tidak menyiratkan Struct
. Anda harus menambahkan keduanya untuk memiliki struct IsReadOnly
.
Penggunaan atribut ini memunculkan metadata yang memungkinkan F# dan C# mengetahui cara memperlakukannya sebagai inref<'T>
dan in ref
, masing-masing.
Menentukan nilai yang dapat diubah di dalam struct readonly menghasilkan kesalahan.
Rekaman Struct dan Gabungan Terdiskriminasi
Anda dapat mewakili Rekaman dan Gabungan Terdiskriminasi sebagai struct dengan atribut [<Struct>]
. Lihat setiap artikel untuk mempelajari selengkapnya.