cv.cm

Pemrograman · Bahasa pemrograman

Tutorial Lua untuk pemula

7 menit baca

Jawaban singkat

Lua adalah bahasa scripting ringan yang bisa disematkan (embeddable) dan dipakai di game, Roblox (lewat dialeknya, Luau), Neovim, Redis, dan perangkat embedded. Sintaksnya kecil dan hanya punya satu struktur data, yaitu tabel, yang berfungsi sebagai array, dictionary, dan objek. Halaman ini membahas cara memasang Lua, variabel dan tipe data, alur kontrol, fungsi, tabel, metatable, penanganan error dengan pcall, dan satu contoh program lengkap.

Apa itu Lua dan untuk apa dipakai

Lua adalah bahasa scripting kecil, cepat, dan bertipe dinamis yang dibuat pada 1993 di PUC-Rio, sebuah universitas di Brasil. Seluruh interpreter-nya berupa library ringkas yang ditulis dalam C, sehingga mudah disematkan ke dalam program yang lebih besar. Lua hanya punya satu struktur data, yaitu tabel, dan sangat sedikit konsep, jadi cepat dipelajari.

Lua paling sering dipakai sebagai bahasa scripting tersemat: game engine dan game (Roblox memakai dialek Lua bernama Luau; LÖVE dan Defold memakai Lua), editor Neovim, database Redis, perangkat jaringan seperti Nginx dengan OpenResty, dan banyak perangkat embedded. LuaJIT adalah compiler just-in-time populer untuk kode Lua 5.1.

Memasang Lua dan menjalankan Hello, world

Pasang Lua lewat package manager Anda (misalnya brew install lua atau apt install lua5.4) atau build dari source di lua.org. Jalankan lua saja untuk membuka prompt interaktif.

-- hello.lua
print("Hello, world!")
lua hello.lua
# Hello, world!

Komentar diawali dengan --. Komentar blok ditulis --[[ ... ]]. Statement tidak memerlukan titik koma.

Variabel dan tipe dasar

Variabel bersifat global secara default. Selalu deklarasikan dengan local kecuali Anda memang menginginkan variabel global. Lua punya delapan tipe dasar; yang dipakai sehari-hari ada di bawah ini.

local name = "Lua"
local year = 1993              -- integer
local pi = 3.14159             -- float
local ok = true
local nothing = nil

print(type(name), type(year), type(nothing))  -- string  number  nil
print(math.type(year), math.type(pi))         -- integer  float
print(name .. " " .. year)                    -- Lua 1993 (.. joins strings)
print(#name)                                  -- 3 (length)
print(7 / 2, 7 // 2, 7 % 2, 2 ^ 10)           -- 3.5  3  1  1024.0
print(string.format("%.2f", pi))              -- 3.14
print(tonumber("42") + 1, tostring(10))       -- 43  10
TipeContohCatatan
nilniltidak adanya nilai; variabel yang belum diisi bernilai nil
booleantrue, falsehanya false dan nil yang dianggap falsy; 0 dan "" dianggap truthy
number42, 3.14subtipe integer dan float sejak Lua 5.3
string"hi", 'hi', [[long]]string byte yang tidak dapat diubah (immutable)
table{1, 2, x = 3}satu-satunya struktur data
functionfunction() endnilai kelas satu (first-class)

Operator tidak sama dengan adalah ~=, bukan !=. Operator logika berupa kata and, or, dan not.

Alur kontrol

Blok diakhiri dengan kata kunci end. Lua punya if/elseif/else, while, repeat ... until, for numerik, dan for generik yang bekerja dengan iterator.

local score = 72
if score >= 90 then
  print("A")
elseif score >= 70 then
  print("B")                   -- B
else
  print("C")
end

for i = 1, 3 do                -- 1 to 3, inclusive
  io.write(i, " ")             -- 1 2 3
end
print()

for i = 10, 1, -4 do io.write(i, " ") end   -- 10 6 2
print()

local n = 3
while n > 0 do n = n - 1 end

repeat
  n = n + 1
until n >= 2
print(n)                       -- 2

Tidak ada statement continue; gunakan goto continue dengan label ::continue::, atau susun ulang perulangan dengan if.

Fungsi

Fungsi adalah nilai. Fungsi dapat menerima jumlah argumen yang bervariasi dengan ... dan mengembalikan beberapa nilai sekaligus. Closure menangkap variabel lokal dari scope di sekitarnya.

local function add(a, b)
  return a + b
end

local function minmax(t)
  local lo, hi = math.huge, -math.huge
  for _, v in ipairs(t) do
    lo, hi = math.min(lo, v), math.max(hi, v)
  end
  return lo, hi                -- two return values
end

local function counter()
  local count = 0
  return function()            -- a closure
    count = count + 1
    return count
  end
end

print(add(2, 3))               -- 5
local lo, hi = minmax({4, 9, 1})
print(lo, hi)                  -- 1  9
local next_id = counter()
print(next_id(), next_id())    -- 1  2
local function sum(...)
  local total = 0
  for _, v in ipairs({...}) do total = total + v end
  return total
end
print(sum(1, 2, 3))            -- 6

Tabel: array, dictionary, dan objek

Tabel adalah associative array yang dapat diindeks dengan nilai apa pun kecuali nil. Struktur yang sama berfungsi sebagai array, dictionary, set, modul, atau objek. Menurut konvensi, array dimulai dari indeks 1.

local fruits = {"apple", "banana"}
table.insert(fruits, "cherry")
print(#fruits, fruits[1])            -- 3  apple

for i, f in ipairs(fruits) do        -- array part, in order
  print(i, f)
end

local ages = {ann = 31, bo = 25}
ages["cy"] = 40
ages.bo = nil                        -- remove a key
for k, v in pairs(ages) do           -- all keys, order not defined
  print(k, v)
end

table.sort(fruits, function(a, b) return a > b end)
print(table.concat(fruits, ", "))    -- cherry, banana, apple

Metatable dan Lua berorientasi objek

Metatable adalah fitur khas Lua. Metatable yang dipasang pada sebuah tabel mengubah perilakunya: __index menyediakan key yang tidak ada (dipakai untuk pewarisan), dan field seperti __add, __eq, dan __tostring melakukan overload operator. Sintaks titik dua obj:method() meneruskan objek sebagai parameter pertama tersembunyi self.

local Vector = {}
Vector.__index = Vector

function Vector.new(x, y)
  return setmetatable({x = x, y = y}, Vector)
end

function Vector:length()
  return math.sqrt(self.x ^ 2 + self.y ^ 2)
end

Vector.__add = function(a, b) return Vector.new(a.x + b.x, a.y + b.y) end
Vector.__tostring = function(v) return "(" .. v.x .. ", " .. v.y .. ")" end

local v = Vector.new(3, 4) + Vector.new(0, 0)
print(tostring(v))       -- (3, 4)
print(v:length())        -- 5.0

Lua juga punya coroutine (coroutine.create, coroutine.resume, coroutine.yield) yang memungkinkan sebuah fungsi berhenti sejenak dan dilanjutkan nanti. Script game sering memakainya untuk perilaku bertahap yang berlangsung selama beberapa frame.

Penanganan error

Munculkan error dengan error(message). Tangkap dengan pcall (protected call), yang mengembalikan false beserta errornya alih-alih menghentikan program. Banyak fungsi library mengembalikan nil dan pesan error alih-alih memunculkan error, seperti io.open.

local function divide(a, b)
  if b == 0 then
    error("division by zero")
  end
  return a / b
end

local ok, result = pcall(divide, 10, 2)
print(ok, result)                  -- true  5.0

ok, result = pcall(divide, 1, 0)
print(ok, result)                  -- false  script.lua:3: division by zero

local f, err = io.open("missing.txt", "r")
if not f then print("open failed: " .. err) end

Nama file dan nomor baris pada pesan error bergantung pada tempat kode dijalankan. assert(value, message) memunculkan error ketika value adalah false atau nil, dan merupakan cara singkat untuk memeriksa hasil.

Program lengkap kecil: penghitung kata

Program ini menghitung kata dalam sebuah teks dengan pattern match, mengurutkannya berdasarkan frekuensi, dan mencetak tiga teratas. Program ini memakai string pattern, tabel, pengurutan dengan comparator kustom, dan pemformatan string.

local text = [[
The cat and the dog. The dog sat,
and the cat ran.
]]

local counts = {}
for word in text:lower():gmatch("%a+") do
  counts[word] = (counts[word] or 0) + 1
end

local list = {}
for word, n in pairs(counts) do
  list[#list + 1] = {word = word, n = n}
end
table.sort(list, function(a, b)
  if a.n ~= b.n then return a.n > b.n end
  return a.word < b.word
end)

for i = 1, 3 do
  print(string.format("%-4s %d", list[i].word, list[i].n))
end
-- the  4
-- and  2
-- cat  2

Langkah selanjutnya

  • Lua Reference Manual di lua.org, singkat dan lengkap.
  • Programming in Lua oleh Roberto Ierusalimschy, salah satu pembuat Lua; edisi pertamanya tersedia gratis secara online.
  • Dokumentasi lingkungan host Anda, seperti panduan Lua untuk Neovim, LÖVE, atau dokumentasi Luau milik Roblox.
  • LuaRocks, package manager untuk modul Lua.

FAQ

Mengapa array Lua dimulai dari 1?

Perancang Lua memilih pengindeksan berbasis 1 agar sesuai dengan konvensi matematika dan kebiasaan non-programmer. Fungsi library standar seperti ipairs, #, dan table.insert semuanya mengasumsikan sequence dimulai dari 1.

Apakah Lua lebih cepat daripada Python?

Interpreter Lua standar berukuran kecil dan umumnya cepat untuk bahasa dinamis, sedangkan LuaJIT jauh lebih cepat untuk banyak beban kerja. Kecepatan sebenarnya bergantung pada tugasnya, jadi ukurlah kasus Anda sendiri.

Apa perbedaan pairs dan ipairs?

ipairs menelusuri bagian array secara berurutan dari indeks 1 sampai nil pertama. pairs mengunjungi setiap key dalam tabel dengan urutan yang tidak ditentukan.

Apa itu Luau?

Luau adalah bahasa turunan Lua 5.1 yang dikembangkan oleh Roblox. Luau menambahkan gradual typing dan peningkatan performa, dan dipakai untuk game Roblox.

Apakah Lua cocok untuk pemula?

Ya. Sintaksnya kecil dan konsisten dengan sedikit konsep, itulah sebabnya Lua populer untuk modding game dan pengajaran. Standard library-nya minimal, jadi untuk fitur lain Anda mengandalkan program host atau modul.

Semua tutorial pemrograman