Networks Business Online Việt Nam & International VH2

Học Lua trong 30 phút – Nomi

Đăng ngày 07 November, 2022 bởi admin

Lua là gì?

Ngôn ngữ lập trình ngữ cảnh bậc cao với những đặc thù : kiểu động, nhẹ, nhanh, đa hình, đa tính năng và mã nguồn mở .

Nhẹ chỗ nào?

  • Lua được viết bằng C với hơn hai chục nghìn dòng code!
  • Trình thông dịch Lua chỉ có kích thước vài trăm KB.
  • Bộ nhớ mà Lua sử dụng khi chạy cũng rất ít.

Nhanh hơn Python không?

  • Bộ xử lý Lua bao gồm trình biên dịch, dịch code thành bytecode và máy ảo để thực thi code đó
  • Kiến trúc máy ảo của Lua từ v5.x trở đi sử dụng mô hình thanh ghi theo kiến trúc x86 (trước đó là sử dụng mô hình ngăn xếp)
  • Tất nhiên là nhanh hơn Python nhiều (có thể nói là nhanh nhất trong các họ ngôn ngữ kịch bản phổ biến). Lua có một phiên bản tên là LuaJIT, thay vì dịch ra bytecode thì nó dịch ra mã máy.

Không so sánh với CPython, PyPy… mà có gán mác JIT vào cũng thua LuaJIT, chấp V8 luôn.

Ngôn ngữ kịch bản luôn gắn liền với từ thông dịch, ở đây Lua cho code vào và chạy luôn.

Bạn đang đọc: Học Lua trong 30 phút – Nomi

Xuất hiện thêm từ biên dịch là do Lua dịch code sang bytecode rước khi cho vào máy ảo.

Đa hình ra sao?

  • Lua hỗ trợ lập trình hàm và cả hướng đối tượng.
  • OOP chủ yếu thông qua prototype, tựa tựa JS vậy.

Làm được gì mà đa tính năng?

  • Lua có thể dùng để viết ứng dụng, game, web (backend) và cả hệ thống.
  • Lua xuất hiện nhiều trong cả lập trình nhúng, đi kèm với các ngôn ngữ nhanh như C/C++, Rust để dễ dàng triển khai, tái sử dụng các API.
  • Có thể tham khảo các project về Lua tại đây, ở đây và cả đây nữa.

Nhúng ở đây không phải là lập trình mạch mà là Lua hỗ trợ CAPI để nhúng vào các ngôn ngữ khác.

Một số game engine hay tools hack game tương hỗ script Lua cũng là một hình thức nhúng .

Cài đặt Lua

Lua không kén thằng C compiler nào cả, tương hỗ trên nhiều kiến trúc khác nhau nữa. Phiên bản release mới nhất là 5.3.5, nhưng không thay đổi nhất và được sử dụng nhiều vẫn là 5.1.5 .

$ curl https://www.lua.org/ftp/lua-5.1.5.tar.gz -o lua.tar.gz
$ tar -xvf lua.tar.gz
$ cd lua-5.1.5
$ make và và make install

Chọn editor

Muốn đa nền tảng thì cứ quất Sublime Text, có một số package hỗ trợ autocomplete và cả just-in-time syntax checker. VS Code cũng ngon (có nhiều extension hỗ trợ Lua và cả debug).

Ngoài ra còn có một IDE được viết hoàn toàn bằng Lua (sử dụng wxWidget UI) vô cùng nhanh và nhẹ, đó là ZeroBrane Studio, nó hỗ trợ chủ yếu là code Lua và các game engine có Lua built-in, có live-coding khá ngon.

Trên Windows, ta hoàn toàn có thể sử dụng Lua Studio, trọn gói setup chỉ bằng giao diện .

Lua có một package manager tên là LuaRocks, tựa tựa như vcpkg, conan… hỗ trợ cài đặt các thư viện ngoài nhanh chóng.

Hello Lua

$ echo print(" Hello, world ! ") > test.lua

Hoặc tạo một file và gõ code sau vào :

print(" Hello, world ! ")

Trên một số ít code editor / IDE chỉ cần nhấn Ctrl + B hoặc chạy lệnh sau :

$ lua ./test.lua

1. Chú pháp và biến

Note: Các hướng dẫn được viết trong code block, bạn có thể copy chúng và chạy. Hãy cẩn thận vì có tiếng Việt, không nên set file test với encoding là UTF8 with BOM.

 
 
Thêm hai cặp ngoặc vuông vào
để comment
trên nhiều dòng.
 

local a
 
 
 

a = 4
 
 
 

A = 4.0
 
 
 

print(a, b)
 
 
 

a = 5 b = 6 
 
 

b = 11; print(b) 
 

local x, y, z = 1, 2, 3, 4
 
 

 
s = ' dấu nháy đơn '
n = " dấu nháy kép cũng được "
u = [[
chuỗi trên 
nhiều dòng bằng 
hai hai cặp ngoặc vuông]]

 
x = ' abc '..' def '
print(x..' 789 ')

p = print    
print = 20   
p(print)     
print = p    

2. Rẻ nhánh và câu điều kiện

b = true  

if b then
    print(' yes ')
else
    print(' no ')
end
 
 

x = 123
if x = = 456 then
    print(' false ')
elseif x ~ = 789 then     
    print(' true ')
else
    print(' otherwise ')
end
 

 
 
 

 
print(false and nil)     
print(0 and nil)         
print(true and nil)      
print(false and 0)       
print(true and false)    
print(1 and 0)           

 
print(1 > 6 and 4 or 3)
 
print(0 and ' true ' or ' false ')
 

3. Vòng lặp

for i = 1, 10 do  
    print(i)
end

for i = 20, 10, -1 do    
    print(i)
end

n = 0
while (n < 5) do
    n = n + 1
end
 

repeat
    n = n + 1
until n > 5
 

4. Hàm

 
function foo()
    print(' Hello World ! ')
end

 
foo()    

 
fib = function(n)
    if n < 2 then
        return 1
    end
    return fib(n - 2) + fib(n - 1)
end

 
function mulret(a, b, c)
    print(a, b, c)
    return 4, 5, 6, 7, 8
end

x, y, z = mulret(5)
 

 
print(x, y, z)   

 
local function g(x) print(x) end
local g; g = function (x) print(x) end
 

g((((((1))))))
g ' qwerty '       
 
 
 

 
function vargs(...)
    print(...)
end

vargs(11, ' a ', 4+5)  

5. Bảng (table)

 
 

t = {key1 = ' value1 ', key2 = false}

 
print(t.key1)    
t.newKey = {}    
t.key2 = nil     

 
u = {[' @ ! # '] = ' qbert ', [{}] = 1729, [6.0 + 0.28] = ' concho '}
 
print(u[6.28])   

a = u[' @ ! # ']     
b = u[{}]        
 
 

 
function h(x) print(x.key1) end 
h {key1 = ' AK-47 '}   

 
v = {' value1 ', ' value2 ', 1.21, ' gigawatts '} 
for i = 1, #v do   
    print(v[i])  
end

local a = {11, 22, 55, 77}
local b = {x = 10, y = 15, pi = 3.14}

 
for i,v in ipairs(a) do
    print(i,v)
end
 
for k,v in pairs(b) do
    print(k,v)
end

6 Metatable, metamethod (prototype)

 
 

f1 = {x = 1, y = 2}
f2 = {x = 5, y = 6}

 
 
 

 
my_meta = {} 
function my_meta.__add(a, b) 
    local ret = {}
    ret.x = a.x + b.y 
    ret.y = a.x - b.y
    return ret
end

 
setmetatable(f1, my_meta)
setmetatable

(

f2, my_meta)
r1 = f1 + f2 r2 = f2 + f1 print(r1.x, r1.y) print(r2.x, r2.y) defaultFavs = {animal = ' dog ', food = ' donuts '} myFavs = {food = ' pizza '} setmetatable(myFavs, {__index = defaultFavs}) eatenBy = myFavs.animal __add(a, b) cho a + b __sub(a, b) cho a - b __mul(a, b) cho a * b __div(a, b) cho a / b __mod(a, b) cho a % b __pow(a, b) cho a ^ b __unm(a) cho -a __concat(a, b) cho a .. b __len(a) cho #a __eq(a, b) cho a = = b __lt(a, b) cho a < b __le(a, b) cho a < = b __index(a, b) cho a.b __newindex(a, b, c) cho a.b = c __call(a, ...) cho a(...)

7 Lớp và kế thừa

 
 
 

Dog = {}                                 
function Dog:new()                       
    newObj = {sound = ' woof '}            
    self.__index = self                  
    return setmetatable(newObj, self)    
end

function Dog:makeSound()                 
    print(' I say ' .. self.sound)
end

mrDog = Dog:new()                        
mrDog:makeSound()  

 

 
 
 
 
 

 

 
 
 
 
 

 

 
 

 
 

 
 
 

LoudDog = Dog:new()                      

function LoudDog:makeSound()
    s = self.sound .. ' '                
    print(s .. s)
end

seymour = LoudDog:new()                  
seymour:makeSound()  

 

 

 
 
 
 
 
 
 
 

 
 

 

function LoudDog:new()
    newObj = {}  
    self.__index = self
    return setmetatable(newObj, self)
end

8. Tạo module

Module giống như một thư viện riêng, và người dùng hoàn toàn có thể sử dụng nó trải qua :

local mod = require(' module_name ')

Có 2 loại module gồm có :

  • Lua module: viết bằng Lua, được xem như một hàm.
  • C module: thường được viết bằng C hoặc bất kỳ ngôn ngữ nào, được biên dịch dưới dạng thư viện liên kết động.

Đầu tiên, tạo một file mới làm module :

 
 
local M = {}

Thêm mộ số giá trị vào table M:

local M = {}

M.a = 1
M.b = true
M.c = ' Hello '

M.foo = function(self)
    print(self.c)
end

Và trả về M ngay cuối file:

    print(self.c)
end

return M

Tiếp tục tạo một file mới để chạy code :

local mod = require(' module ')
 
 
 
 

print(mod.a)     
print(mod.b)     
mod:foo()        

Nên nhớ, biến local trong main.lua sẽ không dùng được trong module.lua.
Nếu quy về hàm hoặc sử dụng cho cùng một file thì sẽ như này:

local function module()
    local M = {}
     
    return M
end

mod = module()

Ngoài ra hoàn toàn có thể chạy file Lua khác ngay trong chương trình .

dofile(' abc.lua ')
 
 
 

local f = loadfile(' abc.lua ')  
 

Các module chuẩn

Lua cung cấp một số module chuẩn dành cho các nhu cầu cơ bản, tất nhiên là không cần dùng require đâu, trừ khi biến của thư viện được bạn gán cho một giá trị nào đó.

io.write(" Hello \ n ")  
os.exit()           

9. Lập trình coroutines

Một coroutine mang nghĩa một luồng ( thread ), lập trình coroutines cũng mang nghĩa lập trình đồng thời ( concurrency, nhưng chỉ là nghĩa bóng ). Khác nhau ở đây là nghĩa đen, là sự hợp tác ( chứ không phải đồng thời ) giữa những coroutine, và một lúc chỉ chạy được một coroutine, chúng hoàn toàn có thể được nhu yếu dừng để coroutine khác chạy xen vào .

concurrency @ là điểm mở mànmain  +----+-+--------------- >
           | |
thread     @----------------- >
           |
thread     @----------------- >
coroutines o là điểm dừngmain  +----+     +--+
           |     |  |
coroutine  o  @--o  +  @----- >
           |  |     |  |
coroutine  @--o     @--o

Coroutines chỉ khác đơn luồng ở chỗ là hoàn toàn có thể dừng hàm ở bất kể đâu để xen hàm khác tại vị trí đó .

Mấy con cẩu cute :v

Cho dễ hiểu hơn, hãy xem ảnh trên (biễu diễn cho concurrency). Khi gọi thì cả ba con cún đều xuất hiện cùng lúc, nhưng bạn chỉ có thể nựng một con một lúc. Khi đơn luồng, bạn sẽ nựng mỗi con một lúc, hết con này mới đến con khác. Còn coroutines thì nếu trong lúc nựng con này mà chán, bạn có thể sang nựng con khác, chán nữa thì quay lại con này cho đến khi xong.

Tạo một coroutine đơn thuần như sau :

co = coroutine.create(function ()
    print(" hi ")
end)

print(co)
  • In ra thread: 0x64...., địa chỉ của coroutine.

Một coroutine sẽ có 3 trạng thái: suspended, runningdead.

print(co)
print(coroutine.status(co))
  • In ra suspended, nó đang ở trạng thái dừng vì chưa chạm gì vào.

Chạy và check trạng thái sau cuối :

print(coroutine.status(co))
coroutine.resume(co)
print(coroutine.status(co))
  • In ra dead, và tất nhiên sẽ không thễ resume được nữa.

Để dừng một coroutine đang chạy, ta có hàm coroutine.yield:

co = coroutine.create(function ()
    for i=1,10 do
        print(" co ", i)
        coroutine.yield()
    end
end)

Test thử :

end)

coroutine.resume(co)         
print(coroutine.status(co))  
coroutine.resume(co)         
coroutine.resume(co)        
  • Nếu quá 10 lần resume thì nó dead.

Truyền tham số vào hàm trong coroutine :

co = coroutine.create(function(a,b,c)
    print(" co ", a, b, c)
end)

coroutine.resume(co, 1, 2, 3)   

Tính hợp tác

Ta có 2 coroutine sau :

co1 = coroutine.create(function()
    for i=1,3 do print(" co1_ "..i) end
end)

co2 = coroutine.create(function()
    for i=1,3 do print(" co2_ "..i) end
end)

Chạy thử :

end)

coroutine.resume(co1)
coroutine.resume(co2)

Ta sẽ thấy, nó chạy xong co1 rồi mới đến co2:

co1_1
co1_2
co1_3
co2_1
...

Tiếp tục thêm yield vào, co1 dừng co2 và ngược lại:

co1 = coroutine.create(function()
    for i=1,3 do print(" co1_ "..i) coroutine.yield(co2) end
end)
co2 = coroutine.create(function()
    for i=1,3 do print(" co2_ "..i) coroutine.yield(co1) end
end)

Sửa luôn chỗ test :

end)

for i=1,3 do
    coroutine.resume(co1)
    coroutine.resume(co2)
end

Và đây là kết quả, hai coroutine chạy xen nhau theo thứ tự.

co1_1
co2_1
co1_2
co2_2
...

Đến đây là kết thúc rồi, có thể là hơn 30 phải không?

Lua rất dễ và mê hoặc, xứng danh là ngôn từ cho người mới mở màn .

Khoảng 10 năm trước thì Lua mở màn nổi lên trong mảng lập trình game, đến nay nó vẫn đứng top !

Source: https://vh2.com.vn
Category : Tin Học