Topik ini membahas sistem tipe Lua secara menyeluruh, mulai dari kedelapan tipe dasar beserta fungsi type() untuk memeriksanya, pengetikan dinamis, peran khusus nilai nil, aturan nilai kebenaran, dua sub-tipe pada tipe number, hingga konversi otomatis antara string dan number. Setelah menyelesaikannya, perilaku setiap nilai pada operasi aritmetika maupun uji kondisi dapat dijelaskan dengan istilah yang tepat.
Delapan tipe dasar#
Lua hanya memiliki kedelapan tipe dasar berikut, dan tidak ada tipe lain, yaitu nil, boolean, number, string, function, userdata, thread, dan table. Tipe melekat pada nilai, bukan pada variabel, sehingga nilai apa pun dapat diperiksa tipenya di mana pun nilai itu berada. Fungsi type() menerima satu nilai dan mengembalikan nama tipe nilai tersebut dalam bentuk string, misalnya "number" atau "table". Nama table merujuk pada satu tipe tunggal, sehingga seluruh bentuk kumpulan data pada Lua dibangun di atasnya.
Tabel berikut merangkum peran setiap tipe.
| Tipe | Peran |
|---|---|
nil | Penanda ketiadaan nilai |
boolean | Nilai kebenaran true dan false |
number | Bilangan bulat maupun pecahan |
string | Urutan byte 8-bit, umumnya teks |
function | Fungsi, yang dapat ditampung dan dipindah seperti nilai lain |
userdata | Data milik program host, yaitu aplikasi yang menyematkan Lua |
thread | Alur eksekusi kooperatif yang dihasilkan coroutine |
table | Satu-satunya struktur data Lua untuk seluruh bentuk kumpulan data |
Berkas berikut memanggil type() atas satu contoh nilai untuk setiap tipe. Nilai bertipe userdata diambil dari aliran keluaran standar pustaka io, sedangkan nilai bertipe thread diambil dari coroutine, yaitu jalur eksekusi kooperatif yang dapat dihentikan dan dilanjutkan secara terkendali. Perhatikan bahwa 10 dan 3.5 sama-sama dilaporkan sebagai number, karena keduanya berada di dalam tipe yang sama.
-- Memeriksa tipe satu nilai dari setiap tipe dasar Lua
print(type(nil))
print(type(true))
print(type(10))
print(type(3.5))
print(type("Citra"))
print(type(print))
print(type(io.stdout))
print(type(coroutine.create(function() end)))
print(type({90, 85, 78}))nil
boolean
number
number
string
function
userdata
thread
tablePengetikan dinamis#
Lua menerapkan pengetikan dinamis (dynamic typing), yaitu skema yang memeriksa tipe saat program berjalan, bukan saat kode ditulis atau dikompilasi. Akibatnya, variabel tidak memiliki tipe, dan yang memiliki tipe adalah nilai yang sedang ditampungnya. Satu nama variabel boleh menampung number pada satu baris, kemudian menampung string atau nil pada baris berikutnya, tanpa deklarasi maupun konversi apa pun.
Fleksibilitas ini menuntut kehati-hatian yang seimbang. Kesalahan tipe tidak tertangkap saat kode ditulis, melainkan baru muncul saat program berjalan. Kebiasaan yang menjaga kejelasan adalah memeriksa tipe nilai yang berasal dari luar fungsi sendiri dengan type() sebelum nilai itu diolah lebih lanjut.
Berkas berikut mengganti isi satu variabel dua kali, lalu menanyakan tipenya pada setiap tahap.
-- Satu variabel menampung nilai bertipe berbeda sepanjang hidupnya
local skor = 90
print(type(skor))
skor = "sembilan puluh"
print(type(skor))
skor = nil
print(type(skor))number
string
nilNilai balik type() berupa string, sehingga pemeriksaan tipe dapat dilakukan dengan perbandingan biasa tanpa pustaka tambahan.
-- Nilai balik type() berupa string sehingga dapat dibandingkan langsung
local skor = 90
if type(skor) == "number" then
print("skor berupa bilangan")
endskor berupa bilanganPeran khusus nil#
nil adalah satu-satunya nilai pada satu-satunya tipenya, dan tipe ini berperan sebagai penanda ketiadaan nilai (absence of value). Setiap variabel yang belum diberi nilai bernilai nil, dan penugasan nil kepada suatu variabel menghapus nilai yang lama. Fungsi print() menampilkan teks nil untuk nilai ini, sehingga ketiadaan nilai memperoleh nama yang terlihat hanya pada saat ditampilkan.
-- Variabel yang belum diberi nilai tetap bernilai nil
local catatan
print(catatan)nilPeran kedua nil adalah menghapus pasangan kunci-nilai dari sebuah table. Penugasan nil kepada satu kunci membuat kunci tersebut tidak lagi ada di dalam table, berbeda dari menyimpan nilai yang tidak berguna. Berkas berikut menghapus satu jadwal dari sebuah table.
-- Penugasan nil menghapus pasangan kunci-nilai dari sebuah table
local jadwal = { senin = "Matematika", selasa = "Fisika" }
jadwal.senin = nil
print(jadwal.senin)
print(jadwal.selasa)nil
FisikaKeluaran menunjukkan jadwal.senin tidak lagi memiliki nilai, sedangkan kunci lain tetap utuh. Peran ketiga muncul pada fungsi, yaitu fungsi yang berakhir tanpa pernyataan return tidak mengembalikan nilai apa pun, dan nilai yang hilang itu menjadi nil apabila ditempatkan ke dalam variabel.
-- Fungsi tanpa return tidak mengembalikan nilai apa pun
local function catat(pesan)
print(pesan)
end
local balikan = catat("rapat dimulai")
print(balikan)rapat dimulai
nilNilai kebenaran dalam uji kondisi#
Dalam uji kondisi, Lua menganggap hanya nil dan false sebagai nilai palsu (falsy), sedangkan nilai lain semuanya benar. Aturan ini berbeda dari banyak bahasa lain yang menganggap nol atau string kosong sebagai nilai palsu. Akibatnya, 0, string kosong "", dan table kosong tetap lolos pengujian sebagai nilai benar.
Berkas berikut menguji tiga nilai yang berbeda-beda terhadap pernyataan if.
-- Hanya nil dan false yang palsu, sisanya benar dalam uji kondisi
local jumlah = 0
if jumlah then
print("nol dianggap benar")
end
local nama = ""
if nama then
print("string kosong dianggap benar")
end
local catatan = nil
if not catatan then
print("nil dianggap palsu")
endnol dianggap benar
string kosong dianggap benar
nil dianggap palsuAturan ini menjelaskan pola umum pada pustaka Lua, yaitu mengembalikan nil untuk menyatakan ketiadaan hasil. Pencarian yang gagal mengembalikan nil, sehingga hasilnya langsung dapat diuji dengan if hasil then tanpa perbandingan tambahan. Pola yang sama membuat false dan nil dapat ditulis sebagai satu kelas pengujian, namun nilai lain tetap harus diperiksa tipenya apabila pembagiannya diperlukan.
Tipe number: integer dan float#
Sejak Lua 5.4, tipe number terbagi menjadi dua sub-tipe, yaitu integer untuk bilangan bulat 64 bit dan float untuk bilangan pecahan presisi ganda. Keduanya merupakan satu tipe number yang sama, tetapi fungsi math.type() dapat membedakannya dan mengembalikan teks "integer" atau "float". Nilai 3.0 dan 3 bernilai sama menurut perbandingan kesamaan, namun sub-tipenya berbeda.
-- math.type membedakan dua sub-tipe number
print(math.type(1))
print(math.type(1.0))
print(3.0 == 3)integer
float
truePerbedaan sub-tipe memengaruhi hasil aritmetika. Pembagian biasa dengan operator / selalu menghasilkan float, sedangkan pembagian bulat dengan operator // menghasilkan bilangan bulat apabila kedua operannya bulat. Dua operator ini menangani kebutuhan yang berbeda, yaitu perhitungan pecahan dan pembagian yang hasilnya harus berupa bilangan bulat.
-- Pembagian / selalu menghasilkan float, sedangkan // membulatkan ke bawah
print(7 / 2)
print(7 // 2)
print(-7 // 2)3.5
3
-4Keluaran menunjukkan 7 / 2 menghasilkan 3.5, sedangkan 7 // 2 menghasilkan 3 dan -7 // 2 menghasilkan -4. Pembulatan // mengikuti arah bilangan bulat terdekat yang lebih kecil, sehingga hasil untuk -7 turun ke -4 dan bukan naik ke -3. Nilai 3 tanpa bagian desimal pada keluaran menandakan sub-tipe integer, sedangkan 3.5 dan keluaran dengan bagian desimal menandakan float.
Konversi otomatis antartipe#
Lua melakukan coercion, yaitu konversi tipe otomatis pada operasi tertentu. Dalam operasi aritmetika, Lua mencoba mengubah string menjadi number, dan dalam penyambungan string, Lua mengubah number menjadi string. Konversi ini terjadi pada tingkat operasi, bukan pada nilai itu sendiri, sehingga nilai aslinya tidak berubah.
-- Lua mengonversi string dan number secara otomatis pada operasi tertentu
print("10" + 1)
print("3.5" * 2)
print("Nilai: " .. 95)11
7.0
Nilai: 95Keluaran menunjukkan "10" + 1 menghasilkan 11, "3.5" * 2 menghasilkan 7.0, dan penyambungan "Nilai: " .. 95 menghasilkan teks Nilai: 95. Kemudahan ini nyaman, tetapi konversi eksplisit dengan tonumber dan tostring menyatakan maksud dengan lebih jelas serta memisahkan pemeriksaan nilai dari operasinya.
-- Konversi eksplisit menyatakan maksud dengan lebih jelas
print(tonumber("10") + 5)
print(math.type(tonumber("10")))
print(tostring(95) .. " poin")15
integer
95 poinRingkasan#
- Lua memiliki delapan tipe dasar, dan
type()mengembalikan nama tipe sebuah nilai dalam bentukstring. - Pengetikan dinamis menempelkan tipe pada nilai, bukan pada variabel, sehingga satu variabel boleh menampung tipe yang berbeda dari waktu ke waktu.
nilmenandai ketiadaan nilai, menghapus kuncitable, dan menjadi hasil dari fungsi tanpareturn.- Hanya
nildanfalseyang palsu dalam uji kondisi,numberterbagi menjadiintegerdanfloat, dan coercion mengubah tipe secara otomatis pada aritmetika serta penyambungan.
Referensi#
- Referensi Manual Lua 5.4 — Lua.org — Bagian Values and Types mendefinisikan kedelapan tipe dasar, sedangkan bagian Coercions and Conversions mengatur konversi otomatis antara string dan number.
- Programming in Lua — Lua.org — Buku pegangan resmi Lua yang ditulis arsitek utamanya, dengan bab-bab awal memperkenalkan tipe nilai, angka, dan pengetikan dinamis.