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.

Lihat juga