Topik ini membahas fungsi Lua secara utuh, mulai dari definisi dan pemanggilan, nilai balik ganda, penanganan argumen berjumlah tidak tetap, kedudukan fungsi sebagai nilai kelas satu, hingga fungsi lokal beserta rekursinya. Setelah menyelesaikannya, fungsi dapat dirancang dengan antarmuka keluaran yang sesuai bagi pemanggilnya.
Definisi dan pemanggilan#
Fungsi didefinisikan dengan kata function, daftar parameter di dalam tanda kurung, badan pernyataan, dan penutup end. Pemanggilan dilakukan dengan menulis nama fungsi diikuti tanda kurung yang memuat argumen, dan tanda kurung itu wajib ada. Definisi diawali local function apabila fungsi hanya digunakan di dalam cakupannya, dan pola ini menjadi pilihan bawaan untuk fungsi pembantu.
-- Definisi dan pemanggilan fungsi dengan tanda kurung
local function sapa(nama)
return "Halo, " .. nama
end
print(sapa("Budi"))Halo, BudiLua mengizinkan satu pengecualian pada aturan tanda kurung. Apabila pemanggilan menyertakan tepat satu argumen berupa string literal atau konstruktor table, tanda kurung boleh digantikan oleh argumennya langsung, sehingga sapa"Budi" setara dengan sapa("Budi") dan total{ pensil = 24 } setara dengan total({ pensil = 24 }).
-- Satu argumen string boleh dipanggil tanpa tanda kurung
local function sapa(nama)
return "Halo, " .. nama
end
print(sapa"Budi")Halo, Budi-- Satu argumen berupa konstruktor table juga boleh tanpa tanda kurung
local function total(item)
local jumlah = 0
for _, harga in pairs(item) do
jumlah = jumlah + harga
end
return jumlah
end
print(total{ pensil = 24, buku = 10 })34Bentuk tanpa tanda kurung ini banyak muncul pada pustaka Lua untuk konfigurasi singkat, tetapi bentuknya kurang lazim bagi pembaca baru.
Nilai balik ganda#
Pernyataan return boleh mengembalikan lebih dari satu nilai sekaligus, dipisahkan tanda koma. Kemampuan ini menghilangkan kebutuhan membungkus beberapa hasil ke dalam table untuk kasus sederhana, misalnya nilai terkecil dan terbesar dari satu deret skor. Pemanggil menampung hasilnya dengan variabel sebanyak nilai baliknya, dan variabel penampung pun dipisahkan tanda koma.
-- Fungsi mengembalikan nilai terkecil dan terbesar sekaligus
local function rentang(daftar)
local terkecil = daftar[1]
local terbesar = daftar[1]
for _, isi in ipairs(daftar) do
if isi < terkecil then
terkecil = isi
end
if isi > terbesar then
terbesar = isi
end
end
return terkecil, terbesar
end
local terkecil, terbesar = rentang({78, 92, 65, 88})
print(terkecil, terbesar)65 92Jumlah nilai balik disesuaikan dengan tempatnya. Penampungan ke beberapa variabel menerima seluruh nilai, penampungan ke satu variabel memangkasnya menjadi satu, dan kekurangan nilai dilengkapi dengan nil.
-- Jumlah nilai balik disesuaikan dengan jumlah variabel penampung
local function duaNilai()
return 10, 20
end
local pertama, kedua = duaNilai()
print(pertama, kedua)
local hanyaSatu = duaNilai()
print(hanyaSatu)10 20
10Aturan penyesuaian yang sama berlaku di dalam daftar ekspresi. Pemanggilan fungsi yang berada di tengah daftar dipangkas menjadi satu nilai, sedangkan pemanggilan pada posisi terakhir menyumbang seluruh nilainya. Penulisan tanda kurung di sekeliling pemanggilan, yaitu (duaNilai()), memaksanya menjadi satu nilai pula.
-- Di tengah daftar ekspresi, nilai balik ganda dipangkas menjadi satu
local function duaNilai()
return 10, 20
end
print(duaNilai(), "tambahan")
print("tambahan", duaNilai())10 tambahan
tambahan 10 20Vararg#
Ekspresi ... yang disebut vararg menampung seluruh argumen tambahan yang diteruskan pemanggil, dengan jumlah yang tidak tetap. Fungsi yang mendeklarasikan ... di akhir daftar parameternya dapat menerima tiga argumen pada satu pemanggilan dan dua argumen pada pemanggilan lain. Vararg diperlakukan sebagai ekspresi multi-nilai, sehingga dapat dibungkus ke dalam table untuk ditelusuri.
-- Vararg menampung sejumlah argumen yang tidak tetap
local function jumlahkan(...)
local total = 0
for _, isi in ipairs({...}) do
total = total + isi
end
return total
end
print(jumlahkan(10, 20, 30))
print(jumlahkan(5, 5))60
10Pustaka dasar menyediakan fungsi select untuk menangani vararg tanpa membungkusnya. Bentuk select("#", ...) mengembalikan jumlah argumen, sedangkan select(n, ...) mengembalikan argumen mulai posisi ke-n hingga akhir.
-- select("#", ...) menghitung jumlah argumen, select(n, ...) mengambil sisanya
local function laporkan(...)
print(select("#", ...))
print(select(2, ...))
end
laporkan("Ali", "Budi", "Citra")3
Budi CitraPasangan table.pack dan table.unpack menyelesaikan kebutuhan sebaliknya. table.pack membungkus argumen menjadi satu table yang menyimpan jumlah aslinya pada kunci n, sedangkan table.unpack menyebar isi table menjadi deretan argumen.
-- table.pack membungkus vararg, sedangkan table.unpack menyebar table menjadi argumen
local kemasan = table.pack("Ali", "Budi", "Citra")
print(kemasan.n)
print(table.unpack(kemasan))3
Ali Budi CitraFungsi sebagai nilai kelas satu#
Fungsi di Lua merupakan nilai kelas satu (first-class value), yaitu nilai yang dapat ditampung dalam variabel, disimpan sebagai elemen table, diteruskan sebagai argumen, dan dikembalikan sebagai nilai balik. Definisi fungsi sesungguhnya berupa penugasan, sehingga local function sapa tidak berbeda prinsip dengan menampung nilai lain ke variabel lokal.
-- Fungsi dapat ditampung dan dipanggil lewat variabel lain
local function kuadrat(x)
return x * x
end
local f = kuadrat
print(f(7))49Kedudukan kelas satu ini membuka pola fungsi yang menerima fungsi lain sebagai argumen. Fungsi anonim (anonymous function) dibuat tanpa nama dan ditulis langsung di tempat argumennya, sehingga perilaku kecil tidak perlu diberi nama formal.
-- Fungsi anonim diteruskan sebagai argumen ke fungsi lain
local function terapkan(daftar, operasi)
local hasil = {}
for i, isi in ipairs(daftar) do
hasil[i] = operasi(isi)
end
return hasil
end
local berlipat = terapkan({2, 4, 6}, function(isi) return isi * 3 end)
print(table.unpack(berlipat))6 12 18Fungsi anonim function(isi) return isi * 3 end digunakan sekali oleh terapkan dan tidak meninggalkan nama baru di cakupan luarnya. Pola ini menjadi dasar banyak pustaka Lua, misalnya table.sort yang menerima fungsi pembanding dari pemanggilnya.
Fungsi lokal dan rekursi#
Bentuk local function menetapkan nama fungsi sebagai variabel lokal, dan nama itu langsung terlihat di dalam badannya sendiri. Ciri ini membuat rekursi sederhana dapat ditulis tanpa persiapan tambahan, sebab pemanggilan dirinya sendiri menemukan nama lokal yang sudah dideklarasikan.
-- local function membuat nama fungsi terlihat di dalam badannya sendiri
local function hitungMundur(n)
if n == 0 then
return
end
print(n)
hitungMundur(n - 1)
end
hitungMundur(3)3
2
1Perilaku itu berbeda dengan penugasan local f = function ... end. Pada bentuk penugasan tersebut, nama f baru berlaku setelah pernyataannya selesai, sehingga badan fungsi tidak melihat nama lokal f dan pemanggilan rekursifnya mencari variabel global dengan nama sama. Kasus serupa menimpa fungsi lokal yang saling memanggil, yaitu ketika satu fungsi memanggil fungsi lokal lain yang belum dideklarasikan.
Solusinya berupa deklarasi maju (forward declaration), yaitu mendeklarasikan nama lokal lebih dahulu, kemudian menugaskan fungsi kepadanya. Dengan nama yang sudah berlaku, badan fungsi dapat memanggil dirinya sendiri maupun fungsi rekannya.
-- Deklarasi maju memungkinkan fungsi lokal memanggil dirinya sendiri
local faktorial
function faktorial(n)
if n <= 1 then
return 1
end
return n * faktorial(n - 1)
end
print(faktorial(5))120Ringkasan#
- Definisi fungsi menggunakan
functiondengan tanda kurung wajib pada pemanggilan, kecuali argumennya tepat satu berupa string literal atau konstruktortable. returndapat mengembalikan beberapa nilai sekaligus, dan jumlahnya disesuaikan dengan posisi pemanggilan, dipangkas menjadi satu apabila berada di tengah daftar ekspresi.- Ekspresi vararg
...menampung argumen berjumlah tidak tetap, ditopangselectserta pasangantable.packdantable.unpack. - Fungsi adalah nilai kelas satu yang dapat ditampung, diteruskan, dan dikembalikan, sedangkan rekursi lokal memerlukan
local functionatau deklarasi maju.
Referensi#
- Referensi Manual Lua 5.4 — Lua.org — Bagian Function Calls dan Function Definitions menetapkan aturan pemanggilan, penyesuaian nilai balik, dan vararg, sedangkan bagian Basic Functions merinci select serta table.pack dan table.unpack.
- Programming in Lua — Lua.org — Bab fungsi membahas definisi, nilai balik ganda, fungsi bersarang, dan rekursi beserta idiom deklarasi majunya.