Record adalah tipe komposit yang menggabungkan beberapa nilai menjadi satu kesatuan, dan setiap nilai disimpan pada komponen bernama yang disebut bidang. Topik ini membahas deklarasi record beserta akses bidangnya, nilai bawaan pada setiap bidang, dan penulisan agregat record (record aggregate), yaitu notasi untuk menyusun nilai record secara utuh dalam satu ekspresi. Contoh pada topik ini menggunakan titik koordinat dan bacaan sensor, dan seluruh programnya dapat dikompilasi serta dijalankan dengan GNAT.
Deklarasi record dan akses bidang#
Deklarasi record diawali type Nama is record, diikuti daftar bidang dengan tipenya masing-masing, dan ditutup dengan end record;. Urutan bidang pada deklarasi menentukan urutan penyimpanan secara bawaan, sehingga dua bidang bertipe sama tetap merupakan komponen yang berbeda apabila posisinya berbeda. Sebuah bidang diakses dengan notasi titik, misalnya A.X untuk membaca atau mengisi bidang X dari variabel A. Penugasan antara dua objek record bertipe sama menyalin seluruh nilai bidang sekaligus, sehingga bidang tidak perlu disalin satu per satu.
-- tidak-dijalankan
type Titik is record
X : Float := 0.0;
Y : Float := 0.0;
end record;
Asal : Titik;
Asal.X := 3.0;
Asal.Y := 4.0;Notasi titik juga berlaku berlapis pada record di dalam record, misalnya Ruang.Pos.X apabila Pos merupakan bidang bertipe Titik di dalam record Ruang. Akses berlapis ini bekerja untuk kedalaman berapa pun, selama setiap tingkatnya merupakan record dengan bidang yang sesuai. Tipe bidang boleh merupakan tipe apa pun yang sudah dideklarasikan, termasuk record lain, array, maupun tipe enumerasi. Kombinasi tersebut menjadikan record cocok untuk menyusun data terstruktur dalam program.
Dua tipe record dengan susunan bidang yang sama persis tetap merupakan dua tipe yang berbeda. Penugasan antara objek dari dua tipe semacam itu ditolak kompilator, sekalipun seluruh bidangnya identik, karena pengetikan kuat memperlakukan kedua tipe tersebut sebagai tipe yang tidak berkaitan. Apabila pertukaran nilai memang diinginkan, kedua objek harus bertipe sama. Aturan ini mencegah kekeliruan pada data yang bentuknya kebetulan sama tetapi maknanya berbeda, karena penolakan terjadi sebelum program berjalan.
Nilai bawaan pada bidang#
Setiap bidang boleh memiliki nilai bawaan yang ditulis setelah tanda := pada deklarasinya. Nilai tersebut digunakan setiap kali objek dideklarasikan tanpa nilai awal, sehingga objek record langsung berada dalam keadaan yang sah sejak baris deklarasinya. Kebiasaan ini mencegah error yang lazim, yaitu membaca bidang yang belum pernah diisi. Nilai bawaan juga digunakan pada alokasi dengan new, sehingga objek yang dialokasikan mengambil nilai bawaan tersebut.
Nilai bawaan tidak membatasi bidang, karena setiap bidang tetap dapat diisi ulang dengan penugasan biasa. Dengan kata lain, nilai bawaan hanya menyatakan titik awal, bukan kendala. Apabila bidang memang tidak boleh berubah setelah dibuat, penjagaannya dilakukan pada lapisan package melalui tipe privat beserta operasi yang diekspor.
Nilai bawaan ditulis pada spesifikasi tipe, sehingga keputusan keadaan awal berada di satu tempat dan tidak tersebar pada setiap deklarasi objek. Apabila bidang baru ditambahkan beserta nilai bawaannya, deklarasi objek lama yang tidak menyebut bidang tersebut tetap benar tanpa perubahan apa pun. Sifat ini menjadikan nilai bawaan bagian dari perawatan tipe, bukan sekadar keringkasan penulisan.
Agregat record#
Agregat record menyusun seluruh nilai bidang dalam satu ekspresi, dan bentuknya ada dua, yaitu posisional dan bernama. Bentuk posisional menuliskan nilai berurutan sesuai urutan deklarasi bidang, sedangkan bentuk bernama menyebut nama bidangnya dengan tanda =>. Bentuk bernama tidak harus lengkap apabila bidang yang tersisa ditutup dengan others, dan tanda <> yang disebut box menyatakan bidang tersebut mengambil nilai bawaannya. Program berikut memperagakan bentuk-bentuk penulisan tersebut beserta penyalinan record.
Agregat juga dapat ditulis di tengah pernyataan, misalnya Utara := (X => 1.0, Y => 2.0);, sehingga isi record dapat diganti secara utuh tanpa menyebut bidang satu per satu. Bentuk seperti ini lazim digunakan sebagai parameter subprogram dan pada ekspresi yang menyusun data baru.
with Ada.Text_IO; use Ada.Text_IO;
procedure Titik_Sensor is
-- Record titik dengan dua bidang numerik dan nilai bawaan nol.
type Titik is record
X : Float := 0.0;
Y : Float := 0.0;
end record;
-- Record bacaan sensor dengan bidang bertipe berbeda.
type Bacaan is record
Sudut : Float := 0.0;
Jarak : Float := 0.0;
Aktif : Boolean := False;
end record;
package Real_IO is new Ada.Text_IO.Float_IO (Float);
use Real_IO;
-- Tanpa agregat: seluruh bidang mengambil nilai bawaan.
Nol : Titik;
-- Agregat bernama: setiap bidang disebut dengan tanda =>.
Utara : Titik := (X => 0.0, Y => 4.0);
-- Agregat posisional: urutannya mengikuti deklarasi record.
Uji_A : Bacaan := (30.0, 12.5, True);
-- Agregat bernama dengan box: bidang tanpa nilai mengambil bawaan.
Uji_B : Bacaan := (Sudut => 90.0, others => <>);
Salinan : Titik;
procedure Cetak_Titik (Label : String; T : Titik) is
begin
Put (Label & ": (");
Put (T.X, Fore => 0, Aft => 1, Exp => 0);
Put (", ");
Put (T.Y, Fore => 0, Aft => 1, Exp => 0);
Put_Line (")");
end Cetak_Titik;
procedure Cetak_Bacaan (Label : String; B : Bacaan) is
begin
Put (Label & ": sudut=");
Put (B.Sudut, Fore => 0, Aft => 1, Exp => 0);
Put (" jarak=");
Put (B.Jarak, Fore => 0, Aft => 1, Exp => 0);
Put (" aktif=");
Put_Line (Boolean'Image (B.Aktif));
end Cetak_Bacaan;
begin
Cetak_Titik ("Nol ", Nol);
Cetak_Titik ("Utara ", Utara);
Cetak_Bacaan ("Uji_A ", Uji_A);
Cetak_Bacaan ("Uji_B ", Uji_B);
-- Penugasan antar record menyalin seluruh nilainya.
Salinan := Utara;
Utara.Y := 6.0;
Cetak_Titik ("Salinan", Salinan);
Cetak_Titik ("Utara ", Utara);
end Titik_Sensor;# kompilasi program
gnatmake -q titik_sensor.adb
# jalankan program
./titik_sensorNol : (0.0, 0.0)
Utara : (0.0, 4.0)
Uji_A : sudut=30.0 jarak=12.5 aktif=TRUE
Uji_B : sudut=90.0 jarak=0.0 aktif=FALSE
Salinan: (0.0, 4.0)
Utara : (0.0, 6.0)Keluaran menunjukkan bahwa keempat cara deklarasi menghasilkan objek dalam keadaan awal yang sah. Nol tidak membawa agregat sama sekali, sehingga kedua bidangnya mengambil nilai bawaan 0.0. Uji_B menggunakan box untuk bidang Jarak dan Aktif, sehingga keduanya mengambil nilai bawaan 0.0 dan False. Pada bagian akhir, Salinan tetap bernilai (0.0, 4.0) setelah Utara.Y diubah menjadi 6.0, karena penugasan Salinan := Utara menyalin nilai pada saat itu dan tidak mengikat kedua objek.
Kesalahan umum#
- Menulis agregat posisional dengan jumlah nilai yang tidak sama dengan jumlah bidang. Kompilator menolak agregat tersebut karena nilai tiap bidang tidak dapat dipetakan. Perbaikannya, lengkapi nilainya, atau ubah ke bentuk bernama yang komponennya dapat diperiksa satu per satu.
- Menulis agregat yang tidak menyebut nilai setiap bidang dan tidak ditutup
others. Asosiasi posisional boleh mendahului asosiasi bernama pada agregat yang sama, tetapi seluruh bidang tetap wajib memperoleh nilai, sehingga penulisan(30.0, Jarak => 12.5)ditolak dengan pesan bahwa bidangAktifbelum diberi nilai. Perbaikannya, lengkapi nilai bidang yang tersisa atau tutup sisanya denganothers. - Menyebut nama bidang yang tidak ada, misalnya
Suhupada recordBacaan. Notasi titik hanya menerima nama bidang yang terdaftar pada deklarasi record, sehingga kompilator menolaknya. Perbaikannya, periksa ejaan bidang pada deklarasi record yang dimaksud. - Menyalin record antar variabel yang bentuk bidangnya sama tetapi tipenya berbeda. Kompilator menolak penugasan tersebut sesuai pembahasan dua tipe record pada bagian deklarasi. Perbaikannya, deklarasikan kedua variabel dengan tipe yang sama, atau pertukarkan nilainya melalui subprogram yang menyatakan konversinya secara jelas.
Ringkasan#
- Record menggabungkan beberapa bidang bernama dalam satu tipe, diakses dengan notasi titik, dan disalin utuh pada penugasan antar objek.
- Nilai bawaan pada bidang menjaga objek tetap sah sejak deklarasi, baik tanpa nilai awal maupun pada alokasi dengan
new. - Agregat record ditulis secara posisional atau bernama, dengan
othersdan box<>untuk bidang yang mengambil nilai bawaan.
Referensi#
- Ada Reference Manual 2022, Bagian 3.8 Record Types — Ada Resource Association — Penetapan bahasa mengenai deklarasi record, komponen, dan aturan variannya.
- Introduction to Ada: Records — AdaCore — Bab kursus resmi yang membahas deklarasi record dan penulisan agregatnya.