Crystal menyediakan beberapa tipe dasar yang menjadi bahan hampir semua program, yaitu string untuk teks, array dan hash untuk kumpulan nilai, serta symbol dan tuple sebagai pelengkapnya. Topik ini membahas penulisan nilai dari masing-masing tipe beserta operasi dasarnya, mulai dari interpolasi string, penambahan elemen array, hingga akses kunci hash. Setelah membaca topik ini, kontainer yang tepat untuk data tertentu dapat dipilih sambil memahami tipe yang disimpulkan compiler untuk setiap nilainya.
String dan interpolasi#
String menyimpan rangkaian karakter teks dan ditulis di antara tanda kutip ganda. String dalam Crystal disimpan sebagai teks UTF-8, sehingga karakter di luar ASCII seperti é tetap dihitung sebagai satu karakter. Penanaman hasil ekspresi ke dalam teks disebut interpolasi (string interpolation) dan ditulis dengan #{...}. Saat program berjalan, ekspresi di dalam #{...} dievaluasi dan hasilnya disambungkan ke bagian teks yang mengapitnya.
Pengukuran panjang tersedia dalam dua bentuk, yaitu size yang menghitung karakter dan bytes yang menghitung byte penyimpanannya. Program berikut menggunakan interpolasi untuk menyusun teks, lalu mengukur dan mengubahnya.
# Interpolasi string dan pengukuran panjangnya
nama = "Ayu"
jumlah = 3
teks = "#{nama} memiliki #{jumlah} buku"
p teks
p teks.size
p teks.upcaseJalankan berkasnya dengan perintah berikut.
# jalankan program teks.cr
crystal run teks.cr"Ayu memiliki 3 buku"
19
"AYU MEMILIKI 3 BUKU"Hasil interpolasi menempatkan nilai nama dan jumlah di tengah teks tanpa penyambungan manual. Metode size menghitung 19 karakter pada teks tersebut, sedangkan upcase mengembalikan salinan baru dalam huruf kapital. Metode pada string tidak mengubah string yang memanggilnya, sehingga hasilnya ditampung ke variabel baru apabila ingin disimpan.
Perbedaan karakter dan byte tampak jelas pada teks yang memuat karakter multibyte.
kata = "résumé"
p kata.size
p kata.bytes6
[114, 195, 169, 115, 117, 109, 195, 169]Karakter é membutuhkan dua byte dalam UTF-8, sehingga kata tersebut terdiri atas enam karakter tetapi delapan byte. Pilihan metode ini menentukan hasil saat teks diproses pada tingkat byte, misalnya saat menghitung ukuran data sebelum dikirim melalui jaringan.
Array dan literalnya#
Array menyimpan rangkaian nilai yang dapat diakses melalui posisinya, dan penulisan nilai secara langsung di dalam kode disebut literal (literal). Literal [1, 2, 3] menghasilkan array bertipe Array(Int32) karena seluruh elemennya bilangan bulat. Operasi yang lazim digunakan antara lain push untuk menambah elemen di akhir, size untuk menghitung elemen, first dan last untuk ujungnya, serta includes? untuk memeriksa keanggotaan.
Program berikut mempraktikkan operasi tersebut, termasuk literal %w[...] yang membuat array string dari kata-kata yang dipisahkan spasi.
# Operasi dasar array
angka = [1, 2, 3]
angka.push(4)
p angka
p angka.size
p angka.first
p angka.last
p angka.includes?(2)
kata = %w[jambu apel mangga]
p kata
citra = %W[foo #{"bar"} baz]
p citra[1, 2, 3, 4]
4
1
4
true
["jambu", "apel", "mangga"]
["foo", "bar", "baz"]Metode push mengubah array yang sama, sehingga deret yang awalnya tiga elemen menjadi empat. Literal %w[...] menghasilkan array string tanpa tanda kutip per kata, sedangkan bentuk %W[...] mengizinkan interpolasi sehingga #{"bar"} diperluas menjadi satu elemen tersendiri.
Tipe array disimpulkan compiler dari isi literalnya.
angka = [1, 2]
p typeof(angka)
campur = [1, "dua"]
p typeof(campur)Array(Int32)
Array(Int32 | String)Array yang seluruh elemennya bilangan bulat menghasilkan Array(Int32), sedangkan array yang mencampur angka dan teks menghasilkan tipe union (union type), yaitu tipe gabungan beberapa kemungkinan yang ditulis dengan tanda |. Menjaga isi satu array tetap satu jenis merupakan kebiasaan yang lazim karena tipenya tetap sederhana dan setiap elemen dapat digunakan dengan operasi yang sama.
Hash dan akses kuncinya#
Hash menyimpan pasangan kunci dan nilai, dan literal {"pensil" => 12} menghasilkan Hash(String, Int32). Pembacaan nilai dilakukan dengan menyebut kuncinya pada kurung siku, sedangkan penugasan dengan kunci baru menambahkan pasangan. Bentuk []? memeriksa kunci dengan aman karena mengembalikan nil alih-alih menghentikan program ketika kunci tidak ada.
Program berikut menyusun catatan stok dari sebuah hash berkunci string lalu sebuah hash berkunci symbol.
# Stok gudang sederhana
stok = {"pensil" => 12, "buku" => 7}
stok["penghapus"] = 5
p stok
p stok["buku"]
p stok["pensil"]?
laci = {:pensil => 12, :buku => 7}
p laci[:buku]
p laci[:bolpoin]?{"pensil" => 12, "buku" => 7, "penghapus" => 5}
7
12
7
nilPenugasan stok["penghapus"] = 5 menambah pasangan baru karena kuncinya belum ada, dan keluaran pertama menampilkannya pada posisi akhir. Pemanggilan stok["buku"] mengembalikan nilai 7, sedangkan laci[:bolpoin]? mengembalikan nil karena kunci tersebut tidak pernah ditambahkan. Kunci yang ditulis dengan awalan titik dua adalah symbol, dan pemanggilan laci[:buku] menunjukkan bahwa symbol digunakan sebagai kunci hash dengan pola yang sama seperti string.
Symbol layak diperkenalkan lebih rinci karena kehadirannya sebagai kunci hash sangat umum.
simbol = :nama
p typeof(simbol)
p :nama == "nama"
campur = {"pensil" => 12, :buku => 7}
p typeof(campur)Symbol
false
Hash(String | Symbol, Int32)Symbol adalah objek ringan yang mewakili sebuah nama dan ditulis dengan awalan titik dua. Perbandingan :nama == "nama" bernilai false karena symbol dan string adalah tipe yang berbeda meskipun namanya sama. Hash yang kuncinya mencampur keduanya menghasilkan tipe kunci String | Symbol, dan konvensi kode Crystal lazim memilih symbol sebagai kunci hash karena penulisannya singkat.
Tuple sebagai pembeda array#
Tuple menyimpan sekelompok nilai dengan panjang tetap, dan tipe setiap posisinya diketahui compiler sejak saat compile. Literal tuple ditulis dalam kurung kurawal dengan koma sebagai pemisah, berbeda dari literal hash yang menggunakan => antara kunci dan nilainya.
pasangan = {1, "dua"}
p typeof(pasangan)
p pasangan[0] + 5Tuple(Int32, String)
6Tipe Tuple(Int32, String) menyatakan bahwa posisi 0 selalu bertipe Int32 dan posisi 1 selalu bertipe String. Karena kepastian itu, operasi pasangan[0] + 5 langsung sah tanpa pemeriksaan tambahan. Array campur seperti [1, "dua"] tidak memberikan kepastian per posisi, sehingga tipenya dinyatakan sebagai union untuk setiap elemen. Tuple dengan demikian tepat digunakan ketika jumlah nilai dan kedudukannya sudah pasti, misalnya untuk mengembalikan beberapa hasil dari satu pemanggilan metode.
Kesalahan umum#
Mengakses kunci yang tidak ada dengan []. Pemanggilan stok["bolpoin"] pada hash yang tidak memiliki kunci tersebut menghentikan program dengan exception KeyError. Pilih metode sesuai maksudnya, yaitu []? apabila ketiadaan kunci adalah keadaan yang wajar dan hasilnya perlu diperiksa, sedangkan [] hanya tepat apabila kunci dijamin ada.
Mengira %w mempertahankan spasi. Pemisah pada %w[...] adalah spasi, sehingga teks yang berisi spasi tidak dapat ditulis dengan bentuk ini.
daftar = %w[kuda nil]
p daftar
p daftar.size["kuda", "nil"]
2Literal tersebut menghasilkan dua elemen, bukan satu. Untuk satu elemen yang memuat spasi, gunakan penulisan array biasa seperti ["kuda nil"].
Ringkasan#
- String disimpan sebagai UTF-8, interpolasi
#{...}menanamkan hasil ekspresi ke teks, dansizemenghitung karakter sementarabytesmenghitung byte. - Literal
[...]membuat array yang tipenya disimpulkan compiler,%w[...]membuat array string tanpa kutip per kata, dan%W[...]menambahkan dukungan interpolasi. - Literal
{"kunci" => nilai}membuat hash,[]menghentikan program denganKeyErrorketika kunci tidak ada, sedangkan[]?mengembalikan nil. - Symbol mewakili sebuah nama dan lazim digunakan sebagai kunci hash, sedangkan tuple menyimpan nilai dengan tipe per posisi yang diketahui compiler.
Referensi#
- Literal — Crystal Language Reference — Aturan penulisan literal string, array, hash, symbol, dan tuple.
- String — Dokumentasi API Crystal 1.22.1 — Metode string seperti size, bytes, dan upcase.
- Array — Dokumentasi API Crystal 1.22.1 — Operasi array seperti push, first, last, dan includes?.
- Hash — Dokumentasi API Crystal 1.22.1 — Akses kunci hash beserta pasangan metode [] dan []?.
- Symbol — Dokumentasi API Crystal 1.22.1 — Definisi symbol dan perbandingannya dengan string.