Menu

Shape di Zero: Mendefinisikan Record Mirip Struct

Shape adalah product type ala struct di Zero. Inilah cara mendeklarasikannya, membuat nilainya, membaca field-nya, dan mengirimnya lewat fungsi, dengan contoh dari sampel resmi.

Halaman ini dilengkapi editor yang bisa dijalankan. Edit, jalankan, dan lihat output-nya seketika.

Mendeklarasikan Shape

shape adalah tipe record dengan field yang bernama dan bertipe:

shape Point {
    x: i32,
    y: i32,
}

Bagian-bagiannya:

  • shape mengawali deklarasi.
  • Point adalah nama tipenya.
  • Kurung kurawal membungkus daftar field, masing-masing dengan bentuk name: Type.

Deklarasi itu menambahkan tipe baru bernama Point ke scope yang sedang berlaku. Di mana pun kamu bisa memakai tipe bawaan seperti i32, sekarang kamu juga bisa memakai Point.

Membuat Nilai Shape

Buat sebuah instance dengan ekspresi literal struct:

let point = Point { x: 40, y: 2 }

Literal itu menyebut nama shape dan mengisi setiap field. Setiap field wajib ada, karena Zero tidak diam-diam mengisi field yang hilang dengan nol atau null. Kalau kamu lupa satu field, compiler akan memberitahumu:

{
    "code": "FLD002",
    "message": "missing field: y",
    "line": 4
}

(Kode error persisnya bisa berbeda, tetapi prinsip "tidak ada default implisit" tetap sama.)

Kamu bisa menulis anotasi tipenya secara eksplisit kalau ingin tipenya terlihat:

let point: Point = Point { x: 40, y: 2 }

Membaca Field

Akses field memakai sintaks titik:

let point = Point { x: 40, y: 2 }
let xVal  = point.x
let yVal  = point.y

point.x membaca field x. Tidak ada method get_x(), karena field adalah data biasa.

Contoh Lengkap

Ini contoh point.0 standar dari repository bahasa ini. Klik Jalankan untuk mencobanya:

Telusuri dari atas:

  1. Deklarasikan shape Point dengan dua field i32.
  2. Definisikan fungsi sum yang menerima Point dan mengembalikan jumlah kedua field-nya.
  3. Di main, buat sebuah Point, panggil sum, lalu bandingkan hasilnya.

Tiga langkah, tiga ide seputar shape (deklarasi, pembuatan, akses), dan satu efek, yaitu check world.out.write(...) di bagian akhir. Perhatikan bahwa sum tidak menyentuh World. Itu fungsi murni atas data, dan signature-nya membuat hal itu jelas.

Shape dengan Field Bersarang

Shape bisa menyimpan nilai bertipe apa pun, termasuk shape lain:

shape Range {
    start: i32,
    end: i32,
}

shape Segment {
    label: String,
    range: Range,
}

let seg = Segment {
    label: "warmup",
    range: Range { start: 0, end: 10 },
}

Akses field bisa dirangkai seperti yang kamu harapkan:

let len = seg.range.end - seg.range.start

Shape Generic

Saat field sebuah shape perlu bisa menerima berbagai tipe, deklarasikan parameter tipe di dalam kurung sudut:

shape Pair<T, U> {
    left: T,
    right: U,
}

Instance-nya menetapkan parameter itu ke tipe konkret:

let intBytePair: Pair<i32, u8> = Pair { left: 40, right: 2_u8 }
let words: Pair<String, String> = Pair { left: "hello", right: "world" }

Alias tipe bisa menyingkat parameterisasi yang sering dipakai:

type BytePair = Pair<u8, u8>

let bytes: BytePair = Pair { left: 1_u8, right: 2_u8 }

Generic membahas parameter tipe lebih dalam, termasuk pada fungsi, bukan hanya pada shape.

Yang Tidak Dimiliki Shape

Beberapa hal yang mungkin kamu harapkan dari "struct" di bahasa lain, tetapi sengaja tidak disertakan dalam shape:

  • Tidak ada method. Deklarasi shape hanyalah data. Perilaku ditulis di fungsi lepas yang menerima shape sebagai parameter. Ini mencerminkan pemisahan data dan efek yang sama dengan yang kamu lihat di fungsi.
  • Tidak ada inheritance. Shape tidak bisa memperluas shape lain. Kalau kamu ingin struktur yang sama dipakai bersama, pindahkan ke field bersama atau buat sum type dengan choice.
  • Tidak ada constructor atau destructor implisit. Pembuatan nilai dilakukan dengan ekspresi literal struct. Pembersihan bersifat eksplisit: saat standard library menyediakan resource yang perlu dibuang, hal itu dilakukan lewat API bergaya capability, bukan lewat RAII tersembunyi.
  • Tidak ada field privat. Semua field sebuah shape bisa diakses oleh kode yang bisa melihat tipe shape itu. Visibilitas berlaku di tingkat tipe, bukan di tingkat field.

Polanya: shape adalah tipe record yang sederhana dan mudah ditebak, dan semua hal lain kamu bangun dari situ.

Kapan Memakai Shape dan Kapan Memakai Choice

Panduan singkat:

  • Pakai shape saat sebuah nilai punya semua field ini sekaligus. Point selalu punya x dan y.
  • Pakai choice saat sebuah nilai adalah salah satu dari beberapa alternatif. Result adalah antara ok atau err.
  • Pakai enum saat alternatifnya tidak membawa data tambahan dan hanya berupa label. Nama hari dalam seminggu, state sederhana.

Ketiga bahan dasar ini, yaitu shape (dan), choice (atau), dan enum (atau tanpa payload), mencakup hampir semua kebutuhan pemodelan data.

Berikutnya: Generic

Kamu sudah melihat Pair<T, U> muncul sekilas. Dokumen berikutnya, generic, menjelaskan cara kerja parameter tipe pada shape maupun fungsi, termasuk pola-pola yang muncul di seluruh standard library Zero.

Pertanyaan yang sering diajukan

Apa itu shape di Zero?

shape adalah product type ala struct di Zero, yaitu record bernama dengan field-field bertipe. Kamu mendeklarasikannya dengan shape Name { field1: T1, field2: T2 }, membuat nilainya dengan Name { field1: v1, field2: v2 }, dan membaca field-nya dengan sintaks titik (value.field1). Shape adalah bahan dasar untuk memodelkan data yang terstruktur.

Bagaimana cara membuat nilai shape?

Pakai ekspresi literal struct yang menyebut nama shape dan mengisi setiap field: let point = Point { x: 40, y: 2 }. Setiap field harus diisi, karena Zero tidak diam-diam memberi nilai default pada field yang hilang. Urutan field di literal tidak harus sama dengan urutan di deklarasi.

Apa bedanya shape dengan class?

Shape adalah data biasa: punya field, tetapi tidak punya method, inheritance, atau constructor implisit. Fungsi yang bekerja dengan sebuah shape menerimanya sebagai parameter secara eksplisit. Pemisahan ini menjaga bahasanya tetap kecil dan membuat biaya membangun atau menyalin shape mudah ditebak, tanpa vtable atau destructor tersembunyi.

Apakah shape bisa generic di Zero?

Bisa. Deklarasikan parameter tipe di dalam kurung sudut: shape Pair<T, U> { left: T, right: U }. Instance-nya menetapkan parameter itu: Pair<i32, u8>. Shape generic muncul di seluruh standard library: Maybe<T>, Span<T>, dan sejenisnya adalah shape generic atau sum type yang dibangun dari ide yang sama.

Apakah shape disalin atau direferensikan saat dikirim ke fungsi?

Model berpikir default untuk shape adalah pass-by-value: fungsi yang dipanggil melihat salinan datanya sendiri secara logis, bukan referensi ke binding milik pemanggil. Model memori yang persis di Zero pra-1.0 masih terus berkembang (kamu akan melihat ref dan mutref di contoh standard library untuk tipe referensi yang eksplisit). Untuk sebagian besar kode aplikasi, anggap parameter shape sebagai input bertipe nilai.

Ilustrasi bahasa pemrograman di Coddy

Belajar coding dengan Coddy

Mulai