1. Trang chủ
  2. » Công Nghệ Thông Tin

Học lua trong 30 phút

26 59 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Học lua trong 30 phút
Trường học Trường Đại Học Bách Khoa Hà Nội
Chuyên ngành Khoa học Máy Tính
Thể loại Bài viết hướng dẫn
Năm xuất bản 2018
Thành phố Hà Nội
Định dạng
Số trang 26
Dung lượng 135,73 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddvddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddv

Trang 1

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.

Trang 2

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.

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ữ

just-in-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 có thể sử dụng Lua Studio , trọn gói cài đặt 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.

Trang 3

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ố 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.

Hai dấu trừ đánh dấu comment trên một dòng

Khai báo biến a, nếu không gán gì thì nó là nil

nil có thể hiểu là chưa định nghĩa, không mang giá trị nào

a =4

Gán giá trị cho biến

Trang 4

Số trong Lua đều là số thực double,

nhưng biến a vẫn được hiểu là số nguyên

print để in giá trị ra console

Biến b chưa được khai báo sẽ là nil, không lỗi đâu vì nó được hiểu là biến global

Trang 5

Khai báo một chuỗi.

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]]

Nối hai chuỗi bằng hai dấu chấm

x ='abc' 'def'

print(x '789')

p = print Tuy print là một hàm, nhưng cũng là kiểu dữ liệu

print =20 Tất cả các biến đều thay đổi giá trị được

p(print) In ra 20

print = p Trả lại như cũ

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

b =true Kiểu đúng/sai boolean

if b then

print('yes')

Trang 6

còn false và nil đều sai.

Logic or, and

print(falseandnil) > false

print(0andnil) > nil

Trang 7

print(trueandnil) > nil

print(falseand0) > false

print(trueandfalse) > false

Trang 8

foo() In ra Hello World!

Khai báo kiểu lambda

Trang 9

print(x, y, z) Kiểm tra, chỉ in ra 4 5 6.

Thêm local vào trước thì là hàm cục bộ

localfunctiong(x)print(x)end

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

Hai thằng như nhau

g((((((1))))))

g 'qwerty' In ra qwerty

Trường hợp gọi hàm không cần cặp ngoặc tròn khi tham số được cách tên hàm bằng các kí tự cú pháp

Trang 10

như: ngoặc nhọn { (table), dấu nháy " hoặc ' (chuỗi).

Đây là kiểu cấu trúc phức hợp của Lua,

tương tự như array trong PHP hay object trong JS

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

Sử dụng dấu chấm để tham chiếu đến phần tử con

print( key1) In ra value1

t.newKey ={} Thêm newKey, giá trị là một table

t.key2 =nil Xóa key2

Sử dụng giá trị để đánh dấu phần tử con

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

Sử dụng cặp ngoặc [ ] và cho biểu thức vào trong

Trang 11

print(u[6.28]) In ra concho.

a = u['@!#'] a = 'qbert'

b = u[{}] b = nil, không phải 1729 nhé

Vì key này là table rỗng,

cần phải sử dụng hai table giống nhau

Sử dụng table cho tham số của hàm

function h(x)print(x.key1)end

h {key1 ='AK-47'} In ra AK-47

Mảng (list / arrays):

v ={'value1','value2',1.21,'gigawatts'}

for i =1,#v do #v để lấy độ dài, dùng được cho cả chuỗi

print(v[i]) Array trong Lua "start at 1" nhé! =))

Trang 13

r1 = f1 + f2 Gọi add(f1, f2) trong metatable của f1.

r2 = f2 + f1 Tương tự luôn, metatable của f2

print(r1.x, r1.y) > 7 -5

print(r2.x, r2.y) > 7 3

Hiểu đơn giản hơn thì một table bình thường,

chỉ để chứa dữ liệu mà thôi,

metatable thêm vào sẽ là bộ tiền xử lý cho nó

Thêm table vào table thông qua key index

defaultFavs ={animal ='dog', food ='donuts'}

myFavs ={food ='pizza'}

setmetatable(myFavs,{ index = defaultFavs})

eatenBy = myFavs.animal > 'dog'

Giá trị của index, add, được gọi là metamethod

Trang 14

Full list, a là một table với một metamethod.

Trang 15

Dog ={} 1.

function Dog:new() 2

newObj ={sound ='woof'} 3

self. index = self 4

returnsetmetatable(newObj, self) 5

end function Dog:makeSound() 6

print('I say ' self.sound) end mrDog = Dog:new() 7

mrDog:makeSound() > 'I say woof' 8

1 Dog giống như một class, nhưng thực chất là table 2 Hàm tablename:func( ) được hiểu như hàm tablename.func(self, )

dấu hai chấm : thêm self vào

thành tham số thứ nhất

Đọc 7 & 8 bên dưới để hiểu nó thêm như nào

Trang 16

3 newObj sẽ là instance mới cho class Dog.

4 self = class mới tạo ra Thông thường

self = Dog, nhưng phần kế thừa sẽ thay đổi nó

newObj get các hàm từ chính nó nhưng set

metatable của newObj và index của nó

vào chính nó (Dog)

5 Nên nhớ: setmetatable sẽ return tham số đầu

6 Dấu hai chấm : như trong mục 2, nhưng self này

có thể sử dụng cho lớp con kế thừa thông qua Dog.new()

7 Giống như Dog.new(Dog), self = Dog trong new(). 8 Giống như mrDog.makeSound(mrDog); self = mrDog

- Ví dụ kế thừa

-LoudDog = Dog:new() 1

function LoudDog:makeSound()

Trang 17

s = self.sound ' ' 2.

print(s s)

end

seymour = LoudDog:new() 3

seymour:makeSound() > 'woof woof' 4

1 LoudDog lấy method & property từ Dog

2 Bản thân nó có key 'sound' từ hàm new()

3 Giống như LoudDog.new(LoudDog),

và được chuyển thành Dog.new(LoudDog),

LoudDog không có key 'new', nhưng nó có

index = Dog trong metatable của nó (LoudDog)

Kết quả: metatable của seymour là LoudDog, và

LoudDog. index = LoudDog Nên seymour.key sẽ

= seymour.key, LoudDog.key, Dog.key, bất kỳ

table nào cũng là cái đầu tiên với key nhận được

4 Key 'makeSound' có sẵn trong LoudDog, seymour kế thừa, nó giống như LoudDog.makeSound(seymour)

Trang 18

Nếu cần tạo thêm class con mới, cấu trúc sẽ như sau:

function LoudDog:new()

newObj ={} tạo newObj

self. index = self

returnsetmetatable(newObj, self)

end

8 Tạo module

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

local mod =require('module_name')

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

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:

Khởi tạo table M

Đây là biến cục bộ, chỉ sử dụng được trong file này

Trang 19

M.foo =function(self)

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

local mod =require('module')

Load module ở trên, lưu ý tên file

Nếu file module.lua nằm trong thư mục con thì

require('folder.module')

có thể thay '.' thành '/' hoặc '\\'

print(mod.a) > 1

print(mod.b) > true

mod:foo() > 'Hello'

Hoặc mod.foo(mod)

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:

localfunctionmodule()

Trang 20

tất nhiên là không lưu các biến từ file đó,

không giống như require đâu

local f =loadfile('abc.lua')

loadfile sẽ load một file nhưng không chạy ngay mà lưu vào hàm

Trang 21

os.exit() Thoát nhanh.

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 các coroutine, và một lúc chỉ chạy được một coroutine, chúng có thể được yêu cầu dừng để coroutine khác chạy xen vào.

concurrency @ là điểm bắt đầu

coroutine @ o @ o

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

Trang 22

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 giả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, running và dead.

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 cuối cùng:

Trang 23

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()

 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)

Trang 24

coroutine.resume(co,1,2,3) > In ra co 1 2 3

Tính hợp tác

Ta có 2 coroutine sau:

co1 = coroutine.create(function()

for i=1,3doprint("co1_" i)end

end)

co2 = coroutine.create(function()

for i=1,3doprint("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:

Trang 25

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,3doprint("co1_" i) coroutine.yield(co2)end

end)

co2 = coroutine.create(function()

for i=1,3doprint("co2_" i) coroutine.yield(co1)end

end)

Sửa luôn chỗ test:

end)

for i=1,3do

coroutine.resume(co1)

coroutine.resume(co2)

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

Lua rất dễ và thú vị, xứng đáng là ngôn ngữ cho người mới bắt đầu.

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

Ngày đăng: 22/08/2023, 21:44

TỪ KHÓA LIÊN QUAN

w