Variabel lokal di Mojo wajib dideklarasikan dengan kata kunci var, dan aturan tipe yang menyertainya lebih tegas daripada Python. Topik ini membahas bentuk deklarasi beserta anotasi tipenya, tipe dasar Int, Float64, Bool, dan String, inferensi tipe, deklarasi tertunda, serta konversi antar tipe yang dinyatakan secara eksplisit. Tiga penulisan yang ditolak compiler juga diperagakan lengkap dengan pesan error aslinya, sehingga setiap larangan dapat dipahami bersama alasan teknisnya. Setelah topik ini, deklarasi variabel yang sah pada Mojo 1.2.0 dapat ditulis dengan benar dan pesan error pengetikan dapat dibaca dengan tepat.
Deklarasi variabel dengan var#
Deklarasi variabel lokal dimulai dengan kata kunci var, diikuti nama variabel dan nilai awalnya. Anotasi tipe berupa : Tipe ditulis setelah nama apabila tipe ingin ditegaskan, sedangkan tanpa anotasi, tipe variabel ditentukan compiler dari nilai awalnya melalui inferensi tipe (type inference), yaitu penyimpulan tipe secara otomatis pada saat kompilasi. Pola ini berbeda dari Python yang mendeklarasikan nama baru pada penugasan pertama tanpa kata kunci, sehingga kebiasaan tersebut perlu disesuaikan saat menulis Mojo.
Berkas deklarasi.mojo menunjukkan kedua bentuk deklarasi pada empat variabel bertipe berbeda. Variabel umur ditulis tanpa anotasi sehingga bertipe Int dari literal 17, sedangkan suhu, aktif, dan nama dianotasi dengan Float64, Bool, dan String. Pemanggilan print dengan beberapa argumen mencetak seluruh nilai dalam satu baris yang dipisahkan spasi.
def main():
var umur = 17
var suhu: Float64 = 30.5
var aktif: Bool = True
var nama: String = "Citra"
print(umur, suhu, aktif, nama)# deklarasi variabel dengan dan tanpa anotasi tipe
mojo run deklarasi.mojo17 30.5 True CitraKeluaran menampilkan keempat nilai berurutan dalam satu baris. Tipe pada anotasi wajib cocok dengan nilai yang diberikan, dan penugasan nilai bertipe lain ke nama yang sama tidak diperbolehkan tanpa konversi eksplisit. Aturan ini memastikan tipe setiap nama diketahui pada saat kompilasi, sehingga ketidakcocokan tipe terdeteksi sebelum program dijalankan.
Tipe dasar dan operasi aritmetika#
Empat tipe dasar yang paling sering digunakan adalah Int untuk bilangan bulat, Float64 untuk bilangan pecahan presisi ganda, Bool untuk nilai kebenaran, dan String untuk teks. Aritmetika mengikuti tipe operandnya, sehingga penjumlahan dua nilai bulat menghasilkan nilai bulat, sedangkan operasi yang melibatkan nilai pecahan menghasilkan nilai bertipe Float64. Perbandingan seperti 3 == 3 menghasilkan Bool, dan operator not membalik nilai kebenarannya.
Berkas angka.mojo memperagakan perilaku tersebut dalam satu program. Variabel jumlah dihitung dari dua bilangan bulat, variabel suhu diinferensikan sebagai Float64 lalu dijumlahkan dengan 1.5, variabel campur dihitung dari literal bulat dan literal pecahan, dan variabel sama menyimpan hasil perbandingan.
def main():
var jumlah = 7 + 2
print(jumlah)
var suhu = 30.5
print(suhu + 1.5)
var campur = 7 + 0.5
print(campur)
var sama = 3 == 3
print(sama, not sama)# aritmetika pada tipe Int, Float64, dan Bool
mojo run angka.mojo9
32.0
7.5
True FalseKeluaran 9 dan 32.0 mengikuti tipe operandnya, sedangkan 7.5 menunjukkan bahwa penjumlahan literal bulat dengan literal pecahan menghasilkan nilai pecahan. Literal bilangan bulat diterima compiler pada konteks bertipe pecahan karena nilainya sudah pasti pada saat kompilasi, sehingga konversi manual tidak diperlukan. Baris terakhir mencetak True False, yaitu hasil perbandingan 3 == 3 beserta pembalikannya dengan not, sekaligus menunjukkan bahwa print dapat menerima lebih dari dua argumen.
Inferensi tipe dan deklarasi tertunda#
Variabel boleh dideklarasikan tanpa nilai awal asalkan tipenya dianotasi, lalu diisi pada baris lain, sebuah pola yang disebut deklarasi tertunda. Compiler melacak status inisialisasi setiap variabel, sehingga pembacaan variabel tertunda sebelum diisi ditolak dengan error use of uninitialized value. Pola ini berguna apabila nilainya baru diketahui di tengah perhitungan, tetapi tipenya harus tetap disepakati sejak awal.
Berkas inferensi.mojo menggunakan kedua pola sekaligus di dalam program yang memanggil fungsi bertipe. Variabel x ditulis tanpa anotasi sehingga bertipe Int dari literal 21, sedangkan variabel sisa dideklarasikan lebih dahulu tanpa nilai lalu diisi 9. Fungsi dua_kali menampilkan signature eksplisit, yaitu menerima argumen Int dan mengembalikan Int.
def dua_kali(n: Int) -> Int:
return n * 2
def main():
var x = 21
print(dua_kali(x))
var sisa: Int
sisa = 9
print(sisa)# inferensi tipe dan pengisian yang tertunda
mojo run inferensi.mojo42
9Keluaran 42 berasal dari pemanggilan dua_kali(x) dan keluaran 9 berasal dari pencetakan sisa. Pembagian kerjanya perlu dipahami, yaitu tipe wajib eksplisit pada signature fungsi, sedangkan di dalam badan fungsi inferensi mengurangi kebutuhan anotasi. Kombinasi ini menjaga kejelasan antarmuka antar fungsi tanpa memberatkan penulisan variabel lokal.
Konversi tipe yang eksplisit#
Konversi antar tipe dinyatakan dengan menyebut tipe tujuan sebagaimana fungsi, misalnya Float64(3) mengubah nilai Int menjadi Float64. Konversi semacam ini wajib ditulis karena compiler menolak konversi implisit antar tipe, sebagaimana diperagakan pada bagian Kesalahan umum. Selain memenuhi syarat compiler, konversi eksplisit menyatakan maksud perhitungan secara terbaca bagi pembaca kode.
Berkas persen.mojo menghitung persentase dari dua nilai Int setelah keduanya dikonversi. Konversi tersebut menentukan kebenaran hasil, karena pembagian dua nilai Int adalah pembagian bulat yang memotong sisa, sehingga 3 / 8 menghasilkan 0 dan bukan 0.375.
def persen(bagian: Int, total: Int) -> Float64:
return Float64(bagian) / Float64(total) * 100.0
def main():
print(persen(3, 8))# konversi eksplisit sebelum pembagian
mojo run persen.mojo37.5Keluaran 37.5 hanya diperoleh karena kedua argumen dikonversi ke Float64 sebelum dibagi. Apabila kedua konversi dihilangkan, pembagian bulat 3 / 8 menghasilkan 0, sehingga hasil akhirnya menjadi 0.0. Contoh ini menunjukkan bahwa konversi eksplisit bukan sekadar syarat penulisan, tetapi juga penentu kebenaran hasil perhitungan.
Kesalahan umum#
Kebiasaan Python menugaskan nama baru tanpa deklarasi, dan pola tersebut ditolak Mojo. Deklarasi yang eksplisit membuat setiap nama memiliki tipe yang pasti sejak barisnya ditulis. Berkas tanpa-var.mojo menugaskan x tanpa var.
def main():
x = 5
print(x)# penugasan tanpa deklarasi var
mojo run tanpa-var.mojo/home/kal/my-project/content/mojo/dua-jenis-fungsi/variabel-dan-tipe/tanpa-var.mojo:2:5: error: implicit declaration of 'x' is not allowed; add 'var' to declare a new name
x = 5
^
var
/home/kal/.pixi/envs/mojo/bin/mojo: error: failed to parse the provided Mojo source modulePesan error menyuruh menambahkan var untuk mendeklarasikan nama baru, dan perbaikannya sesederhana saran tersebut. Kesalahan kedua berupa konversi implisit antar tipe. Berkas konversi-implisit.mojo menugaskan nilai Float64 ke variabel yang dianotasi Int.
def main():
var suhu = 30.5
var bulat: Int = suhu
print(bulat)# penugasan nilai Float64 ke variabel dianotasi Int
mojo run konversi-implisit.mojo/home/kal/my-project/content/mojo/dua-jenis-fungsi/variabel-dan-tipe/konversi-implisit.mojo:3:22: error: cannot implicitly convert 'Float64' value to 'Int'
var bulat: Int = suhu
^~~~
/home/kal/.pixi/envs/mojo/bin/mojo: error: failed to parse the provided Mojo source modulePerbaikannya mengikuti maksud penulisnya, yaitu mengubah anotasi menjadi Float64 apabila nilai pecahan memang diinginkan, atau mengonversi nilai dengan Int(suhu) apabila bagian bulatnya yang dibutuhkan. Kesalahan ketiga berupa variabel global, yaitu variabel yang dideklarasikan di luar fungsi. Berkas global.mojo mendeklarasikan total pada tingkat berkas lalu menambahkannya di dalam main.
var total = 0
def main():
total += 1
print(total)# variabel pada tingkat berkas ditolak compiler
mojo run global.mojo/home/kal/my-project/content/mojo/dua-jenis-fungsi/variabel-dan-tipe/global.mojo:1:1: error: global variables are not supported; move this into a function body or use 'comptime' to declare a constant
var total = 0
^
/home/kal/my-project/content/mojo/dua-jenis-fungsi/variabel-dan-tipe/global.mojo:5:5: error: use of unknown declaration 'total'
total += 1
^~~~~
/home/kal/my-project/content/mojo/dua-jenis-fungsi/variabel-dan-tipe/global.mojo:6:11: error: use of unknown declaration 'total'
print(total)
^~~~~
/home/kal/.pixi/envs/mojo/bin/mojo: error: failed to parse the provided Mojo source moduleCompiler menyebut dua jalan keluar, yaitu memindahkan variabel ke dalam badan fungsi atau menyatakannya sebagai konstanta comptime. Untuk pencacah yang berubah nilainya seperti pada contoh, pilihan yang tepat adalah memindahkannya ke dalam fungsi, sedangkan comptime cocok untuk nilai yang tetap dan sudah diketahui pada saat kompilasi. Dengan aturan ini, seluruh keadaan program berada di dalam fungsi, dan nilai lintas fungsi diteruskan lewat argumen maupun nilai kembalian.
Ringkasan#
- Variabel lokal wajib dideklarasikan dengan
var, dengan anotasi tipe yang opsional, dan tanpa anotasi, tipe variabel disimpulkan compiler dari nilai awalnya. - Aritmetika mengikuti tipe operandnya, termasuk pembagian dua nilai
Intyang merupakan pembagian bulat, sedangkan perbandingan menghasilkanBool. - Variabel boleh dideklarasikan tanpa nilai awal sepanjang tipenya dianotasi, tetapi pembacaan sebelum diisi ditolak dengan error
use of uninitialized value. - Konversi antar tipe ditulis eksplisit melalui tipe tujuan seperti
Float64(3), penugasan tanpavartidak sah, dan variabel global tidak didukung.
Referensi#
- Mojo Manual — Modular — Dokumentasi resmi Mojo 1.2.0 yang menjadi rujukan aturan variabel, tipe, dan comptime.
- Functions — Mojo Manual — Aturan signature fungsi bertipe yang berpasangan dengan deklarasi variabel lokal.