Topik ini menuntaskan penanganan teks pada Erlang: string yang ternyata list kode titik unicode, penggabungan dan formatnya, serta dasar-dasar binary sebagai wadah data biner yang lebih hemat. Pembahasan bit syntax yang lengkap, termasuk ukuran unit dan pencocokan segmen majemuk, ditutup pada modul Penyimpanan dan binary. Topik ini hanya membahas dasar yang dipakai setiap hari.
String adalah list#
String pada Erlang bukan tipe tersendiri, melainkan list berisi kode titik unicode. Tanda kutip ganda hanyalah notasi penulisan yang praktis, dan nilainya tetap list biasa:
Erlang/OTP 29 [erts-17.1.1] [source] [64-bit] [smp:2:2] [ds:2:2:10] [async-threads:1] [jit:ns]
Eshell V17.1.1 (press Ctrl+G to abort, type help(). for help)
1> "halo".
"halo"
2> length("halo").
4
3> [104, 97, 108, 111] =:= "halo".
truelength/1 bekerja pada string karena memang fungsi list, dan perbandingan =:= menegaskan kesetaraan keduanya. Konsekuensi langsungnya ada pada pencetakan: shell menampilkan list sebagai string bila seluruh elemennya kode karakter yang dapat dicetak, dan menampilkan angka bila tidak, sehingga list yang sama bisa tercetak berbeda tergantung pada isinya. Perilaku ini diingatkan kembali setiap kali contoh mencetak list bilangan yang kebetulan tampak seperti teks.
Menggabungkan dan memformat#
Karena string adalah list, penggabungannya memakai operator ++, dan pemformatan teks memakai io_lib:format/2 atau io:format/2 dengan kode ~s untuk string dan ~p untuk nilai apa pun:
4> "ha" ++ "lo".
"halo"
5> io_lib:format("Nilai: ~p dari ~s", [42, "kalkulator"]).
"Nilai: 42 dari kalkulator"Pengembalian io_lib:format/2 memakai struktur iodata, yaitu list yang boleh bersarang berisi string dan binary, yang diterima semua fungsi keluaran tanpa perlu diratakan lebih dulu. Bentuk ini menjadi kebiasaan baku saat menyusun teks dari beberapa potong, dan penghematan iodata dibahas lebih jauh pada modul Penyimpanan dan binary.
Biaya ++ pada string mengikuti aturan list: menyambung di depan murah, menyambung di belakang menyalin sisi kiri. Untuk teks yang disambung berulang, binary pada bagian akhir topik ini memberikan alternatif yang lebih hemat. Fungsi io:format/2 langsung menuliskan hasilnya ke perangkat keluaran standar, sehingga perbedaannya dengan io_lib:format/2 adalah tujuan: satu untuk menulis, satu untuk menyusun nilai yang siap dikirim.
Binary sebagai wadah biner#
Binary adalah deretan byte yang ditulis di antara << dan >>. Berbeda dengan list yang tiap elemennya berdiri sendiri dengan overhead cons cell, binary menyimpan byte secara rapat sehingga menjadi wadah standar untuk data dari jaringan dan berkas:
5> unicode:characters_to_binary("halo").
<<"halo">>
6> <<"halo">> =:= <<104, 97, 108, 111>>.
trueFungsi unicode:characters_to_binary/1 mengubah string menjadi binary UTF-8, dan cetakan <<"halo">> menunjukkan binary yang isinya kebetulan teks. Pemeriksaan =:= membandingkan byte demi byte sehingga binary teks dan binary angka yang isinya sama dianggap sama persis. Konversi sebaliknya memakai binary_to_list/1:
1> binary_to_list(<<"halo">>).
"halo"Aturan praktisnya: string untuk teks yang sedang dibangun di memori, binary untuk data yang dipindahkan atau disimpan.
Satuan pengukuran: kode titik versus byte#
Perbedaan string dan binary terasa pada pengukuran panjang. length/1 menghitung kode titik unicode, sedangkan byte_size/1 menghitung byte, dan keduanya berbeda bila ada karakter yang membutuhkan lebih dari satu byte dalam UTF-8:
2> Kata = "koën".
"koën"
3> length(Kata).
4
4> byte_size(unicode:characters_to_binary(Kata)).
5Teks koën terdiri atas empat kode titik dengan huruf ë membutuhkan dua byte dalam UTF-8, sehingga binarynya berisi lima byte. Karena itu satuan yang dipilih harus sesuai keperluan: batas kolom basis data lazim diukur byte, sedangkan batas tampilan antarmuka diukur kode titik. Mengukur dengan satuan yang keliru tidak memicu error, melainkan menghasilkan batas yang diam-diam berbeda dari maksud desainnya.
Pencocokan pola pada binary#
Binary mengikuti aturan pencocokan pola dengan sintaks segmen. Pola <<A, B, C>> mengikat tiga byte pertama, sedangkan spesifikasi /binary mengambil seluruh sisa sebagai binary:
7> <<A, B, C>> = <<1, 2, 3>>.
<<1,2,3>>
8> A.
1
9> <<"ha", Sisa/binary>> = <<"halo">>.
<<"halo">>
10> Sisa.
<<"lo">>Pola <<"ha", Sisa/binary>> mencocokkan dua byte awal sebagai teks ha dan mengikat sisanya ke Sisa sebagai binary, sehingga penguraian header protokol ditulis seringkas data yang diuraikan. Segmen juga bisa ditulis dengan ukuran tetap seperti <<B:16>> untuk dua byte sekaligus, dan seluruh mekanisme ukuran unit serta kombinasi segmennya dituntaskan pada modul Penyimpanan dan binary.
Kesalahan umum#
- Mengira list dan binary itu saling dipertukarkan.
"halo"dan<<"halo">>adalah nilai berbeda yang pencetakannya mirip, dan fungsi list sepertilength/1gagal pada binary. Konversikan denganunicode:characters_to_binary/1ataubinary_to_list/1secara eksplisit. - Menyambung teks berulang dengan
++di dalam perulangan. Setiap penyambungan menyalin seluruh teks sisi kiri, sedangkan pembangunan binary dengan akumulator memakai<<Acc/binary, Byte>>yang lebih hemat, dan polanya dituntaskan pada modul Penyimpanan dan binary. - Mengabaikan unicode pada panjang teks.
length/1menghitung kode titik, bukan byte, sehingga teks beraksen dan binary UTF-8-nya punya angka panjang yang berbeda. Pilih satuan yang benar sebelum memotong atau mengukur.
Ringkasan#
- String adalah list kode titik unicode, sehingga length/1 dan ++ bekerja padanya dan pencetakannya bergantung pada isi list.
- io_lib:format/2 dan io:format/2 memformat teks dengan ~s untuk string dan ~p untuk nilai apa pun.
- Binary adalah deretan byte rapat yang ditulis «…», menjadi wadah standar data jaringan dan berkas, dan unicode:characters_to_binary/1 mengubah string menjadi binary UTF-8.
- Pencocokan pola binary menguraikan segmen byte dan /binary mengambil sisanya, dasar dari bit syntax lengkap pada modul Penyimpanan dan binary.
Referensi#
- Erlang Reference Manual: Data Types — Ericsson — Dokumentasi resmi string, binary, dan representasinya.
- unicode — Ericsson — Dokumentasi resmi penanganan unicode dan konversi antar wadah teks.
- Learn You Some Erlang for Great Good! — Fred Hebert — Bab yang memperkenalkan string sebagai list beserta kejutan pencetakannya.