Lua - Hướng dẫn nhanh
Lua là một ngôn ngữ lập trình nhẹ, có thể mở rộng được viết bằng C. Nó bắt đầu như một dự án nội bộ vào năm 1993 bởi Roberto Ierusalimschy, Luiz Henrique de Figueosystemo và Waldemar Celes.
Nó được thiết kế ngay từ đầu để trở thành một phần mềm có thể được tích hợp với mã viết bằng C và các ngôn ngữ thông thường khác. Sự tích hợp này mang lại nhiều lợi ích. Nó không cố gắng làm những gì C đã có thể làm mà nhằm đưa ra những gì C không giỏi: khoảng cách tốt với phần cứng, cấu trúc động, không dư thừa, dễ kiểm tra và gỡ lỗi. Đối với điều này, Lua có một môi trường an toàn, quản lý bộ nhớ tự động và các phương tiện tốt để xử lý các chuỗi và các loại dữ liệu khác với kích thước động.
Đặc trưng
Lua cung cấp một tập hợp các tính năng độc đáo giúp nó khác biệt với các ngôn ngữ khác. Chúng bao gồm -
- Extensible
- Simple
- Efficient
- Portable
- Miễn phí và mở
Mã mẫu
print("Hello World!")
Lua được thực hiện như thế nào?
Lua bao gồm hai phần - phần thông dịch Lua và hệ thống phần mềm hoạt động. Hệ thống phần mềm hoạt động là một ứng dụng máy tính thực tế có thể thông dịch các chương trình được viết bằng ngôn ngữ lập trình Lua. Trình thông dịch Lua được viết bằng ANSI C, do đó nó có tính di động cao và có thể chạy trên nhiều thiết bị từ các máy chủ mạng cao cấp đến các thiết bị nhỏ.
Cả ngôn ngữ của Lua và thông dịch viên của nó đều thuần thục, nhỏ và nhanh. Nó đã phát triển từ các ngôn ngữ lập trình khác và các tiêu chuẩn phần mềm hàng đầu. Kích thước nhỏ giúp nó có thể chạy trên các thiết bị nhỏ với bộ nhớ thấp.
Học Lua
Điểm quan trọng nhất khi học Lua là tập trung vào các khái niệm mà không bị lạc vào các chi tiết kỹ thuật của nó.
Mục đích của việc học một ngôn ngữ lập trình là trở thành một lập trình viên giỏi hơn; nghĩa là, để trở nên hiệu quả hơn trong việc thiết kế và triển khai các hệ thống mới cũng như duy trì các hệ thống cũ.
Một số công dụng của Lua
Lập trình trò chơi
Viết kịch bản trong các ứng dụng độc lập
Viết kịch bản trong Web
Các tiện ích mở rộng và tiện ích bổ sung cho cơ sở dữ liệu như MySQL Proxy và MySQL WorkBench
Hệ thống an ninh như Hệ thống phát hiện xâm nhập.
Thiết lập môi trường cục bộ
Nếu bạn vẫn sẵn sàng thiết lập môi trường của mình cho ngôn ngữ lập trình Lua, bạn cần có các phần mềm sau trên máy tính của mình - (a) Trình soạn thảo văn bản, (b) Trình thông dịch Lua và (c) Trình biên dịch Lua.
Trình soạn thảo văn bản
Bạn cần một trình soạn thảo văn bản để nhập chương trình của mình. Ví dụ về một số trình chỉnh sửa bao gồm Windows Notepad, lệnh Chỉnh sửa hệ điều hành, Tóm tắt, Epsilon, EMACS và vim hoặc vi.
Tên và phiên bản của trình soạn thảo văn bản có thể khác nhau trên các hệ điều hành khác nhau. Ví dụ: Notepad sẽ được sử dụng trên Windows và vim hoặc vi có thể được sử dụng trên Windows cũng như Linux hoặc UNIX.
Các tệp bạn tạo bằng trình chỉnh sửa của mình được gọi là tệp nguồn và các tệp này chứa mã nguồn chương trình. Các tệp nguồn cho các chương trình Lua thường được đặt tên với phần mở rộng".lua".
Thông dịch viên Lua
Nó chỉ là một chương trình nhỏ cho phép bạn gõ lệnh Lua và thực thi chúng ngay lập tức. Nó dừng việc thực thi tệp Lua trong trường hợp nó gặp lỗi không giống như trình biên dịch thực thi đầy đủ.
Trình biên dịch Lua
Khi chúng tôi mở rộng Lua sang các ngôn ngữ / ứng dụng khác, chúng tôi cần Bộ phát triển phần mềm với trình biên dịch tương thích với Giao diện chương trình ứng dụng Lua.
Cài đặt trên Windows
Có một IDE riêng biệt có tên "SciTE" được phát triển cho môi trường windows, có thể tải xuống từ https://code.google.com/p/luaforwindows/ phần tải xuống.
Chạy tệp thực thi đã tải xuống để cài đặt Lua IDE.
Vì đó là một IDE, bạn có thể vừa tạo và xây dựng mã Lua bằng cách sử dụng cùng một mã.
Trong trường hợp bạn muốn cài đặt Lua ở chế độ dòng lệnh, bạn cần cài đặt MinGW hoặc Cygwin, sau đó biên dịch và cài đặt Lua trong windows.
Cài đặt trên Linux
Để tải xuống và xây dựng Lua, hãy sử dụng lệnh sau:
$ wget http://www.lua.org/ftp/lua-5.2.3.tar.gz $ tar zxf lua-5.2.3.tar.gz
$ cd lua-5.2.3 $ make linux test
Để cài đặt trên các nền tảng khác như aix, ansi, bsd, linux chung, mingw, posix, solaris bằng cách thay thế Linux bằng tạo Linux, hãy thử nghiệm với tên nền tảng tương ứng.
Chúng tôi có một helloWorld.lua, trong Lua như sau:
print("Hello World!")
Bây giờ, chúng ta có thể xây dựng và chạy tệp Lua nói helloWorld.lua, bằng cách chuyển sang thư mục chứa tệp bằng cd, sau đó sử dụng lệnh sau:
$ lua helloWorld
Chúng ta có thể xem kết quả sau.
Hello World!
Cài đặt trên Mac OS X
Để xây dựng / kiểm tra Lua trong Mac OS X, hãy sử dụng lệnh sau:
$ curl -R -O http://www.lua.org/ftp/lua-5.2.3.tar.gz
$ tar zxf lua-5.2.3.tar.gz $ cd lua-5.2.3
$ make macosx test
Trong một số trường hợp nhất định, bạn có thể chưa cài đặt công cụ Xcode và dòng lệnh. Trong những trường hợp như vậy, bạn sẽ không thể sử dụng lệnh make. Cài đặt Xcode từ cửa hàng ứng dụng mac. Sau đó đi tới Tùy chọn của Xcode, rồi chuyển sang Tải xuống và cài đặt thành phần có tên "Công cụ dòng lệnh". Khi quá trình hoàn tất, lệnh make sẽ có sẵn cho bạn.
Bạn không bắt buộc phải thực hiện câu lệnh "thực hiện kiểm tra macosx". Ngay cả khi không thực hiện lệnh này, bạn vẫn có thể sử dụng Lua trong Mac OS X.
Chúng tôi có một helloWorld.lua, trong Lua, như sau:
print("Hello World!")
Bây giờ, chúng ta có thể xây dựng và chạy tệp Lua say helloWorld.lua bằng cách chuyển sang thư mục chứa tệp bằng cd và sau đó sử dụng lệnh sau:
$ lua helloWorld
Chúng ta có thể thấy kết quả sau:
Hello World!
Lua IDE
Như đã đề cập trước đó, đối với Windows SciTE, Lua IDE là IDE mặc định được cung cấp bởi nhóm tạo Lua. IDE thay thế có sẵn là từ ZeroBrane Studio, có sẵn trên nhiều nền tảng như Windows, Mac và Linux.
Ngoài ra còn có các plugin cho eclipse cho phép phát triển Lua. Sử dụng IDE giúp phát triển dễ dàng hơn với các tính năng như hoàn thành mã và rất được khuyến khích. IDE cũng cung cấp lập trình chế độ tương tác tương tự như phiên bản dòng lệnh của Lua.
Hãy để chúng tôi bắt đầu tạo chương trình Lua đầu tiên của chúng tôi!
Chương trình Lua đầu tiên
Lập trình chế độ tương tác
Lua cung cấp một chế độ gọi là chế độ tương tác. Trong chế độ này, bạn có thể gõ lần lượt các hướng dẫn và nhận được kết quả tức thì. Điều này có thể được gọi trong shell bằng cách sử dụng lua -i hoặc chỉ lệnh lua. Sau khi nhập xong, nhấn Enter và chế độ tương tác sẽ được khởi động như hình dưới đây.
$ lua -i $ Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
quit to end; cd, dir and edit also available
Bạn có thể in thứ gì đó bằng cách sử dụng câu lệnh sau:
print("test")
Khi bạn nhấn enter, bạn sẽ nhận được kết quả sau:
test
Lập trình chế độ mặc định
Việc gọi trình thông dịch với tham số tên tệp Lua bắt đầu thực thi tệp và tiếp tục cho đến khi tập lệnh kết thúc. Khi tập lệnh kết thúc, trình thông dịch không còn hoạt động.
Hãy để chúng tôi viết một chương trình Lua đơn giản. Tất cả các tệp Lua sẽ có phần mở rộng .lua. Vì vậy, hãy đặt mã nguồn sau vào tệp test.lua.
print("test")
Giả sử, môi trường lua được thiết lập chính xác, hãy chạy chương trình bằng đoạn mã sau:
$ lua test.lua
Chúng ta sẽ nhận được kết quả sau:
test
Hãy thử một cách khác để thực thi một chương trình Lua. Dưới đây là tệp test.lua đã sửa đổi -
#!/usr/local/bin/lua
print("test")
Ở đây, chúng tôi đã giả định rằng bạn có sẵn trình thông dịch Lua trong thư mục / usr / local / bin của bạn. Dòng đầu tiên bị trình thông dịch bỏ qua, nếu nó bắt đầu bằng dấu #. Bây giờ, hãy thử chạy chương trình này như sau:
$ chmod a+rx test.lua
$./test.lua
Chúng ta sẽ nhận được kết quả sau.
test
Bây giờ chúng ta hãy xem cấu trúc cơ bản của chương trình Lua, để bạn có thể dễ dàng hiểu được các khối xây dựng cơ bản của ngôn ngữ lập trình Lua.
Token trong Lua
Một chương trình Lua bao gồm các mã thông báo khác nhau và mã thông báo là một từ khóa, một định danh, một hằng số, một chuỗi ký tự hoặc một ký hiệu. Ví dụ: câu lệnh Lua sau đây bao gồm ba mã thông báo:
io.write("Hello world, from ",_VERSION,"!\n")
Các mã thông báo riêng lẻ là -
io.write
(
"Hello world, from ",_VERSION,"!\n"
)
Bình luận
Nhận xét giống như văn bản trợ giúp trong chương trình Lua của bạn và chúng bị thông dịch viên bỏ qua. Chúng bắt đầu bằng - [[và kết thúc bằng các ký tự -]] như hình dưới đây -
--[[ my first program in Lua --]]
Định danh
Định danh Lua là tên được sử dụng để xác định một biến, hàm hoặc bất kỳ mục nào khác do người dùng xác định. Số nhận dạng bắt đầu bằng chữ cái 'A đến Z' hoặc 'a đến z' hoặc dấu gạch dưới '_', theo sau là không hoặc nhiều chữ cái, dấu gạch dưới và chữ số (0 đến 9).
Lua không cho phép các ký tự dấu câu như @, $ và% trong số nhận dạng. Lua là mộtcase sensitivengôn ngữ lập trình. Như vậy Nhân lực và nhân lực là hai định danh khác nhau trong Lúa. Dưới đây là một số ví dụ về các số nhận dạng được chấp nhận -
mohd zara abc move_name a_123
myname50 _temp j a23b9 retVal
Từ khóa
Danh sách sau đây cho thấy một số từ dành riêng trong Lua. Những từ dành riêng này không được dùng làm hằng số hoặc biến hoặc bất kỳ tên định danh nào khác.
và | phá vỡ | làm | khác |
elseif | kết thúc | sai | cho |
chức năng | nếu | trong | địa phương |
không | không phải | hoặc là | nói lại |
trở về | sau đó | thật | cho đến khi |
trong khi |
Khoảng trắng trong Lua
Một dòng chỉ chứa khoảng trắng, có thể có chú thích, được gọi là dòng trống và trình thông dịch Lua hoàn toàn bỏ qua nó.
Khoảng trắng là thuật ngữ được sử dụng trong Lua để mô tả khoảng trống, tab, ký tự dòng mới và nhận xét. Khoảng trắng phân tách một phần của câu lệnh với phần khác và cho phép trình thông dịch xác định vị trí một phần tử trong câu lệnh, chẳng hạn như int kết thúc và phần tử tiếp theo bắt đầu. Do đó, trong câu lệnh sau:
local age
Phải có ít nhất một ký tự khoảng trắng (thường là khoảng trắng) giữa địa phương và tuổi để trình thông dịch có thể phân biệt chúng. Mặt khác, trong câu lệnh sau:
fruit = apples + oranges --get the total fruit
Không cần ký tự khoảng trắng nào giữa trái cây và =, hoặc giữa = và táo, mặc dù bạn có thể thêm một số ký tự nếu muốn vì mục đích dễ đọc.
Một biến không là gì ngoài tên được đặt cho một vùng lưu trữ mà chương trình của chúng ta có thể thao tác. Nó có thể chứa các loại giá trị khác nhau bao gồm các hàm và bảng.
Tên của một biến có thể bao gồm các chữ cái, chữ số và ký tự gạch dưới. Nó phải bắt đầu bằng một chữ cái hoặc một dấu gạch dưới. Chữ hoa và chữ thường khác nhau vì Lua có phân biệt chữ hoa chữ thường. Có tám loại giá trị cơ bản trong Lua -
Trong Lua, mặc dù chúng ta không có kiểu dữ liệu biến, chúng ta có ba kiểu dựa trên phạm vi của biến.
Global variables - Tất cả các biến được coi là toàn cục trừ khi được khai báo rõ ràng là cục bộ.
Local variables - Khi kiểu được chỉ định là cục bộ cho một biến thì phạm vi của nó bị giới hạn với các hàm bên trong phạm vi của chúng.
Table fields - Đây là một loại biến đặc biệt có thể chứa bất cứ thứ gì ngoại trừ nil bao gồm các hàm.
Định nghĩa biến trong Lua
Định nghĩa biến có nghĩa là cho trình thông dịch biết vị trí và số lượng để tạo bộ lưu trữ cho biến. Định nghĩa biến có kiểu tùy chọn và chứa danh sách một hoặc nhiều biến thuộc kiểu đó như sau:
type variable_list;
Đây, type là tùy chọn cục bộ hoặc kiểu được chỉ định làm cho nó toàn cầu và variable_listcó thể bao gồm một hoặc nhiều tên định danh được phân tách bằng dấu phẩy. Một số khai báo hợp lệ được hiển thị ở đây -
local i, j
local i
local a,c
Dòng local i, jcả khai báo và định nghĩa các biến i và j; hướng dẫn trình thông dịch tạo các biến có tên i, j và giới hạn phạm vi là cục bộ.
Các biến có thể được khởi tạo (gán giá trị ban đầu) trong khai báo của chúng. Bộ khởi tạo bao gồm một dấu bằng theo sau là một biểu thức hằng số như sau:
type variable_list = value_list;
Một số ví dụ là -
local d , f = 5 ,10 --declaration of d and f as local variables.
d , f = 5, 10; --declaration of d and f as global variables.
d, f = 10 --[[declaration of d and f as global variables.
Here value of f is nil --]]
Đối với định nghĩa không có trình khởi tạo: các biến có thời lượng lưu trữ tĩnh được khởi tạo ngầm định bằng nil.
Khai báo biến trong Lua
Như bạn có thể thấy trong các ví dụ trên, các phép gán cho nhiều biến tuân theo định dạng danh sách biến và giá trị. Trong ví dụ trênlocal d, f = 5,10 chúng ta có d và f trong danh sách biến và 5 và 10 trong danh sách giá trị.
Việc gán giá trị trong Lua diễn ra giống như biến đầu tiên trong danh sách biến với giá trị đầu tiên trong danh sách giá trị, v.v. Do đó, giá trị của d là 5 và giá trị của f là 10.
Thí dụ
Hãy thử ví dụ sau, trong đó các biến đã được khai báo ở trên cùng, nhưng chúng đã được xác định và khởi tạo bên trong hàm chính:
-- Variable definition:
local a, b
-- Initialization
a = 10
b = 30
print("value of a:", a)
print("value of b:", b)
-- Swapping of variables
b, a = a, b
print("value of a:", a)
print("value of b:", b)
f = 70.0/3.0
print("value of f", f)
Khi đoạn mã trên được xây dựng và thực thi, nó tạo ra kết quả sau:
value of a: 10
value of b: 30
value of a: 30
value of b: 10
value of f 23.333333333333
Giá trị và giá trị trong Lua
Có hai loại biểu thức trong Lua -
lvalue- Các biểu thức tham chiếu đến một vị trí bộ nhớ được gọi là biểu thức "lvalue". Giá trị có thể xuất hiện ở dạng bên trái hoặc bên phải của bài tập.
rvalue- Thuật ngữ rvalue đề cập đến một giá trị dữ liệu được lưu trữ tại một số địa chỉ trong bộ nhớ. Giá trị là một biểu thức không thể có giá trị được gán cho nó, có nghĩa là giá trị có thể xuất hiện ở phía bên phải, nhưng không xuất hiện ở phía bên trái của phép gán.
Các biến là giá trị và do đó có thể xuất hiện ở phía bên trái của phép gán. Các chữ số là các giá trị và do đó có thể không được gán và không thể xuất hiện ở phía bên trái. Sau đây là một tuyên bố hợp lệ -
g = 20
Nhưng sau đây không phải là một tuyên bố hợp lệ và sẽ tạo ra lỗi thời gian xây dựng -
10 = 20
Trong ngôn ngữ lập trình Lua, ngoài các kiểu gán trên, có thể có nhiều giá trị và giá trị trong cùng một câu lệnh. Nó được hiển thị bên dưới.
g,l = 20,30
Trong câu lệnh trên, 20 được gán cho g và 30 được gán cho l.
Lua là một ngôn ngữ được nhập động, vì vậy các biến không có kiểu, chỉ có các giá trị mới có kiểu. Giá trị có thể được lưu trữ trong các biến, được truyền dưới dạng tham số và trả về dưới dạng kết quả.
Trong Lua, mặc dù chúng ta không có kiểu dữ liệu biến đổi, nhưng chúng ta có kiểu cho các giá trị. Dưới đây là danh sách các kiểu dữ liệu cho các giá trị.
Sr.No | Loại Giá trị & Mô tả |
---|---|
1 | nil Được sử dụng để phân biệt giá trị có một số dữ liệu hoặc không có dữ liệu (nil). |
2 | boolean Bao gồm giá trị true và false. Thường được sử dụng để kiểm tra tình trạng. |
3 | number Biểu diễn số thực (dấu phẩy động chính xác kép). |
4 | string Biểu diễn mảng ký tự. |
5 | function Đại diện cho một phương thức được viết bằng C hoặc Lua. |
6 | userdata Biểu diễn dữ liệu C tùy ý. |
7 | thread Đại diện cho các luồng thực thi độc lập và nó được sử dụng để triển khai các coroutines. |
số 8 | table Biểu diễn các mảng thông thường, bảng ký hiệu, tập hợp, bản ghi, đồ thị, cây, v.v. và triển khai các mảng kết hợp. Nó có thể giữ bất kỳ giá trị nào (ngoại trừ nil). |
Loại chức năng
Trong Lua, có một hàm gọi là 'kiểu' cho phép chúng ta biết kiểu của biến. Một số ví dụ được đưa ra trong đoạn mã sau.
print(type("What is my type")) --> string
t = 10
print(type(5.8*t)) --> number
print(type(true)) --> boolean
print(type(print)) --> function
print(type(nil)) --> nil
print(type(type(ABC))) --> string
Khi bạn xây dựng và thực thi chương trình trên, nó tạo ra kết quả sau trên Linux:
string
number
boolean
function
nil
string
Theo mặc định, tất cả các biến sẽ trỏ đến nil cho đến khi chúng được gán giá trị hoặc khởi tạo. Trong Lua, chuỗi không và chuỗi rỗng được coi là đúng trong trường hợp kiểm tra điều kiện. Do đó, bạn phải cẩn thận khi sử dụng các phép toán Boolean. Chúng ta sẽ biết nhiều hơn cách sử dụng các loại này trong các chương tiếp theo.
Toán tử là một ký hiệu yêu cầu trình thông dịch thực hiện các thao tác toán học hoặc logic cụ thể. Ngôn ngữ Lua có nhiều toán tử cài sẵn và cung cấp các loại toán tử sau:
- Toán tử số học
- Toán tử quan hệ
- Toán tử logic
- Nhà điều hành khác
Hướng dẫn này sẽ giải thích từng toán tử số học, quan hệ, logic và các toán tử linh tinh khác.
Toán tử số học
Bảng sau hiển thị tất cả các toán tử số học được ngôn ngữ Lua hỗ trợ. Giả sử biếnA giữ 10 và biến B giữ 20 sau đó -
Hiển thị các ví dụ
Nhà điều hành | Sự miêu tả | Thí dụ |
---|---|---|
+ | Thêm hai toán hạng | A + B sẽ cho 30 |
- | Trừ toán hạng thứ hai với toán hạng đầu tiên | A - B sẽ cho -10 |
* | Nhân cả hai toán hạng | A * B sẽ cho 200 |
/ | Chia tử số cho tử số | B / A sẽ cho 2 |
% | Toán tử mô đun và phần còn lại của sau một phép chia số nguyên | B% A sẽ cho 0 |
^ | Toán tử lũy thừa lấy số mũ | A ^ 2 sẽ cho 100 |
- | Đơn nguyên - toán tử hoạt động như một phủ định | -A sẽ cho -10 |
Toán tử quan hệ
Bảng sau hiển thị tất cả các toán tử quan hệ được hỗ trợ bởi ngôn ngữ Lua. Giả sử biếnA giữ 10 và biến B giữ 20 sau đó -
Hiển thị các ví dụ
Nhà điều hành | Sự miêu tả | Thí dụ |
---|---|---|
== | Kiểm tra xem giá trị của hai toán hạng có bằng nhau hay không, nếu có thì điều kiện trở thành true. | (A == B) không đúng. |
~ = | Kiểm tra xem giá trị của hai toán hạng có bằng nhau hay không, nếu các giá trị không bằng nhau thì điều kiện trở thành true. | (A ~ = B) là đúng. |
> | Kiểm tra xem giá trị của toán hạng bên trái có lớn hơn giá trị của toán hạng bên phải hay không, nếu có thì điều kiện trở thành true. | (A> B) là không đúng. |
< | Kiểm tra xem giá trị của toán hạng bên trái có nhỏ hơn giá trị của toán hạng bên phải hay không, nếu có thì điều kiện trở thành true. | (A <B) là đúng. |
> = | Kiểm tra xem giá trị của toán hạng bên trái có lớn hơn hoặc bằng giá trị của toán hạng bên phải hay không, nếu có thì điều kiện trở thành true. | (A> = B) là không đúng. |
<= | Kiểm tra xem giá trị của toán hạng bên trái có nhỏ hơn hoặc bằng giá trị của toán hạng bên phải hay không, nếu có thì điều kiện trở thành true. | (A <= B) là đúng. |
Toán tử logic
Bảng sau đây hiển thị tất cả các toán tử logic được hỗ trợ bởi ngôn ngữ Lua. Giả sử biếnA giữ đúng và biến B sau đó là sai -
Hiển thị các ví dụ
Nhà điều hành | Sự miêu tả | Thí dụ |
---|---|---|
và | Được gọi là toán tử logic AND. Nếu cả hai toán hạng đều khác 0 thì điều kiện trở thành true. | (A và B) là sai. |
hoặc là | Được gọi là Toán tử logic HOẶC. Nếu bất kỳ toán hạng nào trong hai toán hạng khác 0 thì điều kiện trở thành true. | (A hoặc B) là đúng. |
không phải | Được gọi là Toán tử logic NOT. Sử dụng để đảo ngược trạng thái logic của toán hạng của nó. Nếu một điều kiện là đúng thì toán tử logic NOT sẽ sai. | ! (A và B) là đúng. |
Nhà điều hành khác
Các toán tử khác được Lua Language hỗ trợ bao gồm concatenation và length.
Hiển thị các ví dụ
Nhà điều hành | Sự miêu tả | Thí dụ |
---|---|---|
.. | Nối hai chuỗi. | a..b trong đó a là "Hello" và b là "World", sẽ trả về "Hello World". |
# | Toán tử một ngôi trả về độ dài của một chuỗi hoặc một bảng. | # "Xin chào" sẽ trả về 5 |
Quyền ưu tiên của nhà khai thác trong Lua
Mức độ ưu tiên của toán tử xác định nhóm các từ trong một biểu thức. Điều này ảnh hưởng đến cách một biểu thức được đánh giá. Các toán tử nhất định có quyền ưu tiên cao hơn những toán tử khác; ví dụ, toán tử nhân có mức độ ưu tiên cao hơn toán tử cộng -
Ví dụ: x = 7 + 3 * 2; Ở đây x được gán 13, không phải 20 vì toán tử * có mức độ ưu tiên cao hơn + nên trước tiên nó được nhân với 3 * 2 và sau đó cộng thành 7.
Ở đây, các toán tử có mức độ ưu tiên cao nhất xuất hiện ở đầu bảng, những toán tử có mức độ ưu tiên thấp nhất xuất hiện ở cuối bảng. Trong một biểu thức, các toán tử có mức độ ưu tiên cao hơn sẽ được đánh giá đầu tiên.
Hiển thị các ví dụ
thể loại | Nhà điều hành | Sự liên kết |
---|---|---|
Một ngôi | không phải # - | Phải sang trái |
Kết nối | .. | Phải sang trái |
Phép nhân | * /% | Trái sang phải |
Phụ gia | + - | Trái sang phải |
Quan hệ | <> <=> = == ~ = | Trái sang phải |
Bình đẳng | == ~ = | Trái sang phải |
Logic AND | và | Trái sang phải |
Logic HOẶC | hoặc là | Trái sang phải |
Có thể có một tình huống khi bạn cần thực thi một khối mã nhiều lần. Nói chung, các câu lệnh được thực thi tuần tự: câu lệnh đầu tiên trong một hàm được thực hiện trước tiên, tiếp theo là câu lệnh thứ hai, v.v.
Các ngôn ngữ lập trình cung cấp các cấu trúc điều khiển khác nhau cho phép các đường dẫn thực thi phức tạp hơn.
Một câu lệnh lặp cho phép chúng ta thực hiện một câu lệnh hoặc một nhóm câu lệnh nhiều lần. Sau đây là dạng chung của câu lệnh lặp trong hầu hết các ngôn ngữ lập trình:
Lua cung cấp các loại vòng lặp sau để xử lý các yêu cầu về vòng lặp.
Sr.No. | Loại vòng lặp & Mô tả |
---|---|
1 | trong khi lặp lại Lặp lại một câu lệnh hoặc một nhóm câu lệnh trong khi một điều kiện đã cho là đúng. Nó kiểm tra điều kiện trước khi thực thi phần thân của vòng lặp. |
2 | vòng lặp for Thực thi một chuỗi các câu lệnh nhiều lần và viết tắt mã quản lý biến vòng lặp. |
3 | lặp lại ... cho đến khi lặp lại Lặp lại hoạt động của nhóm câu lệnh cho đến khi điều kiện được đáp ứng. |
4 | vòng lồng nhau Bạn có thể sử dụng một hoặc nhiều vòng lặp bên trong bất kỳ vòng lặp while , for hoặc do.. while nào khác . |
Loop Control Statement
Loop control statement changes execution from its normal sequence. When execution leaves a scope, all automatic objects that were created in that scope are destroyed.
Lua supports the following control statements.
Sr.No. | Control Statement & Description |
---|---|
1 | break statement Terminates the loop and transfers execution to the statement immediately following the loop or switch. |
The Infinite Loop
A loop becomes infinite loop if a condition never becomes false. The while loop is often used for this purpose. Since we directly give true for the condition, it keeps executing forever. We can use the break statement to break this loop.
while( true )
do
print("This loop will run forever.")
end
Decision making structures require that the programmer specifies one or more conditions to be evaluated or tested by the program, along with a statement or statements to be executed, if the condition is determined to be true, and optionally, other statements to be executed if the condition is determined to be false.
Following is the general form of a typical decision making structure found in most of the programming languages −
Lua programming language assumes any combination of Boolean true and non-nil values as true, and if it is either boolean false or nil, then it is assumed as false value. It is to be noted that in Lua, zero will be considered as true.
Lua programming language provides the following types of decision making statements.
Sr.No. | Statement & Description |
---|---|
1 | if statement An if statement consists of a boolean expression followed by one or more statements. |
2 | if...else statement An if statement can be followed by an optional else statement, which executes when the boolean expression is false. |
3 | nested if statements You can use one if or else if statement inside another if or else if statement(s). |
A function is a group of statements that together perform a task. You can divide up your code into separate functions. How you divide up your code among different functions is up to you, but logically the division usually unique, is so each function performs a specific task.
The Lua language provides numerous built-in methods that your program can call. For example, method print() to print the argument passed as input in console.
A function is known with various names like a method or a sub-routine or a procedure etc.
Defining a Function
The general form of a method definition in Lua programming language is as follows −
optional_function_scope function function_name( argument1, argument2, argument3........,
argumentn)
function_body
return result_params_comma_separated
end
A method definition in Lua programming language consists of a method header and a method body. Here are all the parts of a method −
Optional Function Scope − You can use keyword local to limit the scope of the function or ignore the scope section, which will make it a global function.
Function Name − This is the actual name of the function. The function name and the parameter list together constitute the function signature.
Arguments − An argument is like a placeholder. When a function is invoked, you pass a value to the argument. This value is referred to as the actual parameter or argument. The parameter list refers to the type, order, and number of the arguments of a method. Arguments are optional; that is, a method may contain no argument.
Function Body − The method body contains a collection of statements that define what the method does.
Return − In Lua, it is possible to return multiple values by following the return keyword with the comma separated return values.
Example
Following is the source code for a function called max(). This function takes two parameters num1 and num2 and returns the maximum between the two −
--[[ function returning the max between two numbers --]]
function max(num1, num2)
if (num1 > num2) then
result = num1;
else
result = num2;
end
return result;
end
Function Arguments
If a function is to use arguments, it must declare the variables that accept the values of the arguments. These variables are called the formal parameters of the function.
The formal parameters behave like other local variables inside the function and are created upon entry into the function and destroyed upon exit.
Calling a Function
While creating a Lua function, you give a definition of what the function has to do. To use a method, you will have to call that function to perform the defined task.
When a program calls a function, program control is transferred to the called function. A called function performs the defined task and when its return statement is executed or when its function's end is reached, it returns program control back to the main program.
To call a method, you simply need to pass the required parameters along with the method name and if the method returns a value, then you can store the returned value. For example −
function max(num1, num2)
if (num1 > num2) then
result = num1;
else
result = num2;
end
return result;
end
-- calling a function
print("The maximum of the two numbers is ",max(10,4))
print("The maximum of the two numbers is ",max(5,6))
When we run the above code, we will get the following output.
The maximum of the two numbers is 10
The maximum of the two numbers is 6
Assigning and Passing Functions
In Lua, we can assign the function to variables and also can pass them as parameters of another function. Here is a simple example for assigning and passing a function as parameter in Lua.
myprint = function(param)
print("This is my print function - ##",param,"##")
end
function add(num1,num2,functionPrint)
result = num1 + num2
functionPrint(result)
end
myprint(10)
add(2,5,myprint)
When we run the above code, we will get the following output.
This is my print function - ## 10 ##
This is my print function - ## 7 ##
Function with Variable Argument
It is possible to create functions with variable arguments in Lua using '...' as its parameter. We can get a grasp of this by seeing an example in which the function will return the average and it can take variable arguments.
function average(...)
result = 0
local arg = {...}
for i,v in ipairs(arg) do
result = result + v
end
return result/#arg
end
print("The average is",average(10,5,3,4,5,6))
When we run the above code, we will get the following output.
The average is 5.5
String is a sequence of characters as well as control characters like form feed. String can be initialized with three forms which includes −
- Characters between single quotes
- Characters between double quotes
- Characters between [[ and ]]
An example for the above three forms are shown below.
string1 = "Lua"
print("\"String 1 is\"",string1)
string2 = 'Tutorial'
print("String 2 is",string2)
string3 = [["Lua Tutorial"]]
print("String 3 is",string3)
When we run the above program, we will get the following output.
"String 1 is" Lua
String 2 is Tutorial
String 3 is "Lua Tutorial"
Escape sequence characters are used in string to change the normal interpretation of characters. For example, to print double inverted commas (""), we have used \" in the above example. The escape sequence and its use is listed below in the table.
Escape Sequence | Use |
---|---|
\a | Bell |
\b | Backspace |
\f | Formfeed |
\n | New line |
\r | Carriage return |
\t | Tab |
\v | Vertical tab |
\\ | Backslash |
\" | Double quotes |
\' | Single quotes |
\[ | Left square bracket |
\] | Right square bracket |
String Manipulation
Lua supports string to manipulate strings −
Sr.No. | Method & Purpose |
---|---|
1 | string.upper(argument) Returns a capitalized representation of the argument. |
2 | string.lower(argument) Returns a lower case representation of the argument. |
3 | string.gsub(mainString,findString,replaceString) Returns a string by replacing occurrences of findString with replaceString. |
4 | string.find(mainString,findString, optionalStartIndex,optionalEndIndex) Returns the start index and end index of the findString in the main string and nil if not found. |
5 | string.reverse(arg) Returns a string by reversing the characters of the passed string. |
6 | string.format(...) Returns a formatted string. |
7 | string.char(arg) and string.byte(arg) Returns internal numeric and character representations of input argument. |
8 | string.len(arg) Returns a length of the passed string. |
9 | string.rep(string, n)) Returns a string by repeating the same string n number times. |
10 | .. Thus operator concatenates two strings. |
Now, let's dive into a few examples to exactly see how these string manipulation functions behave.
Case Manipulation
A sample code for manipulating the strings to upper and lower case is given below.
string1 = "Lua";
print(string.upper(string1))
print(string.lower(string1))
When we run the above program, we will get the following output.
LUA
lua
Replacing a Substring
A sample code for replacing occurrences of one string with another is given below.
string = "Lua Tutorial"
-- replacing strings
newstring = string.gsub(string,"Tutorial","Language")
print("The new string is "..newstring)
When we run the above program, we will get the following output.
The new string is Lua Language
Finding and Reversing
A sample code for finding the index of substring and reversing string is given below.
string = "Lua Tutorial"
-- replacing strings
print(string.find(string,"Tutorial"))
reversedString = string.reverse(string)
print("The new string is",reversedString)
When we run the above program, we will get the following output.
5 12
The new string is lairotuT auL
Formatting Strings
Many times in our programming, we may need to print strings in a formatted way. You can use the string.format function to format the output as shown below.
string1 = "Lua"
string2 = "Tutorial"
number1 = 10
number2 = 20
-- Basic string formatting
print(string.format("Basic formatting %s %s",string1,string2))
-- Date formatting
date = 2; month = 1; year = 2014
print(string.format("Date formatting %02d/%02d/%03d", date, month, year))
-- Decimal formatting
print(string.format("%.4f",1/3))
When we run the above program, we will get the following output.
Basic formatting Lua Tutorial
Date formatting 02/01/2014
0.3333
Character and Byte Representations
A sample code for character and byte representation, which is used for converting the string from string to internal representation and vice versa.
-- Byte conversion
-- First character
print(string.byte("Lua"))
-- Third character
print(string.byte("Lua",3))
-- first character from last
print(string.byte("Lua",-1))
-- Second character
print(string.byte("Lua",2))
-- Second character from last
print(string.byte("Lua",-2))
-- Internal Numeric ASCII Conversion
print(string.char(97))
When we run the above program, we will get the following output.
76
97
97
117
117
a
Other Common Functions
The common string manipulations include string concatenation, finding length of string and at times repeating the same string multiple times. The example for these operations is given below.
string1 = "Lua"
string2 = "Tutorial"
-- String Concatenations using ..
print("Concatenated string",string1..string2)
-- Length of string
print("Length of string1 is ",string.len(string1))
-- Repeating strings
repeatedString = string.rep(string1,3)
print(repeatedString)
When we run the above program, we will get the following output.
Concatenated string LuaTutorial
Length of string1 is 3
LuaLuaLua
Arrays are ordered arrangement of objects, which may be a one-dimensional array containing a collection of rows or a multi-dimensional array containing multiple rows and columns.
In Lua, arrays are implemented using indexing tables with integers. The size of an array is not fixed and it can grow based on our requirements, subject to memory constraints.
One-Dimensional Array
A one-dimensional array can be represented using a simple table structure and can be initialized and read using a simple for loop. An example is shown below.
array = {"Lua", "Tutorial"}
for i = 0, 2 do
print(array[i])
end
When we run the above code, we wil get the following output.
nil
Lua
Tutorial
As you can see in the above code, when we are trying to access an element in an index that is not there in the array, it returns nil. In Lua, indexing generally starts at index 1. But it is possible to create objects at index 0 and below 0 as well. Array using negative indices is shown below where we initialize the array using a for loop.
array = {}
for i= -2, 2 do
array[i] = i *2
end
for i = -2,2 do
print(array[i])
end
When we run the above code, we will get the following output.
-4
-2
0
2
4
Multi-Dimensional Array
Multi-dimensional arrays can be implemented in two ways.
- Array of arrays
- Single dimensional array by manipulating indices
An example for multidimensional array of 3. 3 is shown below using array of arrays.
-- Initializing the array
array = {}
for i=1,3 do
array[i] = {}
for j=1,3 do
array[i][j] = i*j
end
end
-- Accessing the array
for i=1,3 do
for j=1,3 do
print(array[i][j])
end
end
When we run the above code, we will get the following output.
1
2
3
2
4
6
3
6
9
An example for multidimensional array is shown below using manipulating indices.
-- Initializing the array
array = {}
maxRows = 3
maxColumns = 3
for row=1,maxRows do
for col=1,maxColumns do
array[row*maxColumns +col] = row*col
end
end
-- Accessing the array
for row=1,maxRows do
for col=1,maxColumns do
print(array[row*maxColumns +col])
end
end
When we run the above code, we will get the following output.
1
2
3
2
4
6
3
6
9
As you can see in the above example, data is stored based on indices. It is possible to place the elements in a sparse way and it is the way Lua implementation of a matrix works. Since it does not store nil values in Lua, it is possible to save lots of memory without any special technique in Lua as compared to special techniques used in other programming languages.
Iterator is a construct that enables you to traverse through the elements of the so called collection or container. In Lua, these collections often refer to tables, which are used to create various data structures like array.
Generic For Iterator
A generic for iterator provides the key value pairs of each element in the collection. A simple example is given below.
array = {"Lua", "Tutorial"}
for key,value in ipairs(array)
do
print(key, value)
end
When we run the above code, we will get the following output −
1 Lua
2 Tutorial
The above example uses the default ipairs iterator function provided by Lua.
In Lua we use functions to represent iterators. Based on the state maintenance in these iterator functions, we have two main types −
- Stateless Iterators
- Stateful Iterators
Stateless Iterators
By the name itself we can understand that this type of iterator function does not retain any state.
Let us now see an example of creating our own iterator using a simple function that prints the squares of n numbers.
function square(iteratorMaxCount,currentNumber)
if currentNumber<iteratorMaxCount
then
currentNumber = currentNumber+1
return currentNumber, currentNumber*currentNumber
end
end
for i,n in square,3,0
do
print(i,n)
end
When we run the above program, we will get the following output.
1 1
2 4
3 9
The above code can be modified slightly to mimic the way ipairs function of iterators work. It is shown below.
function square(iteratorMaxCount,currentNumber)
if currentNumber<iteratorMaxCount
then
currentNumber = currentNumber+1
return currentNumber, currentNumber*currentNumber
end
end
function squares(iteratorMaxCount)
return square,iteratorMaxCount,0
end
for i,n in squares(3)
do
print(i,n)
end
When we run the above program, we will get the following output.
1 1
2 4
3 9
Stateful Iterators
The previous example of iteration using function does not retain the state. Each time the function is called, it returns the next element of the collection based on a second variable sent to the function. To hold the state of the current element, closures are used. Closure retain variables values across functions calls. To create a new closure, we create two functions including the closure itself and a factory, the function that creates the closure.
Let us now see an example of creating our own iterator in which we will be using closures.
array = {"Lua", "Tutorial"}
function elementIterator (collection)
local index = 0
local count = #collection
-- The closure function is returned
return function ()
index = index + 1
if index <= count
then
-- return the current element of the iterator
return collection[index]
end
end
end
for element in elementIterator(array)
do
print(element)
end
When we run the above program, we will get the following output.
Lua
Tutorial
In the above example, we can see that elementIterator has another method inside that uses the local external variables index and count to return each of the element in the collection by incrementing the index each time the function is called.
We can create our own function iterators using closure as shown above and it can return multiple elements for each of the time we iterate through the collection.
Introduction
Tables are the only data structure available in Lua that helps us create different types like arrays and dictionaries. Lua uses associative arrays and which can be indexed with not only numbers but also with strings except nil. Tables have no fixed size and can grow based on our need.
Lua uses tables in all representations including representation of packages. When we access a method string.format, it means, we are accessing the format function available in the string package.
Representation and Usage
Tables are called objects and they are neither values nor variables. Lua uses a constructor expression {} to create an empty table. It is to be known that there is no fixed relationship between a variable that holds reference of table and the table itself.
--sample table initialization
mytable = {}
--simple table value assignment
mytable[1]= "Lua"
--removing reference
mytable = nil
-- lua garbage collection will take care of releasing memory
When we have a table a with set of elements and if we assign it to b, both a and b refer to the same memory. No separate memory is allocated separately for b. When a is set to nil, table will be still accessible to b. When there are no reference to a table, then garbage collection in Lua takes care of cleaning up process to make these unreferenced memory to be reused again.
An example is shown below for explaining the above mentioned features of tables.
-- Simple empty table
mytable = {}
print("Type of mytable is ",type(mytable))
mytable[1]= "Lua"
mytable["wow"] = "Tutorial"
print("mytable Element at index 1 is ", mytable[1])
print("mytable Element at index wow is ", mytable["wow"])
-- alternatetable and mytable refers to same table
alternatetable = mytable
print("alternatetable Element at index 1 is ", alternatetable[1])
print("alternatetable Element at index wow is ", alternatetable["wow"])
alternatetable["wow"] = "I changed it"
print("mytable Element at index wow is ", mytable["wow"])
-- only variable released and and not table
alternatetable = nil
print("alternatetable is ", alternatetable)
-- mytable is still accessible
print("mytable Element at index wow is ", mytable["wow"])
mytable = nil
print("mytable is ", mytable)
Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau:
Type of mytable is table
mytable Element at index 1 is Lua
mytable Element at index wow is Tutorial
alternatetable Element at index 1 is Lua
alternatetable Element at index wow is Tutorial
mytable Element at index wow is I changed it
alternatetable is nil
mytable Element at index wow is I changed it
mytable is nil
Thao tác bảng
Có sẵn các hàm để thao tác trên bảng và chúng được liệt kê trong bảng sau.
Sr.No. | Phương pháp & Mục đích |
---|---|
1 | table.concat (table [, sep [, i [, j]]]) Nối các chuỗi trong bảng dựa trên các tham số đã cho. Xem ví dụ để biết chi tiết. |
2 | table.insert (table, [pos,] value) Chèn một giá trị vào bảng ở vị trí đã chỉ định. |
3 | table.maxn (table) Trả về chỉ mục số lớn nhất. |
4 | table.remove (table [, pos]) Xóa giá trị khỏi bảng. |
5 | table.sort (table [, comp]) Sắp xếp bảng dựa trên đối số so sánh tùy chọn. |
Hãy cùng chúng tôi xem một số mẫu của các chức năng trên.
Kết nối bảng
Chúng ta có thể sử dụng hàm concat để ghép hai bảng như hình dưới đây:
fruits = {"banana","orange","apple"}
-- returns concatenated string of table
print("Concatenated string ",table.concat(fruits))
--concatenate with a character
print("Concatenated string ",table.concat(fruits,", "))
--concatenate fruits based on index
print("Concatenated string ",table.concat(fruits,", ", 2,3))
Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau:
Concatenated string bananaorangeapple
Concatenated string banana, orange, apple
Concatenated string orange, apple
Chèn và Xóa
Việc chèn và loại bỏ các mục trong bảng là phổ biến nhất trong thao tác trên bảng. Nó được giải thích dưới đây.
fruits = {"banana","orange","apple"}
-- insert a fruit at the end
table.insert(fruits,"mango")
print("Fruit at index 4 is ",fruits[4])
--insert fruit at index 2
table.insert(fruits,2,"grapes")
print("Fruit at index 2 is ",fruits[2])
print("The maximum elements in table is",table.maxn(fruits))
print("The last element is",fruits[5])
table.remove(fruits)
print("The previous last element is",fruits[5])
Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau:
Fruit at index 4 is mango
Fruit at index 2 is grapes
The maximum elements in table is 5
The last element is mango
The previous last element is nil
Bảng phân loại
Chúng tôi thường yêu cầu sắp xếp một bảng theo một thứ tự cụ thể. Các hàm sắp xếp sắp xếp các phần tử trong bảng theo thứ tự bảng chữ cái. Một mẫu cho điều này được hiển thị bên dưới.
fruits = {"banana","orange","apple","grapes"}
for k,v in ipairs(fruits) do
print(k,v)
end
table.sort(fruits)
print("sorted table")
for k,v in ipairs(fruits) do
print(k,v)
end
Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau:
1 banana
2 orange
3 apple
4 grapes
sorted table
1 apple
2 banana
3 grapes
4 orange
Mô-đun là gì?
Mô-đun giống như một thư viện có thể được tải bằng yêu cầu và có một tên chung duy nhất chứa một bảng. Mô-đun này có thể bao gồm một số hàm và biến. Tất cả các hàm và biến này được bao bọc trong bảng, hoạt động như một không gian tên. Ngoài ra, một mô-đun hoạt động tốt có các điều khoản cần thiết để trả lại bảng này theo yêu cầu.
Tính đặc biệt của Mô-đun Lua
Việc sử dụng các bảng trong mô-đun giúp chúng tôi theo nhiều cách và cho phép chúng tôi thao tác với các mô-đun giống như cách chúng tôi thao tác với bất kỳ bảng Lua nào khác. Do khả năng thao tác với các mô-đun, nó cung cấp các tính năng bổ sung mà các ngôn ngữ khác cần các cơ chế đặc biệt. Do cơ chế miễn phí này của các mô-đun trong Lua, người dùng có thể gọi các hàm trong Lua theo nhiều cách. Một vài trong số chúng được hiển thị bên dưới.
-- Assuming we have a module printFormatter
-- Also printFormatter has a funtion simpleFormat(arg)
-- Method 1
require "printFormatter"
printFormatter.simpleFormat("test")
-- Method 2
local formatter = require "printFormatter"
formatter.simpleFormat("test")
-- Method 3
require "printFormatter"
local formatterFunction = printFormatter.simpleFormat
formatterFunction("test")
Trong đoạn mã mẫu ở trên, bạn có thể thấy cách lập trình linh hoạt trong Lua mà không cần bất kỳ mã bổ sung đặc biệt nào.
Chức năng yêu cầu
Lua đã cung cấp một chức năng cấp cao được gọi là request để tải tất cả các mô-đun cần thiết. Nó được giữ đơn giản nhất có thể để tránh có quá nhiều thông tin trên mô-đun để tải nó. Hàm request chỉ giả sử các mô-đun như một đoạn mã xác định một số giá trị, thực sự là các hàm hoặc bảng chứa các hàm.
Thí dụ
Chúng ta hãy xem xét một ví dụ đơn giản, trong đó một hàm có các hàm toán học. Hãy gọi mô-đun này là mymath và tên tệp là mymath.lua. Nội dung tệp như sau:
local mymath = {}
function mymath.add(a,b)
print(a+b)
end
function mymath.sub(a,b)
print(a-b)
end
function mymath.mul(a,b)
print(a*b)
end
function mymath.div(a,b)
print(a/b)
end
return mymath
Bây giờ, để truy cập mô-đun Lua này trong một tệp khác, chẳng hạn như moduletutorial.lua, bạn cần sử dụng đoạn mã sau.
mymathmodule = require("mymath")
mymathmodule.add(10,20)
mymathmodule.sub(30,20)
mymathmodule.mul(10,20)
mymathmodule.div(30,20)
Để chạy mã này, chúng ta cần đặt hai tệp Lua trong cùng một thư mục hoặc cách khác, bạn có thể đặt tệp mô-đun trong đường dẫn gói và nó cần thiết lập thêm. Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau.
30
10
200
1.5
Những điều cần ghi nhớ
Đặt cả mô-đun và tệp bạn chạy trong cùng một thư mục.
Tên mô-đun và tên tệp của nó phải giống nhau.
Cách tốt nhất là trả về các mô-đun cho chức năng yêu cầu và do đó mô-đun nên được triển khai như được hiển thị ở trên, mặc dù bạn có thể tìm thấy các kiểu triển khai khác ở nơi khác.
Cách thực hiện mô-đun cũ
Bây giờ hãy để tôi viết lại cùng một ví dụ theo cách cũ hơn, sử dụng kiểu triển khai package.seeall. Điều này đã được sử dụng trong phiên bản Lua 5.1 và 5.0. Mô-đun thần thoại được hiển thị bên dưới.
module("mymath", package.seeall)
function mymath.add(a,b)
print(a+b)
end
function mymath.sub(a,b)
print(a-b)
end
function mymath.mul(a,b)
print(a*b)
end
function mymath.div(a,b)
print(a/b)
end
Cách sử dụng các mô-đun trong moduletutorial.lua được hiển thị bên dưới.
require("mymath")
mymath.add(10,20)
mymath.sub(30,20)
mymath.mul(10,20)
mymath.div(30,20)
Khi chúng tôi chạy ở trên, chúng tôi sẽ nhận được cùng một đầu ra. Nhưng bạn nên sử dụng phiên bản mã cũ hơn và nó được cho là kém an toàn hơn. Nhiều SDK sử dụng Lua để lập trình như Corona SDK đã không còn sử dụng tính năng này.
Khả năng đáp ứng là một bảng giúp sửa đổi hành vi của bảng mà nó được gắn vào với sự trợ giúp của bộ khóa và các phương thức meta liên quan. Các phương thức meta này là chức năng Lua mạnh mẽ cho phép các tính năng như -
Thay đổi / thêm chức năng cho các toán tử trên bảng.
Tìm kiếm các dữ liệu có thể đo được khi khóa không có sẵn trong bảng bằng cách sử dụng __index trong metatable.
Có hai phương pháp quan trọng được sử dụng để xử lý các bảng đo bao gồm:
setmetatable(table,metatable) - Phương pháp này được sử dụng để thiết lập độ chính xác cho một bảng.
getmetatable(table) - Phương pháp này được sử dụng để lấy độ phân giải của một bảng.
Trước tiên, hãy xem cách đặt một bảng giống như một bảng khác. Nó được hiển thị bên dưới.
mytable = {}
mymetatable = {}
setmetatable(mytable,mymetatable)
Đoạn mã trên có thể được biểu diễn trong một dòng như hình dưới đây.
mytable = setmetatable({},{})
_mục lục
Dưới đây là một ví dụ đơn giản về việc tra cứu bảng meta khi nó không có sẵn trong bảng.
mytable = setmetatable({key1 = "value1"}, {
__index = function(mytable, key)
if key == "key2" then
return "metatablevalue"
else
return mytable[key]
end
end
})
print(mytable.key1,mytable.key2)
Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau.
value1 metatablevalue
Hãy để chúng tôi giải thích những gì đã xảy ra trong ví dụ trên theo các bước.
Bảng mytable ở đây là {key1 = "value1"}.
Metatable được đặt cho mytable có chứa hàm cho __index, mà chúng tôi gọi là metamethod.
Metamethod thực hiện một công việc đơn giản là tìm kiếm chỉ mục "key2", nếu được tìm thấy, nó sẽ trả về "metatablevalue", nếu không sẽ trả về giá trị của mytable cho chỉ mục tương ứng.
Chúng tôi có thể có một phiên bản đơn giản của chương trình trên như hình dưới đây.
mytable = setmetatable({key1 = "value1"},
{ __index = { key2 = "metatablevalue" } })
print(mytable.key1,mytable.key2)
__newindex
Khi chúng tôi thêm __newindex vào metatable, nếu các khóa không có sẵn trong bảng, thì hoạt động của các khóa mới sẽ được xác định bằng các phương thức meta. Dưới đây là một ví dụ đơn giản trong đó chỉ mục của metatable được đặt khi chỉ mục không có sẵn trong bảng chính.
mymetatable = {}
mytable = setmetatable({key1 = "value1"}, { __newindex = mymetatable })
print(mytable.key1)
mytable.newkey = "new value 2"
print(mytable.newkey,mymetatable.newkey)
mytable.key1 = "new value 1"
print(mytable.key1,mymetatable.newkey1)
Khi bạn chạy chương trình trên, bạn nhận được kết quả sau.
value1
nil new value 2
new value 1 nil
Bạn có thể thấy trong chương trình trên, nếu một khóa tồn tại trong bảng chính, nó chỉ cập nhật nó. Khi một khóa không có sẵn trong phần có thể bảo trì, nó sẽ thêm khóa đó vào phần có thể đo được.
Một ví dụ khác cập nhật cùng một bảng bằng cách sử dụng hàm rawset được hiển thị bên dưới.
mytable = setmetatable({key1 = "value1"}, {
__newindex = function(mytable, key, value)
rawset(mytable, key, "\""..value.."\"")
end
})
mytable.key1 = "new value"
mytable.key2 = 4
print(mytable.key1,mytable.key2)
Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau.
new value "4"
rawset đặt giá trị mà không sử dụng __newindex có thể đo được. Tương tự, có rawget nhận giá trị mà không cần sử dụng __index.
Thêm Hành vi của Người vận hành vào Bảng
Dưới đây là một ví dụ đơn giản để kết hợp hai bảng bằng cách sử dụng + toán tử:
mytable = setmetatable({ 1, 2, 3 }, {
__add = function(mytable, newtable)
for i = 1, table.maxn(newtable) do
table.insert(mytable, table.maxn(mytable)+1,newtable[i])
end
return mytable
end
})
secondtable = {4,5,6}
mytable = mytable + secondtable
for k,v in ipairs(mytable) do
print(k,v)
end
Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau.
1 1
2 2
3 3
4 4
5 5
6 6
Khóa __add được bao gồm trong biến thể để thêm hành vi của toán tử +. Bảng các phím và toán tử tương ứng được hiển thị bên dưới.
Sr.No. | Chế độ & Mô tả |
---|---|
1 | __add Thay đổi hành vi của toán tử '+'. |
2 | __sub Thay đổi hành vi của toán tử '-'. |
3 | __mul Thay đổi hành vi của toán tử '*'. |
4 | __div Thay đổi hành vi của toán tử '/'. |
5 | __mod Thay đổi hành vi của toán tử '%'. |
6 | __unm Thay đổi hành vi của toán tử '-'. |
7 | __concat Thay đổi hành vi của toán tử '..'. |
số 8 | __eq Thay đổi hành vi của toán tử '=='. |
9 | __lt Thay đổi hành vi của toán tử '<'. |
10 | __le Thay đổi hành vi của toán tử '<='. |
__gọi
Thêm hành vi của cuộc gọi phương thức được thực hiện bằng cách sử dụng câu lệnh __call. Một ví dụ đơn giản trả về tổng các giá trị trong bảng chính với bảng đã truyền.
mytable = setmetatable({10}, {
__call = function(mytable, newtable)
sum = 0
for i = 1, table.maxn(mytable) do
sum = sum + mytable[i]
end
for i = 1, table.maxn(newtable) do
sum = sum + newtable[i]
end
return sum
end
})
newtable = {10,20,30}
print(mytable(newtable))
Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau.
70
__tostring
Để thay đổi hành vi của câu lệnh print, chúng ta có thể sử dụng metamethod __tostring. Một ví dụ đơn giản được hiển thị bên dưới.
mytable = setmetatable({ 10, 20, 30 }, {
__tostring = function(mytable)
sum = 0
for k, v in pairs(mytable) do
sum = sum + v
end
return "The sum of values in the table is " .. sum
end
})
print(mytable)
Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau.
The sum of values in the table is 60
Nếu bạn biết đầy đủ các khả năng của bảng meta, bạn thực sự có thể thực hiện nhiều thao tác sẽ rất phức tạp mà không cần sử dụng đến nó. Vì vậy, hãy cố gắng làm việc nhiều hơn với việc sử dụng các bảng đo lường với các tùy chọn khác nhau có sẵn trong bảng meta như được giải thích trong các mẫu và cũng tạo mẫu của riêng bạn.
Giới thiệu
Coroutines có bản chất là hợp tác, cho phép hai hoặc nhiều phương pháp thực thi một cách có kiểm soát. Với coroutines, tại bất kỳ thời điểm nào, chỉ có một quy trình đăng ký chạy và quy trình đăng ký đang chạy này chỉ tạm ngừng thực thi khi nó yêu cầu tạm dừng một cách rõ ràng.
Định nghĩa trên có thể trông mơ hồ. Giả sử chúng ta có hai phương thức, một phương thức chương trình chính và một phương thức đăng quang. Khi chúng ta gọi một hàm điều tra bằng cách sử dụng hàm tiếp tục, nó sẽ bắt đầu thực thi và khi chúng ta gọi hàm thu hồi, nó sẽ tạm ngừng thực thi. Một lần nữa, cùng một quy trình đăng ký có thể tiếp tục thực thi với một lệnh gọi hàm tiếp tục khác từ nơi nó bị tạm dừng. Quá trình này có thể tiếp tục cho đến khi kết thúc quá trình điều tra.
Các chức năng có sẵn trong Coroutines
Bảng sau liệt kê tất cả các hàm có sẵn cho các hàm coroutines trong Lua và cách sử dụng tương ứng của chúng.
Sr.No. | Phương pháp & Mục đích |
---|---|
1 | coroutine.create (f) Tạo một chương trình đăng quang mới với một hàm f và trả về một đối tượng kiểu "thread". |
2 | coroutine.resume (co [, val1, ...]) Tiếp tục co coroutine và chuyển các tham số nếu có. Nó trả về trạng thái hoạt động và các giá trị trả về tùy chọn khác. |
3 | coroutine.running () Trả về chương trình coroutine đang chạy hoặc nil nếu được gọi trong chuỗi chính. |
4 | coroutine.status (co) Trả về một trong các giá trị đang chạy, bình thường, bị treo hoặc chết dựa trên trạng thái của quy trình đăng ký. |
5 | coroutine.wrap (f) Giống như coroutine.create, hàm coroutine.wrap cũng tạo ra một coroutine, nhưng thay vì trả về chính hàm coroutine, nó trả về một hàm mà khi được gọi, sẽ tiếp tục lại các hàm. |
6 | coroutine.yield (...) Tạm dừng quy trình đăng ký đang chạy. Tham số được truyền cho phương thức này hoạt động như các giá trị trả về bổ sung cho hàm tiếp tục. |
Thí dụ
Hãy xem một ví dụ để hiểu khái niệm về coroutines.
co = coroutine.create(function (value1,value2)
local tempvar3 = 10
print("coroutine section 1", value1, value2, tempvar3)
local tempvar1 = coroutine.yield(value1+1,value2+1)
tempvar3 = tempvar3 + value1
print("coroutine section 2",tempvar1 ,tempvar2, tempvar3)
local tempvar1, tempvar2= coroutine.yield(value1+value2, value1-value2)
tempvar3 = tempvar3 + value1
print("coroutine section 3",tempvar1,tempvar2, tempvar3)
return value2, "end"
end)
print("main", coroutine.resume(co, 3, 2))
print("main", coroutine.resume(co, 12,14))
print("main", coroutine.resume(co, 5, 6))
print("main", coroutine.resume(co, 10, 20))
Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau.
coroutine section 1 3 2 10
main true 4 3
coroutine section 2 12 nil 13
main true 5 1
coroutine section 3 5 6 16
main true 2 end
main false cannot resume dead coroutine
Ví dụ trên làm gì?
Như đã đề cập trước đây, chúng tôi sử dụng chức năng tiếp tục để bắt đầu hoạt động và chức năng năng suất để dừng hoạt động. Ngoài ra, bạn có thể thấy rằng có nhiều giá trị trả về nhận được bởi hàm tiếp tục của coroutine.
Đầu tiên, chúng ta tạo một chương trình đăng quang và gán nó cho một tên biến và chương trình đăng quang nhận hai biến làm tham số của nó.
Khi chúng ta gọi hàm tiếp tục đầu tiên, các giá trị 3 và 2 được giữ lại trong các biến tạm thời value1 và value2 cho đến cuối chương trình đăng quang.
Để bạn hiểu điều này, chúng tôi đã sử dụng tempvar3, ban đầu là 10 và nó được cập nhật lên 13 và 16 bởi các lệnh gọi tiếp theo của coroutines vì value1 được giữ lại là 3 trong suốt quá trình thực thi coroutine.
Coroutine.yield đầu tiên trả về hai giá trị 4 và 3 cho hàm tiếp tục, chúng tôi nhận được giá trị này bằng cách cập nhật các tham số đầu vào 3 và 2 trong câu lệnh lợi nhuận. Nó cũng nhận được trạng thái true / false của việc thực thi chương trình đăng quang.
Một điều khác về coroutines là cách xử lý các thông số tiếp theo của cuộc gọi sơ yếu lý lịch, trong ví dụ trên; bạn có thể thấy rằng biến coroutine.yield nhận các tham số cuộc gọi tiếp theo, cung cấp một cách mạnh mẽ để thực hiện hoạt động mới với quyền kiểm tra lại các giá trị tham số hiện có.
Cuối cùng, khi tất cả các câu lệnh trong coroutines được thực thi, các lệnh gọi tiếp theo sẽ trả về false và câu lệnh "không thể tiếp tục coroutine đã chết" dưới dạng phản hồi.
Một ví dụ về thói quen khác
Chúng ta hãy xem xét một quy trình đăng quang đơn giản trả về một số từ 1 đến 5 với sự trợ giúp của hàm lợi nhuận và hàm tiếp tục. Nó tạo ra quy trình đăng ký nếu không có sẵn hoặc nếu không sẽ tiếp tục quy trình đăng ký hiện có.
function getNumber()
local function getNumberHelper()
co = coroutine.create(function ()
coroutine.yield(1)
coroutine.yield(2)
coroutine.yield(3)
coroutine.yield(4)
coroutine.yield(5)
end)
return co
end
if(numberHelper) then
status, number = coroutine.resume(numberHelper);
if coroutine.status(numberHelper) == "dead" then
numberHelper = getNumberHelper()
status, number = coroutine.resume(numberHelper);
end
return number
else
numberHelper = getNumberHelper()
status, number = coroutine.resume(numberHelper);
return number
end
end
for index = 1, 10 do
print(index, getNumber())
end
Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau.
1 1
2 2
3 3
4 4
5 5
6 1
7 2
8 3
9 4
10 5
Thường có sự so sánh các coroutines với các thread của ngôn ngữ đa chương trình, nhưng chúng ta cần hiểu rằng coroutines có các tính năng tương tự của thread nhưng chúng chỉ thực thi một lần và không bao giờ thực thi đồng thời.
Chúng tôi kiểm soát trình tự thực hiện chương trình để đáp ứng nhu cầu với việc cung cấp tạm thời giữ lại một số thông tin nhất định. Sử dụng các biến toàn cục với coroutines cung cấp tính linh hoạt hơn cho các coroutines.
Thư viện I / O được sử dụng để đọc và thao tác các tệp trong Lua. Có hai loại hoạt động tệp trong Lua cụ thể là bộ mô tả tệp ngầm định và bộ mô tả tệp rõ ràng.
Đối với các ví dụ sau, chúng tôi sẽ sử dụng tệp mẫu test.lua như hình dưới đây.
-- sample test.lua
-- sample2 test.lua
Một thao tác mở tệp đơn giản sử dụng câu lệnh sau.
file = io.open (filename [, mode])
Các chế độ tệp khác nhau được liệt kê trong bảng sau.
Sr.No. | Chế độ & Mô tả |
---|---|
1 | "r" Chế độ chỉ đọc và là chế độ mặc định nơi tệp hiện có được mở. |
2 | "w" Chế độ đã bật ghi ghi đè lên tệp hiện có hoặc tạo tệp mới. |
3 | "a" Chế độ nối sẽ mở một tệp hiện có hoặc tạo một tệp mới để nối thêm. |
4 | "r+" Chế độ đọc và ghi cho tệp hiện có. |
5 | "w+" Tất cả dữ liệu hiện có sẽ bị xóa nếu tệp tồn tại hoặc tệp mới được tạo với quyền đọc ghi. |
6 | "a+" Chế độ nối có bật chế độ đọc để mở tệp hiện có hoặc tạo tệp mới. |
Trình mô tả tệp ngầm định
Các bộ mô tả tệp ngầm định sử dụng các chế độ đầu vào / đầu ra tiêu chuẩn hoặc sử dụng một tệp đầu vào và đầu ra duy nhất. Dưới đây là một ví dụ về cách sử dụng bộ mô tả tệp ngầm định.
-- Opens a file in read
file = io.open("test.lua", "r")
-- sets the default input file as test.lua
io.input(file)
-- prints the first line of the file
print(io.read())
-- closes the open file
io.close(file)
-- Opens a file in append mode
file = io.open("test.lua", "a")
-- sets the default output file as test.lua
io.output(file)
-- appends a word test to the last line of the file
io.write("-- End of the test.lua file")
-- closes the open file
io.close(file)
Khi bạn chạy chương trình, bạn sẽ nhận được đầu ra của dòng đầu tiên của tệp test.lua. Đối với chương trình của chúng tôi, chúng tôi nhận được kết quả sau.
-- Sample test.lua
Đây là dòng đầu tiên của câu lệnh trong tệp test.lua cho chúng tôi. Ngoài ra, dòng "- End of the test.lua file" sẽ được nối vào dòng cuối cùng của mã test.lua.
Trong ví dụ trên, bạn có thể thấy cách các bộ mô tả ngầm hoạt động với hệ thống tệp bằng các phương thức io. "X". Ví dụ trên sử dụng io.read () mà không có tham số tùy chọn. Tham số tùy chọn có thể là bất kỳ thông số nào sau đây.
Sr.No. | Chế độ & Mô tả |
---|---|
1 | "*n" Đọc từ vị trí tệp hiện tại và trả về một số nếu tồn tại ở vị trí tệp hoặc trả về nil. |
2 | "*a" Trả về tất cả nội dung của tệp từ vị trí tệp hiện tại. |
3 | "*l" Đọc dòng từ vị trí tệp hiện tại và di chuyển vị trí tệp sang dòng tiếp theo. |
4 | number Đọc số byte được chỉ định trong hàm. |
Các phương thức I / O phổ biến khác bao gồm,
io.tmpfile() - Trả về một tệp tạm thời để đọc và ghi sẽ bị xóa sau khi chương trình thoát.
io.type(file) - Trả về tập tin, tập tin đóng hay nil dựa trên tập tin đầu vào.
io.flush() - Xóa bộ đệm đầu ra mặc định.
io.lines(optional file name)- Cung cấp một trình lặp vòng lặp chung cho vòng lặp lặp qua tệp và đóng tệp cuối cùng, trong trường hợp tên tệp được cung cấp hoặc tệp mặc định được sử dụng và không được đóng ở cuối vòng lặp.
Trình mô tả tệp rõ ràng
Chúng tôi thường sử dụng bộ mô tả tệp rõ ràng cho phép chúng tôi thao tác nhiều tệp cùng một lúc. Các hàm này khá giống với các bộ mô tả tệp ngầm định. Ở đây, chúng tôi sử dụng tệp: function_name thay vì io. functions_name. Dưới đây là ví dụ về phiên bản tệp của cùng một ví dụ về trình mô tả tệp ngầm định.
-- Opens a file in read mode
file = io.open("test.lua", "r")
-- prints the first line of the file
print(file:read())
-- closes the opened file
file:close()
-- Opens a file in append mode
file = io.open("test.lua", "a")
-- appends a word test to the last line of the file
file:write("--test")
-- closes the open file
file:close()
Khi bạn chạy chương trình, bạn sẽ nhận được một kết quả tương tự như ví dụ về bộ mô tả ngầm định.
-- Sample test.lua
Tất cả các chế độ mở tệp và tham số để đọc cho các bộ mô tả bên ngoài đều giống như các bộ mô tả tệp ngầm định.
Các phương pháp tệp phổ biến khác bao gồm,
file:seek(optional whence, optional offset)- Tham số khice là "set", "cur" hoặc "end". Đặt con trỏ tệp mới với vị trí tệp được cập nhật từ đầu tệp. Các hiệu số được dựa trên 0 trong chức năng này. Độ lệch được đo từ đầu tệp nếu đối số đầu tiên là "set"; từ vị trí hiện tại trong tệp nếu nó là "cur"; hoặc từ cuối tệp nếu nó là "kết thúc". Các giá trị đối số mặc định là "cur" và 0, vì vậy vị trí tệp hiện tại có thể nhận được bằng cách gọi hàm này mà không có đối số.
file:flush() - Xóa bộ đệm đầu ra mặc định.
io.lines(optional file name)- Cung cấp một trình lặp vòng lặp chung cho vòng lặp lặp qua tệp và đóng tệp cuối cùng, trong trường hợp tên tệp được cung cấp hoặc tệp mặc định được sử dụng và không được đóng ở cuối vòng lặp.
Dưới đây là một ví dụ để sử dụng phương pháp tìm kiếm. Nó đặt con trỏ khỏi 25 vị trí trước khi kết thúc tệp. Chức năng đọc in phần còn lại của tệp từ vị trí tìm kiếm.
-- Opens a file in read
file = io.open("test.lua", "r")
file:seek("end",-25)
print(file:read("*a"))
-- closes the opened file
file:close()
Bạn sẽ nhận được một số đầu ra tương tự như sau.
sample2 test.lua
--test
Bạn có thể chơi xung quanh tất cả các chế độ và thông số khác nhau để biết toàn bộ khả năng hoạt động của tệp Lua.
Cần xử lý lỗi
Việc xử lý lỗi là khá quan trọng vì các hoạt động trong thế giới thực thường yêu cầu sử dụng các hoạt động phức tạp, bao gồm hoạt động tệp, giao dịch cơ sở dữ liệu và lệnh gọi dịch vụ web.
Trong bất kỳ lập trình nào, luôn có yêu cầu về xử lý lỗi. Lỗi có thể có hai loại bao gồm,
- Lỗi cú pháp
- Lỗi thời gian chạy
Lỗi cú pháp
Lỗi cú pháp xảy ra do sử dụng không đúng các thành phần chương trình khác nhau như toán tử và biểu thức. Một ví dụ đơn giản cho lỗi cú pháp được hiển thị bên dưới.
a == 2
Như bạn đã biết, có một sự khác biệt giữa việc sử dụng đơn "bằng với" và kép "bằng với". Sử dụng cái này thay vì cái kia có thể dẫn đến lỗi. Một "bằng với" đề cập đến sự phân công trong khi một "bằng với" đôi đề cập đến sự so sánh. Tương tự, chúng ta có các biểu thức và hàm có các cách triển khai được xác định trước.
Một ví dụ khác cho lỗi cú pháp được hiển thị bên dưới:
for a= 1,10
print(a)
end
Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau:
lua: test2.lua:2: 'do' expected near 'print'
Lỗi cú pháp dễ xử lý hơn nhiều so với lỗi thời gian chạy vì trình thông dịch Lua định vị lỗi rõ ràng hơn so với trường hợp lỗi thời gian chạy. Từ lỗi trên, chúng ta có thể biết một cách dễ dàng rằng việc thêm một việc phải làm tuyên bố trước khi tuyên bố in được yêu cầu theo cấu trúc Lua.
Lỗi thời gian chạy
Trong trường hợp lỗi thời gian chạy, chương trình thực thi thành công, nhưng nó có thể dẫn đến lỗi thời gian chạy do lỗi nhập hoặc xử lý sai chức năng. Dưới đây là một ví dụ đơn giản để hiển thị lỗi thời gian chạy.
function add(a,b)
return a+b
end
add(10)
Khi chúng tôi xây dựng chương trình, nó sẽ xây dựng thành công và chạy. Khi nó chạy, hiển thị lỗi thời gian chạy.
lua: test2.lua:2: attempt to perform arithmetic on local 'b' (a nil value)
stack traceback:
test2.lua:2: in function 'add'
test2.lua:5: in main chunk
[C]: ?
Đây là lỗi thời gian chạy, đã xảy ra do không chuyển hai biến. Cácb tham số được mong đợi và ở đây nó là nil và tạo ra lỗi.
Chức năng Khẳng định và Lỗi
Để xử lý lỗi, chúng tôi thường sử dụng hai hàm: assert và error. Một ví dụ đơn giản được hiển thị bên dưới.
local function add(a,b)
assert(type(a) == "number", "a is not a number")
assert(type(b) == "number", "b is not a number")
return a+b
end
add(10)
Khi chúng tôi chạy chương trình trên, chúng tôi sẽ nhận được đầu ra lỗi sau.
lua: test2.lua:3: b is not a number
stack traceback:
[C]: in function 'assert'
test2.lua:3: in function 'add'
test2.lua:6: in main chunk
[C]: ?
Các error (message [, level])chấm dứt chức năng được bảo vệ cuối cùng được gọi và trả về thông báo dưới dạng thông báo lỗi. Lỗi hàm này không bao giờ trả về. Thông thường, lỗi thêm một số thông tin về vị trí lỗi ở đầu thư. Đối số mức chỉ định cách lấy vị trí lỗi. Với mức 1 (mặc định), vị trí lỗi là nơi hàm lỗi được gọi. Mức 2 chỉ lỗi đến nơi mà hàm được gọi là lỗi đã được gọi; và như thế. Vượt qua mức 0 sẽ tránh được việc thêm thông tin vị trí lỗi vào thông báo.
pcall và xpcall
Trong lập trình Lua, để tránh ném ra các lỗi này và xử lý lỗi, chúng ta cần sử dụng các hàm pcall hoặc xpcall.
Các pcall (f, arg1, ...)hàm gọi hàm được yêu cầu ở chế độ được bảo vệ. Nếu một số lỗi xảy ra trong hàm f, nó không tạo ra lỗi. Nó chỉ trả về trạng thái lỗi. Một ví dụ đơn giản bằng cách sử dụng pcall được hiển thị bên dưới.
function myfunction ()
n = n/nil
end
if pcall(myfunction) then
print("Success")
else
print("Failure")
end
Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau.
Failure
Các xpcall (f, err)hàm gọi hàm được yêu cầu và cũng đặt trình xử lý lỗi. Bất kỳ lỗi nào bên trong f không được lan truyền; thay vào đó, xpcall bắt lỗi, gọi hàm err với đối tượng lỗi ban đầu và trả về mã trạng thái.
Một ví dụ đơn giản cho xpcall được hiển thị bên dưới.
function myfunction ()
n = n/nil
end
function myerrorhandler( err )
print( "ERROR:", err )
end
status = xpcall( myfunction, myerrorhandler )
print( status)
Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau.
ERROR: test2.lua:2: attempt to perform arithmetic on global 'n' (a nil value)
false
Là một lập trình viên, điều quan trọng nhất là đảm bảo rằng bạn quan tâm đến việc xử lý lỗi thích hợp trong các chương trình bạn viết. Sử dụng xử lý lỗi có thể đảm bảo rằng các điều kiện bất ngờ ngoài điều kiện biên được xử lý mà không làm phiền người dùng chương trình.
Lua cung cấp một thư viện gỡ lỗi, cung cấp tất cả các hàm nguyên thủy để chúng ta tạo trình gỡ lỗi của riêng mình. Mặc dù không có trình gỡ lỗi Lua tích hợp sẵn, chúng tôi có nhiều trình gỡ lỗi cho Lua, được tạo bởi nhiều nhà phát triển khác nhau với nhiều người là mã nguồn mở.
Các hàm có sẵn trong thư viện gỡ lỗi Lua được liệt kê trong bảng sau cùng với cách sử dụng của nó.
Sr.No. | Phương pháp & Mục đích |
---|---|
1 | debug() Vào chế độ tương tác để gỡ lỗi, chế độ này vẫn hoạt động cho đến khi chúng tôi nhập chỉ cont trong một dòng và nhấn enter. Người dùng có thể kiểm tra các biến trong chế độ này bằng các hàm khác. |
2 | getfenv(object) Trả về môi trường của đối tượng. |
3 | gethook(optional thread) Trả về cài đặt móc hiện tại của luồng, dưới dạng ba giá trị - chức năng móc hiện tại, mặt nạ móc hiện tại và số móc hiện tại. |
4 | getinfo(optional thread, function or stack level, optional flag) Trả về một bảng với thông tin về một hàm. Bạn có thể cung cấp hàm trực tiếp hoặc bạn có thể cung cấp một số làm giá trị của hàm, có nghĩa là hàm đang chạy ở hàm cấp của ngăn xếp cuộc gọi của luồng đã cho - cấp 0 là hàm hiện tại (chính là getinfo); mức 1 là chức năng được gọi là getinfo; và như thế. Nếu hàm là một số lớn hơn số hàm đang hoạt động, thì getinfo trả về nil. |
5 | getlocal(optional thread, stack level, local index) Trả về tên và giá trị của biến cục bộ có chỉ mục cục bộ của hàm ở cấp độ ngăn xếp. Trả về giá trị nil nếu không có biến cục bộ nào với chỉ mục đã cho và phát sinh lỗi khi được gọi với cấp nằm ngoài phạm vi. |
6 | getmetatable(value) Trả về đối tượng có thể đo được hoặc nil đã cho nếu đối tượng đó không có đối tượng có thể đo được. |
7 | getregistry() Trả về bảng đăng ký, một bảng được xác định trước có thể được sử dụng bởi bất kỳ mã C nào để lưu trữ bất kỳ giá trị Lua nào mà nó cần để lưu trữ. |
số 8 | getupvalue(function, upvalue index) Hàm này trả về tên và giá trị của giá trị tăng lên với chỉ mục của hàm func. Hàm trả về nil nếu không có giá trị tăng với chỉ số đã cho. |
9 | setfenv(function or thread or userdata, environment table) Đặt môi trường của đối tượng đã cho vào bảng đã cho. Trả về đối tượng. |
10 | sethook(optional thread, hook function, hook mask string with "c" and/or "r" and/or "l", optional instruction count) Đặt hàm đã cho dưới dạng móc câu. Mặt nạ chuỗi và số đếm mô tả khi nào hook sẽ được gọi. Ở đây, c, r và l được gọi mỗi khi Lua gọi, trả về và nhập vào mỗi dòng mã trong một hàm tương ứng. |
11 | setlocal(optional thread, stack level, local index, value) Gán giá trị cho biến cục bộ với chỉ mục cục bộ của hàm ở mức ngăn xếp. Hàm trả về nil nếu không có biến cục bộ với chỉ số đã cho và gây ra lỗi khi được gọi với mức nằm ngoài phạm vi. Nếu không, nó trả về tên của biến cục bộ. |
12 | setmetatable(value, metatable) Đặt khả năng đáp ứng cho đối tượng đã cho vào bảng đã cho (có thể là nil). |
13 | setupvalue(function, upvalue index, value) Hàm này gán giá trị cho giá trị tăng với chỉ mục của hàm func. Hàm trả về nil nếu không có giá trị tăng với chỉ số đã cho. Nếu không, nó trả về tên của giá trị tăng. |
14 | traceback(optional thread, optional message string, optional level argument) Tạo thông báo lỗi mở rộng với tính năng theo dõi. |
Danh sách trên là danh sách đầy đủ các hàm gỡ lỗi trong Lua và chúng tôi thường sử dụng một thư viện sử dụng các hàm trên và cung cấp việc gỡ lỗi dễ dàng hơn. Việc sử dụng các chức năng này và tạo trình gỡ lỗi của riêng chúng tôi khá phức tạp và không được ưa chuộng. Dù sao, chúng ta sẽ thấy một ví dụ về việc sử dụng đơn giản các hàm gỡ lỗi.
function myfunction ()
print(debug.traceback("Stack trace"))
print(debug.getinfo(1))
print("Stack trace end")
return 10
end
myfunction ()
print(debug.getinfo(1))
Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được dấu vết ngăn xếp như hình dưới đây.
Stack trace
stack traceback:
test2.lua:2: in function 'myfunction'
test2.lua:8: in main chunk
[C]: ?
table: 0054C6C8
Stack trace end
Trong chương trình mẫu trên, dấu vết ngăn xếp được in bằng cách sử dụng hàm debug.trace có sẵn trong thư viện gỡ lỗi. Debug.getinfo lấy bảng hiện tại của hàm.
Gỡ lỗi - Ví dụ
Chúng ta thường cần biết các biến cục bộ của một hàm để gỡ lỗi. Với mục đích đó, chúng ta có thể sử dụng getupvalue và để đặt các biến cục bộ này, chúng ta sử dụng setupvalue. Một ví dụ đơn giản cho điều này được hiển thị bên dưới.
function newCounter ()
local n = 0
local k = 0
return function ()
k = n
n = n + 1
return n
end
end
counter = newCounter ()
print(counter())
print(counter())
local i = 1
repeat
name, val = debug.getupvalue(counter, i)
if name then
print ("index", i, name, "=", val)
if(name == "n") then
debug.setupvalue (counter,2,10)
end
i = i + 1
end -- if
until not name
print(counter())
Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau.
1
2
index 1 k = 1
index 2 n = 2
11
Trong ví dụ này, bộ đếm cập nhật từng cái một khi nó được gọi. Chúng ta có thể thấy trạng thái hiện tại của biến cục bộ bằng cách sử dụng hàm getupvalue. Sau đó, chúng tôi đặt biến cục bộ thành một giá trị mới. Ở đây, n là 2 trước khi hoạt động tập hợp được gọi. Sử dụng hàm setupvalue, nó được cập nhật lên 10. Bây giờ khi chúng ta gọi hàm counter, nó sẽ trả về 11 thay vì 3.
Các loại gỡ lỗi
- Gỡ lỗi dòng lệnh
- Gỡ lỗi đồ họa
Gỡ lỗi dòng lệnh
Gỡ lỗi dòng lệnh là loại gỡ lỗi sử dụng dòng lệnh để gỡ lỗi với sự trợ giúp của các lệnh và câu lệnh in. Có nhiều trình gỡ lỗi dòng lệnh có sẵn cho Lua, trong đó có một số trình gỡ rối được liệt kê bên dưới.
RemDebug- RemDebug là trình gỡ lỗi từ xa cho Lua 5.0 và 5.1. Nó cho phép bạn kiểm soát việc thực thi một chương trình Lua khác từ xa, thiết lập các điểm ngắt và kiểm tra trạng thái hiện tại của chương trình. RemDebug cũng có thể gỡ lỗi các tập lệnh CGILua.
clidebugger- Trình gỡ lỗi giao diện dòng lệnh đơn giản cho Lua 5.1 được viết bằng Lua thuần túy. Nó không phụ thuộc vào bất kỳ thứ gì khác ngoài thư viện Lua 5.1 tiêu chuẩn. Nó được lấy cảm hứng từ RemDebug nhưng không có cơ sở vật chất từ xa.
ctrace - Một công cụ để theo dõi các lệnh gọi Lua API.
xdbLua - Trình gỡ lỗi dòng lệnh Lua đơn giản cho nền tảng Windows.
LuaInterface - Debugger- Dự án này là một phần mở rộng trình gỡ lỗi cho LuaInterface. Nó nâng giao diện gỡ lỗi được xây dựng trong Lua lên một cấp độ cao hơn. Tương tác với trình gỡ lỗi được thực hiện bởi các sự kiện và lời gọi phương thức.
Rldb- Đây là trình gỡ lỗi Lua từ xa thông qua socket, khả dụng trên cả Windows và Linux. Nó có thể cung cấp cho bạn nhiều tính năng hơn bất kỳ tính năng nào hiện có.
ModDebug - Điều này cho phép kiểm soát việc thực thi một chương trình Lua khác từ xa, thiết lập các điểm ngắt và kiểm tra trạng thái hiện tại của chương trình.
Gỡ lỗi đồ họa
Gỡ lỗi đồ họa có sẵn với sự trợ giúp của IDE nơi bạn được cung cấp gỡ lỗi trực quan về các trạng thái khác nhau như giá trị biến, dấu vết ngăn xếp và thông tin liên quan khác. Có một trình diễn trực quan và kiểm soát từng bước việc thực thi với sự trợ giúp của các điểm ngắt, bước vào, bước qua và các nút khác trong IDE.
Có một số trình gỡ lỗi đồ họa cho Lua và nó bao gồm những điều sau đây.
SciTE - Windows IDE mặc định cho Lua cung cấp nhiều tiện ích gỡ lỗi như điểm ngắt, bước, bước vào, bước qua, xem các biến, v.v.
Decoda - Đây là một trình gỡ lỗi đồ họa với hỗ trợ gỡ lỗi từ xa.
ZeroBrane Studio- Lua IDE với trình gỡ lỗi từ xa tích hợp, chế độ xem ngăn xếp, chế độ xem đồng hồ, bảng điều khiển từ xa, bộ phân tích tĩnh và hơn thế nữa. Hoạt động với LuaJIT, Love2d, Moai và các động cơ Lua khác; Windows, OSX và Linux. Mã nguồn mở.
akdebugger - Trình gỡ lỗi và trình chỉnh sửa Lua plugin cho Eclipse.
luaedit - Tính năng này có tính năng gỡ lỗi từ xa, gỡ lỗi cục bộ, đánh dấu cú pháp, danh sách đề xuất hoàn thành, công cụ đề xuất tham số, quản lý điểm ngắt trước (bao gồm hệ thống điều kiện về điểm ngắt và số lần truy cập), danh sách chức năng, danh sách biến toàn cục và cục bộ, đồng hồ, quản lý theo hướng giải pháp.
Lua sử dụng quản lý bộ nhớ tự động sử dụng tính năng thu gom rác dựa trên một số thuật toán nhất định được tích hợp sẵn trong Lua. Là kết quả của quản lý bộ nhớ tự động, với tư cách là nhà phát triển -
- Không cần phải lo lắng về việc cấp phát bộ nhớ cho các đối tượng.
- Không cần phải giải phóng chúng khi không còn cần thiết ngoại trừ việc đặt nó thành nil.
Lua sử dụng một bộ thu gom rác chạy theo thời gian để thu thập các đối tượng đã chết khi chúng không thể truy cập được nữa từ chương trình Lua.
Tất cả các đối tượng bao gồm bảng, dữ liệu người dùng, chức năng, luồng, chuỗi, v.v. phải chịu sự quản lý bộ nhớ tự động. Lua sử dụng bộ thu gom đánh dấu và quét tăng dần sử dụng hai số để kiểm soát các chu kỳ thu gom rác của nó, cụ thể làgarbage collector pause và garbage collector step multiplier. Các giá trị này tính theo phần trăm và giá trị 100 thường bằng 1 trong nội bộ.
Công cụ thu gom rác tạm dừng
Tính năng tạm dừng của người thu gom rác được sử dụng để kiểm soát thời gian người thu gom rác cần chờ trước đó; nó được gọi lại bởi quản lý bộ nhớ tự động của Lua. Giá trị nhỏ hơn 100 có nghĩa là Lua sẽ không đợi chu kỳ tiếp theo. Tương tự, các giá trị cao hơn của giá trị này sẽ dẫn đến việc bộ thu gom rác chậm và kém tích cực hơn trong tự nhiên. Giá trị 200, nghĩa là bộ thu sẽ đợi tổng bộ nhớ đang sử dụng tăng gấp đôi trước khi bắt đầu một chu kỳ mới. Do đó, tùy thuộc vào bản chất và tốc độ của ứng dụng, có thể có yêu cầu thay đổi giá trị này để có được hiệu suất tốt nhất trong các ứng dụng Lua.
Hệ số nhân bước của bộ thu gom rác
Hệ số nhân bước này kiểm soát tốc độ tương đối của bộ thu gom rác với tốc độ phân bổ bộ nhớ trong chương trình Lua. Giá trị bước lớn hơn sẽ dẫn đến việc thu gom rác hoạt động mạnh hơn và nó cũng làm tăng kích thước bước của mỗi bước thu gom rác gia tăng. Các giá trị nhỏ hơn 100 thường có thể dẫn đến việc bộ thu gom rác không hoàn thành chu trình của nó và thường không được ưa thích. Giá trị mặc định là 200, có nghĩa là bộ thu gom rác chạy gấp đôi tốc độ cấp phát bộ nhớ.
Chức năng của bộ thu gom rác
Là nhà phát triển, chúng tôi có một số quyền kiểm soát việc quản lý bộ nhớ tự động trong Lua. Đối với điều này, chúng tôi có các phương pháp sau.
collectgarbage("collect") - Chạy một chu kỳ thu gom rác hoàn chỉnh.
collectgarbage("count") - Trả về dung lượng bộ nhớ hiện đang được chương trình sử dụng tính bằng Kilobyte.
collectgarbage("restart") - Nếu bộ thu gom rác đã bị dừng, nó sẽ khởi động lại.
collectgarbage("setpause")- Đặt giá trị đã cho dưới dạng tham số thứ hai chia cho 100 cho biến tạm dừng của bộ thu gom rác. Công dụng của nó như đã thảo luận ở trên.
collectgarbage("setstepmul")- Đặt giá trị đã cho dưới dạng tham số thứ hai chia cho 100 cho biến số nhân bước rác. Công dụng của nó như đã thảo luận ở trên.
collectgarbage("step")- Chạy một bước thu gom rác. Đối số thứ hai càng lớn thì bước này sẽ càng lớn. Thu gom rác sẽ trả về true nếu bước được kích hoạt là bước cuối cùng của chu trình thu gom rác.
collectgarbage("stop") - Dừng bộ thu gom rác nếu nó đang chạy.
Dưới đây là một ví dụ đơn giản sử dụng ví dụ về bộ thu gom rác.
mytable = {"apple", "orange", "banana"}
print(collectgarbage("count"))
mytable = nil
print(collectgarbage("count"))
print(collectgarbage("collect"))
print(collectgarbage("count"))
Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau. Xin lưu ý rằng kết quả này sẽ thay đổi do sự khác biệt về loại hệ điều hành và tính năng quản lý bộ nhớ tự động của Lua.
23.1455078125 149
23.2880859375 295
0
22.37109375 380
Bạn có thể thấy trong chương trình trên, một khi thu dọn rác được thực hiện, nó sẽ làm giảm bộ nhớ được sử dụng. Nhưng, nó không bắt buộc phải gọi này. Ngay cả khi chúng ta không gọi chúng, nó sẽ được thực thi tự động ở giai đoạn sau bởi trình thông dịch Lua sau khoảng thời gian được xác định trước.
Rõ ràng, chúng ta có thể thay đổi hành vi của bộ thu gom rác bằng cách sử dụng các chức năng này nếu được yêu cầu. Các chức năng này cung cấp một chút khả năng bổ sung cho nhà phát triển để xử lý các tình huống phức tạp. Tùy thuộc vào loại bộ nhớ cần cho chương trình, bạn có thể sử dụng hoặc không sử dụng tính năng này. Nhưng rất hữu ích khi biết mức sử dụng bộ nhớ trong các ứng dụng và kiểm tra nó trong quá trình lập trình để tránh kết quả không mong muốn sau khi triển khai.
Giới thiệu về OOP
Lập trình hướng đối tượng (OOP), là một kỹ thuật lập trình được sử dụng nhiều nhất được sử dụng trong kỷ nguyên lập trình hiện đại. Có một số ngôn ngữ lập trình hỗ trợ OOP bao gồm,
- C++
- Java
- Objective-C
- Smalltalk
- C#
- Ruby
Đặc điểm của OOP
Class - Một lớp là một khuôn mẫu có thể mở rộng để tạo các đối tượng, cung cấp các giá trị ban đầu cho trạng thái (các biến thành viên) và các thực thi của hành vi.
Objects - Nó là một thể hiện của lớp và có bộ nhớ riêng được cấp phát cho chính nó.
Inheritance - Là một khái niệm mà các biến và hàm của một lớp này được kế thừa bởi một lớp khác.
Encapsulation- Là quá trình kết hợp dữ liệu và các hàm bên trong một lớp. Dữ liệu có thể được truy cập bên ngoài lớp với sự trợ giúp của các hàm. Nó còn được gọi là trừu tượng hóa dữ liệu.
OOP trong Lua
Bạn có thể triển khai hướng đối tượng trong Lua với sự trợ giúp của bảng và các hàm lớp đầu tiên của Lua. Bằng cách đặt các chức năng và dữ liệu liên quan vào một bảng, một đối tượng được hình thành. Kế thừa có thể được thực hiện với sự trợ giúp của các bảng đo lường, cung cấp cơ chế tra cứu các hàm (phương thức) và trường không tồn tại trong (các) đối tượng mẹ.
Các bảng trong Lua có các tính năng của đối tượng như trạng thái và danh tính độc lập với các giá trị của nó. Hai đối tượng (bảng) có cùng giá trị là các đối tượng khác nhau, ngược lại một đối tượng có thể có giá trị khác nhau tại các thời điểm khác nhau, nhưng nó luôn là cùng một đối tượng. Giống như các đối tượng, bảng có vòng đời độc lập với việc ai tạo ra chúng hoặc nơi chúng được tạo.
Một ví dụ về thế giới thực
Khái niệm hướng đối tượng được sử dụng rộng rãi nhưng bạn cần hiểu rõ về nó để đạt được lợi ích tối đa và phù hợp.
Chúng ta hãy xem xét một ví dụ toán học đơn giản. Chúng ta thường gặp những trường hợp chúng ta làm việc trên các hình dạng khác nhau như hình tròn, hình chữ nhật và hình vuông.
Các hình dạng có thể có một Khu vực thuộc tính chung. Vì vậy, chúng ta có thể mở rộng các hình dạng khác từ hình dạng đối tượng cơ sở với vùng thuộc tính chung. Mỗi hình dạng có thể có các thuộc tính và chức năng riêng của nó như một hình chữ nhật có thể có các thuộc tính chiều dài, chiều rộng, diện tích là thuộc tính của nó và printArea và mathArea là các hàm của nó.
Tạo một lớp học đơn giản
Cách triển khai lớp đơn giản cho một hình chữ nhật có ba thuộc tính diện tích, chiều dài và chiều rộng được hiển thị bên dưới. Nó cũng có chức năng printArea để in diện tích được tính toán.
-- Meta class
Rectangle = {area = 0, length = 0, breadth = 0}
-- Derived class method new
function Rectangle:new (o,length,breadth)
o = o or {}
setmetatable(o, self)
self.__index = self
self.length = length or 0
self.breadth = breadth or 0
self.area = length*breadth;
return o
end
-- Derived class method printArea
function Rectangle:printArea ()
print("The area of Rectangle is ",self.area)
end
Tạo một đối tượng
Tạo một đối tượng là quá trình cấp phát bộ nhớ cho cá thể lớp. Mỗi đối tượng có bộ nhớ riêng và chia sẻ dữ liệu lớp chung.
r = Rectangle:new(nil,10,20)
Truy cập thuộc tính
Chúng ta có thể truy cập các thuộc tính trong lớp bằng toán tử dấu chấm như hình dưới đây:
print(r.length)
Truy cập chức năng thành viên
Bạn có thể truy cập một hàm thành viên bằng cách sử dụng toán tử dấu hai chấm với đối tượng như hình dưới đây:
r:printArea()
Bộ nhớ được cấp phát và các giá trị ban đầu được đặt. Quá trình khởi tạo có thể được so sánh với các hàm tạo trong các ngôn ngữ hướng đối tượng khác. Nó không là gì ngoài một chức năng cho phép thiết lập các giá trị như hình trên.
Hoàn thành ví dụ
Hãy xem một ví dụ hoàn chỉnh bằng cách sử dụng hướng đối tượng trong Lua.
-- Meta class
Shape = {area = 0}
-- Base class method new
function Shape:new (o,side)
o = o or {}
setmetatable(o, self)
self.__index = self
side = side or 0
self.area = side*side;
return o
end
-- Base class method printArea
function Shape:printArea ()
print("The area is ",self.area)
end
-- Creating an object
myshape = Shape:new(nil,10)
myshape:printArea()
Khi bạn chạy chương trình trên, bạn sẽ nhận được kết quả sau.
The area is 100
Thừa kế trong Lua
Kế thừa là quá trình mở rộng các đối tượng cơ sở đơn giản như hình dạng thành hình chữ nhật, hình vuông, v.v. Nó thường được sử dụng trong thế giới thực để chia sẻ và mở rộng các thuộc tính và chức năng cơ bản.
Hãy cho chúng tôi xem một phần mở rộng lớp đơn giản. Chúng tôi có một lớp như hình dưới đây.
-- Meta class
Shape = {area = 0}
-- Base class method new
function Shape:new (o,side)
o = o or {}
setmetatable(o, self)
self.__index = self
side = side or 0
self.area = side*side;
return o
end
-- Base class method printArea
function Shape:printArea ()
print("The area is ",self.area)
end
Chúng ta có thể mở rộng hình dạng thành một lớp vuông như hình dưới đây.
Square = Shape:new()
-- Derived class method new
function Square:new (o,side)
o = o or Shape:new(o,side)
setmetatable(o, self)
self.__index = self
return o
end
Các chức năng cơ sở vượt trội
Chúng ta có thể ghi đè các hàm của lớp cơ sở thay vì sử dụng hàm trong lớp cơ sở, lớp dẫn xuất có thể có triển khai riêng của nó như được hiển thị bên dưới:
-- Derived class method printArea
function Square:printArea ()
print("The area of square is ",self.area)
end
Ví dụ hoàn chỉnh về thừa kế
Chúng ta có thể mở rộng việc triển khai lớp đơn giản trong Lua như được hiển thị ở trên với sự trợ giúp của một phương thức mới khác với sự trợ giúp của các bảng đo lường. Tất cả các biến thành viên và hàm của lớp cơ sở được giữ lại trong lớp dẫn xuất.
-- Meta class
Shape = {area = 0}
-- Base class method new
function Shape:new (o,side)
o = o or {}
setmetatable(o, self)
self.__index = self
side = side or 0
self.area = side*side;
return o
end
-- Base class method printArea
function Shape:printArea ()
print("The area is ",self.area)
end
-- Creating an object
myshape = Shape:new(nil,10)
myshape:printArea()
Square = Shape:new()
-- Derived class method new
function Square:new (o,side)
o = o or Shape:new(o,side)
setmetatable(o, self)
self.__index = self
return o
end
-- Derived class method printArea
function Square:printArea ()
print("The area of square is ",self.area)
end
-- Creating an object
mysquare = Square:new(nil,10)
mysquare:printArea()
Rectangle = Shape:new()
-- Derived class method new
function Rectangle:new (o,length,breadth)
o = o or Shape:new(o)
setmetatable(o, self)
self.__index = self
self.area = length * breadth
return o
end
-- Derived class method printArea
function Rectangle:printArea ()
print("The area of Rectangle is ",self.area)
end
-- Creating an object
myrectangle = Rectangle:new(nil,10,20)
myrectangle:printArea()
Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau:
The area is 100
The area of square is 100
The area of Rectangle is 200
Trong ví dụ trên, chúng ta đã tạo hai lớp dẫn xuất - Rectangle và Square từ Square của lớp cơ sở. Có thể ghi đè các chức năng của lớp cơ sở trong lớp dẫn xuất. Trong ví dụ này, lớp dẫn xuất ghi đè hàm printArea.
Lua là một ngôn ngữ rất linh hoạt và nó thường được sử dụng trên nhiều nền tảng bao gồm cả các ứng dụng web. Cộng đồng Kepler được thành lập vào năm 2004 để cung cấp các thành phần web mã nguồn mở trong Lua.
Mặc dù có những web framework khác sử dụng Lua đã được phát triển, chúng tôi sẽ chủ yếu tập trung vào các thành phần do cộng đồng Kepler cung cấp.
Ứng dụng và Khung công tác
Orbit là một khung công tác web MVC cho Lua, dựa trên WSAPI.
WSAPI là API tóm tắt máy chủ lưu trữ web từ các ứng dụng web Lua và là cơ sở cho nhiều dự án.
Xavante là một máy chủ Web Lua cung cấp giao diện WSAPI.
Sputnik là một wiki / CMS được phát triển qua WSAPI trên Dự án Kepler được sử dụng để hài hước và giải trí.
CGILuacung cấp tính năng tạo trang web LuaPages và LuaScripts, dựa trên WSAPI nhưng không còn được hỗ trợ. Thay vào đó, hãy sử dụng Orbit, Sputnik hoặc WSAPI.
Trong hướng dẫn này, chúng tôi sẽ cố gắng làm cho bạn hiểu những gì Lua có thể làm và để biết thêm về cách cài đặt và sử dụng nó, hãy tham khảo trang web kepler
Quỹ đạo
Orbit là một khung công tác web MVC cho Lua. Nó hoàn toàn từ bỏ mô hình "tập lệnh" CGILua để ủng hộ các ứng dụng, trong đó mỗi ứng dụng Orbit có thể nằm gọn trong một tệp duy nhất, nhưng bạn có thể chia nó thành nhiều tệp nếu muốn.
Tất cả các ứng dụng Orbit đều tuân theo giao thức WSAPI, vì vậy chúng hiện đang hoạt động với Xavante, CGI và Fastcgi. Nó bao gồm một trình khởi chạy giúp bạn dễ dàng khởi chạy phiên bản Xavante để phát triển.
Cách dễ nhất để cài đặt Orbit là sử dụng LuaRocks. Luarocks install quỹ đạo là lệnh cài đặt. Đối với điều này, bạn cần cài đặt LuaRocks trước.
Nếu bạn chưa cài đặt tất cả các phần phụ thuộc, đây là các bước cần làm để thiết lập Orbit trong môi trường Unix / Linux.
Cài đặt Apache
Kết nối với máy chủ của bạn. Cài đặt Apache2, các mô-đun hỗ trợ của nó và kích hoạt các mô-đun Apache2 bắt buộc bằng cách sử dụng -
$ sudo apt-get install apache2 libapache2-mod-fcgid libfcgi-dev build-essential $ sudo a2enmod rewrite
$ sudo a2enmod fcgid $ sudo /etc/init.d/apache2 force-reload
Cài đặt LuaRocks
$ sudo apt-get install luarocks
Cài đặt WSAPI, FCGI, Orbit và Xavante
$ sudo luarocks install orbit
$ sudo luarocks install wsapi-xavante $ sudo luarocks install wsapi-fcgi
Thiết lập Apache2
$ sudo raj /etc/apache2/sites-available/default
Thêm phần sau này bên dưới phần <Thư mục / var / www /> của tệp cấu hình. Nếu phần này có 'AllowOverride None' thì bạn cần thay đổi 'None' thành 'All' để tệp .htaccess có thể ghi đè cấu hình cục bộ.
<IfModule mod_fcgid.c>
AddHandler fcgid-script .lua
AddHandler fcgid-script .ws
AddHandler fcgid-script .op
FCGIWrapper "/usr/local/bin/wsapi.fcgi" .ws
FCGIWrapper "/usr/local/bin/wsapi.fcgi" .lua
FCGIWrapper "/usr/local/bin/op.fcgi" .op
#FCGIServer "/usr/local/bin/wsapi.fcgi" -idle-timeout 60 -processes 1
#IdleTimeout 60
#ProcessLifeTime 60
</IfModule>
Khởi động lại máy chủ để đảm bảo các thay đổi được thực hiện có hiệu lực.
Để kích hoạt ứng dụng của bạn, bạn cần thêm + ExecCGI vào tệp .htaccess trong thư mục gốc của ứng dụng Orbit - trong trường hợp này là / var / www.
Options +ExecCGI
DirectoryIndex index.ws
Ví dụ đơn giản - Quỹ đạo
#!/usr/bin/env index.lua
-- index.lua
require"orbit"
-- declaration
module("myorbit", package.seeall, orbit.new)
-- handler
function index(web)
return my_home_page()
end
-- dispatch
myorbit:dispatch_get(index, "/", "/index")
-- Sample page
function my_home_page()
return [[
<head></head>
<html>
<h2>First Page</h2>
</html>
]]
end
Bây giờ, bạn sẽ có thể khởi chạy trình duyệt web của mình. Truy cập http: // localhost: 8080 / và bạn sẽ thấy kết quả sau:
First Page
Orbit cung cấp một tùy chọn khác, tức là mã Lua có thể tạo ra html.
#!/usr/bin/env index.lua
-- index.lua
require"orbit"
function generate()
return html {
head{title "HTML Example"},
body{
h2{"Here we go again!"}
}
}
end
orbit.htmlify(generate)
print(generate())
Tạo biểu mẫu
Một ví dụ biểu mẫu đơn giản được hiển thị bên dưới:
#!/usr/bin/env index.lua
require"orbit"
function wrap (inner)
return html{ head(), body(inner) }
end
function test ()
return wrap(form (H'table' {
tr{td"First name",td( input{type = 'text', name='first'})},
tr{td"Second name",td(input{type = 'text', name='second'})},
tr{ td(input{type = 'submit', value = 'Submit!'}),
td(input{type = 'submit',value = 'Cancel'})
},
}))
end
orbit.htmlify(wrap,test)
print(test())
WSAPI
Như đã đề cập trước đó, WSAPI hoạt động như cơ sở cho nhiều dự án và có nhiều tính năng được nhúng trong đó. Bạn có thể sử dụng WSAPI và hỗ trợ các nền tảng sau,
- Windows
- Hệ thống dựa trên UNIX
Các máy chủ và giao diện được hỗ trợ bởi WSAPI bao gồm,
- CGI
- FastCGI
- Xavante
WSAPI cung cấp một số thư viện, giúp chúng tôi lập trình web dễ dàng hơn bằng Lua. Một số tính năng được hỗ trợ trong Lua bao gồm,
- Yêu cầu xử lý
- Bộ đệm đầu ra
- Authentication
- Tải lên tệp
- Yêu cầu cách ly
- Multiplexing
Dưới đây là một ví dụ đơn giản về WSAPI:
#!/usr/bin/env wsapi.cgi
module(..., package.seeall)
function run(wsapi_env)
local headers = { ["Content-type"] = "text/html" }
local function hello_text()
coroutine.yield("<html><body>")
coroutine.yield("<p>Hello Wsapi!</p>")
coroutine.yield("<p>PATH_INFO: " .. wsapi_env.PATH_INFO .. "</p>")
coroutine.yield("<p>SCRIPT_NAME: " .. wsapi_env.SCRIPT_NAME .. "</p>")
coroutine.yield("</body></html>")
end
return 200, headers, coroutine.wrap(hello_text)
end
Bạn có thể thấy trong đoạn mã trên, một trang html đơn giản được hình thành và trả về. Bạn có thể thấy việc sử dụng các coroutines để có thể trả về câu lệnh theo câu lệnh cho hàm gọi. Cuối cùng, mã trạng thái html (200), tiêu đề và trang html được trả về.
Xavante
Xavante là một máy chủ Web Lua HTTP 1.1 sử dụng kiến trúc mô-đun dựa trên các trình xử lý được ánh xạ URI. Xavante hiện đang cung cấp,
- Trình xử lý tệp
- Trình xử lý chuyển hướng
- Trình xử lý WSAPI
Trình xử lý tệp được sử dụng cho các tệp chung. Trình xử lý chuyển hướng cho phép ánh xạ lại URI và trình xử lý WSAPI để xử lý với các ứng dụng WSAPI.
Một ví dụ đơn giản được hiển thị bên dưới.
require "xavante.filehandler"
require "xavante.cgiluahandler"
require "xavante.redirecthandler"
-- Define here where Xavante HTTP documents scripts are located
local webDir = XAVANTE_WEB
local simplerules = {
{ -- URI remapping example
match = "^[^%./]*/$",
with = xavante.redirecthandler,
params = {"index.lp"}
},
{ -- cgiluahandler example
match = {"%.lp$", "%.lp/.*$", "%.lua$", "%.lua/.*$" },
with = xavante.cgiluahandler.makeHandler (webDir)
},
{ -- filehandler example
match = ".",
with = xavante.filehandler,
params = {baseDir = webDir}
},
}
xavante.HTTP{
server = {host = "*", port = 8080},
defaultHost = {
rules = simplerules
},
}
Để sử dụng máy chủ ảo với Xavante, lệnh gọi đến xavante.HTTP sẽ được thay đổi thành một cái gì đó như sau:
xavante.HTTP{
server = {host = "*", port = 8080},
defaultHost = {},
virtualhosts = {
["www.sitename.com"] = simplerules
}
}
Các thành phần web Lua
Copas, một bộ điều phối dựa trên các quy trình có thể được sử dụng bởi các máy chủ TCP / IP.
Cosmo, một công cụ "mẫu an toàn" bảo vệ ứng dụng của bạn khỏi mã tùy ý trong các mẫu.
Coxpcall đóng gói Lua native pcall và xpcall với những cái tương thích với coroutine.
LuaFileSystem, một cách di động để truy cập cấu trúc thư mục cơ bản và các thuộc tính tệp.
Rings, một thư viện cung cấp cách tạo các trạng thái Lua mới từ bên trong Lua.
Ghi chú kết thúc
Có rất nhiều khung và thành phần web dựa trên Lua có sẵn cho chúng tôi và dựa trên nhu cầu, nó có thể được lựa chọn. Có sẵn các khuôn khổ web khác bao gồm những điều sau:
Moonstalkcho phép phát triển và lưu trữ hiệu quả các dự án dựa trên web được tạo động được xây dựng bằng ngôn ngữ Lua; từ các trang cơ bản đến các ứng dụng phức tạp.
Lapis, một khuôn khổ để xây dựng các ứng dụng web sử dụng MoonScript (hoặc Lua) chạy bên trong một phiên bản tùy chỉnh của Nginx được gọi là OpenResty.
Lua Server Pages, một plug-in công cụ tạo kịch bản Lua giúp loại bỏ bất kỳ cách tiếp cận nào khác đối với phát triển web nhúng, mang lại một bước cắt ngắn ấn tượng cho các trang máy chủ C truyền thống.
Các khuôn khổ web này có thể thúc đẩy các ứng dụng web của bạn và giúp bạn thực hiện các hoạt động mạnh mẽ.
Đối với các hoạt động dữ liệu đơn giản, chúng tôi có thể sử dụng tệp, nhưng đôi khi, các hoạt động tệp này có thể không hiệu quả, không thể mở rộng và mạnh mẽ. Với mục đích này, chúng tôi có thể thường chuyển sang sử dụng cơ sở dữ liệu. LuaSQL là một giao diện đơn giản từ Lua đến một số hệ quản trị cơ sở dữ liệu. LuaSQL là thư viện, cung cấp hỗ trợ cho các loại SQL khác nhau. Điều này bao gồm,
- SQLite
- Mysql
- ODBC
Trong hướng dẫn này, chúng tôi sẽ đề cập đến việc xử lý cơ sở dữ liệu MySQL một SQLite trong Lua. Điều này sử dụng một giao diện chung cho cả hai và sẽ có thể chuyển việc triển khai này sang các loại cơ sở dữ liệu khác. Trước tiên, hãy xem cách bạn có thể thực hiện các hoạt động trong MySQL.
Thiết lập db MySQL
Để sử dụng các ví dụ sau hoạt động như mong đợi, chúng ta cần thiết lập db ban đầu. Các giả định được liệt kê dưới đây.
Bạn đã cài đặt và thiết lập MySQL với người dùng mặc định là root và mật khẩu là '123456'.
Bạn đã tạo một bài kiểm tra cơ sở dữ liệu.
Bạn đã xem qua hướng dẫn MySQL để hiểu Cơ bản về MySQL.
Nhập MySQL
Chúng ta có thể sử dụng một require để nhập thư viện sqlite giả sử rằng việc triển khai Lua của bạn đã được thực hiện đúng.
mysql = require "luasql.mysql"
Biến mysql sẽ cung cấp quyền truy cập vào các chức năng bằng cách tham chiếu đến bảng mysql chính.
Thiết lập kết nối
Chúng ta có thể thiết lập kết nối bằng cách khởi tạo môi trường MySQL và sau đó tạo kết nối cho môi trường. Nó được hiển thị bên dưới.
local env = mysql.mysql()
local conn = env:connect('test','root','123456')
Kết nối trên sẽ kết nối với tệp MySQL hiện có và thiết lập kết nối với tệp mới tạo.
Thực thi chức năng
Có một chức năng thực thi đơn giản có sẵn với kết nối sẽ giúp chúng ta thực hiện tất cả các thao tác db từ tạo, chèn, xóa, cập nhật, v.v. Cú pháp được hiển thị bên dưới -
conn:execute([[ 'MySQLSTATEMENT' ]])
Trong cú pháp trên, chúng ta cần đảm bảo rằng conn đang mở và kết nối MySQL hiện có và thay thế 'MySQLSTATEMENT' bằng câu lệnh chính xác.
Ví dụ về Tạo bảng
Dưới đây là một ví dụ tạo bảng đơn giản. Nó tạo một bảng với hai tham số id kiểu số nguyên và tên kiểu varchar.
mysql = require "luasql.mysql"
local env = mysql.mysql()
local conn = env:connect('test','root','123456')
print(env,conn)
status,errorString = conn:execute([[CREATE TABLE sample2 (id INTEGER, name TEXT);]])
print(status,errorString )
Khi bạn chạy chương trình trên, một bảng có tên sample sẽ được tạo với hai cột là id và name.
MySQL environment (004BB178) MySQL connection (004BE3C8)
0 nil
Trong trường hợp có bất kỳ lỗi nào, bạn sẽ được trả về một câu lệnh lỗi thay vì nil. Một báo cáo lỗi đơn giản được hiển thị bên dưới.
LuaSQL: Error executing query. MySQL: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '"id INTEGER, name TEXT)' at line 1
Chèn ví dụ câu lệnh
Một câu lệnh chèn cho MySQL được hiển thị bên dưới.
conn:execute([[INSERT INTO sample values('11','Raj')]])
Ví dụ về câu lệnh cập nhật
Một câu lệnh cập nhật cho MySQL được hiển thị bên dưới.
conn:execute([[UPDATE sample3 SET name='John' where id ='12']])
Ví dụ về Xóa câu lệnh
Một câu lệnh xóa cho MySQL được hiển thị bên dưới.
conn:execute([[DELETE from sample3 where id ='12']])
Chọn ví dụ về câu lệnh
Đối với câu lệnh select, chúng ta cần lặp qua từng hàng và trích xuất dữ liệu cần thiết. Một câu lệnh chọn đơn giản được hiển thị bên dưới.
cursor,errorString = conn:execute([[select * from sample]])
row = cursor:fetch ({}, "a")
while row do
print(string.format("Id: %s, Name: %s", row.id, row.name))
-- reusing the table of results
row = cursor:fetch (row, "a")
end
Trong đoạn mã trên, conn là một kết nối MySQL mở. Với sự trợ giúp của con trỏ được trả về bởi câu lệnh thực thi, bạn có thể lặp qua phản hồi bảng và tìm nạp dữ liệu chọn được yêu cầu.
Một ví dụ hoàn chỉnh
Dưới đây là một ví dụ đầy đủ bao gồm tất cả các câu trên.
mysql = require "luasql.mysql"
local env = mysql.mysql()
local conn = env:connect('test','root','123456')
print(env,conn)
status,errorString = conn:execute([[CREATE TABLE sample3 (id INTEGER, name TEXT)]])
print(status,errorString )
status,errorString = conn:execute([[INSERT INTO sample3 values('12','Raj')]])
print(status,errorString )
cursor,errorString = conn:execute([[select * from sample3]])
print(cursor,errorString)
row = cursor:fetch ({}, "a")
while row do
print(string.format("Id: %s, Name: %s", row.id, row.name))
row = cursor:fetch (row, "a")
end
-- close everything
cursor:close()
conn:close()
env:close()
Khi bạn chạy chương trình trên, bạn sẽ nhận được kết quả sau.
MySQL environment (0037B178) MySQL connection (0037EBA8)
0 nil
1 nil
MySQL cursor (003778A8) nil
Id: 12, Name: Raj
Thực hiện giao dịch
Giao dịch là một cơ chế đảm bảo tính nhất quán của dữ liệu. Các giao dịch phải có bốn thuộc tính sau:
Atomicity - Một giao dịch hoàn tất hoặc không có gì xảy ra cả.
Consistency - Một giao dịch phải bắt đầu ở trạng thái nhất quán và để hệ thống ở trạng thái nhất quán.
Isolation - Kết quả trung gian của một giao dịch không được hiển thị bên ngoài giao dịch hiện tại.
Durability - Một khi giao dịch đã được cam kết, các ảnh hưởng vẫn tồn tại, ngay cả sau khi hệ thống bị lỗi.
Giao dịch bắt đầu bằng BẮT ĐẦU GIAO DỊCH; và kết thúc bằng câu lệnh commit hoặc rollback.
Bắt đầu giao dịch
Để bắt đầu một giao dịch, chúng ta cần thực hiện câu lệnh sau trong Lua, giả sử conn là một kết nối MySQL mở.
conn:execute([[START TRANSACTION;]])
Giao dịch khôi phục
Chúng ta cần thực hiện câu lệnh sau để khôi phục các thay đổi được thực hiện sau khi bắt đầu giao dịch được thực hiện.
conn:execute([[ROLLBACK;]])
Giao dịch cam kết
Chúng ta cần thực hiện câu lệnh sau để cam kết các thay đổi được thực hiện sau khi giao dịch bắt đầu được thực hiện.
conn:execute([[COMMIT;]])
Chúng ta đã biết về MySQL trong phần trên và phần sau giải thích về các phép toán SQL cơ bản. Hãy nhớ các giao dịch, mặc dù không được giải thích lại cho SQLite3 nhưng các câu lệnh tương tự cũng sẽ hoạt động cho SQLite3.
Nhập SQLite
Chúng ta có thể sử dụng một câu lệnh request đơn giản để nhập thư viện SQLite với giả định rằng việc triển khai Lua của bạn đã được thực hiện đúng. Trong khi cài đặt, một thư mục libsql chứa các tệp liên quan đến cơ sở dữ liệu.
sqlite3 = require "luasql.sqlite3"
Biến sqlite3 sẽ cung cấp quyền truy cập vào các chức năng bằng cách tham chiếu đến bảng sqlite3 chính.
Thiết lập kết nối
Chúng ta có thể thiết lập kết nối bằng cách khởi tạo môi trường SQLite và sau đó tạo kết nối cho môi trường. Nó được hiển thị bên dưới.
local env = sqlite3.sqlite3()
local conn = env:connect('mydb.sqlite')
Kết nối trên sẽ kết nối với tệp SQLite hiện có hoặc tạo tệp SQLite mới và thiết lập kết nối với tệp mới tạo.
Thực thi chức năng
Có một chức năng thực thi đơn giản có sẵn với kết nối sẽ giúp chúng ta thực hiện tất cả các thao tác db từ tạo, chèn, xóa, cập nhật, v.v. Cú pháp được hiển thị bên dưới -
conn:execute([[ 'SQLite3STATEMENT' ]])
Trong cú pháp trên, chúng ta cần đảm bảo rằng conn đang mở và kết nối sqlite3 hiện có và thay thế 'SQLite3STATEMENT' bằng câu lệnh đúng.
Ví dụ về Tạo bảng
Dưới đây là một ví dụ tạo bảng đơn giản. Nó tạo một bảng với hai tham số id kiểu số nguyên và tên kiểu varchar.
sqlite3 = require "luasql.sqlite3"
local env = sqlite3.sqlite3()
local conn = env:connect('mydb.sqlite')
print(env,conn)
status,errorString = conn:execute([[CREATE TABLE sample ('id' INTEGER, 'name' TEXT)]])
print(status,errorString )
Khi bạn chạy chương trình trên, một bảng có tên sample sẽ được tạo với hai cột là id và name.
SQLite3 environment (003EC918) SQLite3 connection (00421F08)
0 nil
Trong trường hợp có lỗi, bạn sẽ được trả về một câu lệnh lỗi thay vì nil. Một báo cáo lỗi đơn giản được hiển thị bên dưới.
LuaSQL: unrecognized token: ""'id' INTEGER, 'name' TEXT)"
Chèn ví dụ câu lệnh
Một câu lệnh chèn cho SQLite được hiển thị bên dưới.
conn:execute([[INSERT INTO sample values('11','Raj')]])
Chọn ví dụ về câu lệnh
Đối với câu lệnh select, chúng ta cần lặp qua từng hàng và trích xuất dữ liệu cần thiết. Một câu lệnh chọn đơn giản được hiển thị bên dưới.
cursor,errorString = conn:execute([[select * from sample]])
row = cursor:fetch ({}, "a")
while row do
print(string.format("Id: %s, Name: %s", row.id, row.name))
-- reusing the table of results
row = cursor:fetch (row, "a")
end
Trong đoạn mã trên, conn là một kết nối sqlite3 mở. Với sự trợ giúp của con trỏ được trả về bởi câu lệnh thực thi, bạn có thể lặp qua phản hồi bảng và tìm nạp dữ liệu chọn được yêu cầu.
Một ví dụ hoàn chỉnh
Dưới đây là một ví dụ đầy đủ bao gồm tất cả các câu trên.
sqlite3 = require "luasql.sqlite3"
local env = sqlite3.sqlite3()
local conn = env:connect('mydb.sqlite')
print(env,conn)
status,errorString = conn:execute([[CREATE TABLE sample ('id' INTEGER, 'name' TEXT)]])
print(status,errorString )
status,errorString = conn:execute([[INSERT INTO sample values('1','Raj')]])
print(status,errorString )
cursor,errorString = conn:execute([[select * from sample]])
print(cursor,errorString)
row = cursor:fetch ({}, "a")
while row do
print(string.format("Id: %s, Name: %s", row.id, row.name))
row = cursor:fetch (row, "a")
end
-- close everything
cursor:close()
conn:close()
env:close()
Khi bạn chạy chương trình trên, bạn sẽ nhận được kết quả sau.
SQLite3 environment (005EC918) SQLite3 connection (005E77B0)
0 nil
1 nil
SQLite3 cursor (005E9200) nil
Id: 1, Name: Raj
Chúng tôi có thể thực hiện tất cả các truy vấn có sẵn với sự trợ giúp của thư viện libsql này. Vì vậy, xin đừng dừng lại với những ví dụ này. Thử nghiệm các câu lệnh truy vấn khác nhau có sẵn trong MySQL, SQLite3 tương ứng và các db được hỗ trợ khác trong Lua.
Lua được sử dụng trong rất nhiều game engine do cấu trúc ngôn ngữ và cú pháp đơn giản. Tính năng thu gom rác thường khá hữu ích trong các trò chơi tiêu tốn nhiều bộ nhớ do sử dụng đồ họa phong phú. Một số công cụ trò chơi sử dụng Lua bao gồm:
- Corona SDK
- Gideros Mobile
- ShiVa3D
- SDK Moai
- LOVE
- CryEngine
Mỗi công cụ trò chơi này đều dựa trên Lua và có một bộ API phong phú có sẵn trong mỗi công cụ này. Chúng ta sẽ xem xét các khả năng của từng loại một cách ngắn gọn.
Corona SDK
Corona SDK là một công cụ trò chơi di động đa nền tảng hỗ trợ các nền tảng iPhone, iPad và Android. Có một phiên bản Corona SDK miễn phí có thể được sử dụng cho các trò chơi nhỏ với các tính năng hạn chế. Bạn có thể nâng cấp lên các phiên bản khác khi cần thiết.
Corona SDK cung cấp một số tính năng bao gồm:
- API xử lý vật lý và va chạm
- API Web và Mạng
- API mạng trò chơi
- API quảng cáo
- API phân tích
- Cơ sở dữ liệu và API hệ thống tệp
- API tiền điện tử và toán học
- API âm thanh và phương tiện
Việc phát triển ứng dụng bằng cách sử dụng các API trên sẽ dễ dàng và nhanh hơn thay vì sử dụng các API gốc riêng biệt cho iOS và Android.
Gideros Mobile
Gideros cung cấp SDK đa nền tảng để tạo trò chơi cho iOS và Android. Nó là miễn phí để sử dụng với một tia nước Gideros. Một số ưu điểm nổi bật trong Gideoros bao gồm:
Development IDE - Nó cung cấp IDE riêng giúp phát triển ứng dụng Gideros dễ dàng hơn.
Instant testing- Trong khi phát triển trò chơi của bạn, nó có thể được kiểm tra trên thiết bị thực thông qua Wifi chỉ trong 1 giây. Bạn không cần phải lãng phí thời gian của mình với quá trình xuất hoặc triển khai.
Plugins- Bạn có thể dễ dàng mở rộng lõi bằng các plugin. Nhập mã (C, C ++, Java hoặc Obj-C) hiện có của bạn, liên kết với Lua và diễn giải chúng trực tiếp. Hàng chục plugin mã nguồn mở đã được phát triển và sẵn sàng sử dụng.
Clean OOP approach - Gideros cung cấp hệ thống lớp học của riêng mình với tất cả các tiêu chuẩn OOP cơ bản, cho phép bạn viết mã sạch và có thể tái sử dụng cho bất kỳ trò chơi nào trong tương lai của bạn.
Native speed - Được phát triển dựa trên C / C ++ và OpenGL, trò chơi của bạn chạy ở tốc độ gốc và sử dụng đầy đủ sức mạnh của CPU và GPU bên dưới.
ShiVa3D
ShiVa3D là một trong những công cụ trò chơi 3D cung cấp trình chỉnh sửa đồ họa được thiết kế để tạo ứng dụng và trò chơi điện tử cho Web, Bảng điều khiển và thiết bị Di động. Nó hỗ trợ nhiều nền tảng bao gồm Windows, Mac, Linux, iOS, Android, BlackBerry, Palm OS, Wii và WebOS.
Một số tính năng chính bao gồm
- Các plugin tiêu chuẩn
- API sửa đổi lưới
- IDE
- Trình chỉnh sửa địa hình, đại dương và hoạt ảnh tích hợp
- Hỗ trợ công cụ vật lý ODE
- Kiểm soát bản đồ ánh sáng đầy đủ
- Xem trước trực tiếp cho vật liệu, hạt, đường mòn và HUD
- Hỗ trợ định dạng trao đổi Collada
Phiên bản web của Shiva3d hoàn toàn miễn phí và các phiên bản khác mà bạn đăng ký.
SDK Moai
Moai SDK là một công cụ trò chơi di động đa nền tảng hỗ trợ các nền tảng iPhone, iPad và Android. Ban đầu, nền tảng Moai bao gồm Moai SDK, một công cụ trò chơi mã nguồn mở và Moai Cloud, một nền tảng đám mây làm dịch vụ lưu trữ và triển khai các dịch vụ trò chơi. Hiện Moai Cloud đã ngừng hoạt động và chỉ có công cụ trò chơi.
Moai SDK chạy trên nhiều nền tảng bao gồm iOS, Android, Chrome, Windows, Mac và Linux.
YÊU VÀ QUÝ
LOVE là một khuôn khổ mà bạn có thể sử dụng để tạo các trò chơi 2D. Nó là miễn phí và mã nguồn mở. Nó hỗ trợ các nền tảng Windows, Mac OS X và Linux.
Nó cung cấp nhiều tính năng bao gồm,
- API âm thanh
- API hệ thống tệp
- API bàn phím và cần điều khiển
- API toán học
- API cửa sổ và chuột
- API Vật lý
- API hệ thống và bộ hẹn giờ
CryEngine
CryEngine là một công cụ trò chơi được phát triển bởi nhà phát triển trò chơi người Đức Crytek. Nó đã phát triển từ thế hệ 1 đến thế hệ 4 và là một giải pháp phát triển tiên tiến. Nó hỗ trợ các trò chơi PC, Xbox 360, PlayStation3 và WiiU.
Nó cung cấp nhiều tính năng bao gồm,
Các hiệu ứng hình ảnh như Ánh sáng tự nhiên & Bóng mềm động, Chiếu sáng toàn cầu động trong thời gian thực, Khối lượng lan truyền ánh sáng, Đổ bóng hạt, Tessellation, v.v.
Hệ thống hoạt hình nhân vật và hệ thống cá nhân hóa nhân vật.
Hình ảnh động bộ xương tham số và Trình chỉnh sửa hoạt ảnh khuôn mặt chuyên dụng độc đáo
Hệ thống AI như Lưới điều hướng nhiều lớp và Hệ thống điểm chiến thuật. Đồng thời cung cấp Hệ thống chỉnh sửa AI thân thiện với nhà thiết kế.
Trong Game Mixing & Profiling, Hệ thống âm thanh theo hướng dữ liệu Âm thanh động & Âm nhạc tương tác, v.v.
Các tính năng vật lý như Biến dạng thủ tục và Vật lý dây nâng cao.
Một ghi chú kết thúc
Mỗi SDK / khuôn khổ trò chơi này đều có ưu và nhược điểm riêng. Một sự lựa chọn thích hợp giữa chúng sẽ làm cho nhiệm vụ của bạn dễ dàng hơn và bạn có thể có thời gian tốt hơn với nó. Vì vậy, trước khi sử dụng nó, bạn cần phải biết các yêu cầu cho trò chơi của bạn và sau đó phân tích xem cái nào đáp ứng được tất cả nhu cầu của bạn rồi mới nên sử dụng chúng.
Thư viện tiêu chuẩn Lua cung cấp một bộ hàm phong phú được triển khai trực tiếp với API C và được tích hợp sẵn với ngôn ngữ lập trình Lua. Các thư viện này cung cấp các dịch vụ trong ngôn ngữ lập trình Lua và cả các dịch vụ bên ngoài như hoạt động tệp và db.
Các thư viện tiêu chuẩn này được xây dựng trong API C chính thức được cung cấp dưới dạng các mô-đun C riêng biệt. Nó bao gồm những điều sau:
- Thư viện cơ bản, bao gồm thư viện con của coroutine
- Thư viện mô-đun
- Thao tác chuỗi
- Thao tác bảng
- Thư viện toán học
- Đầu vào và đầu ra tệp
- Hệ điều hành cơ sở vật chất
- Cơ sở gỡ lỗi
Thư viện cơ bản
Chúng tôi đã sử dụng thư viện cơ bản trong suốt hướng dẫn theo các chủ đề khác nhau. Bảng sau cung cấp các liên kết của các trang liên quan và liệt kê các chức năng được đề cập trong các phần khác nhau của hướng dẫn Lua này.
Sr.No. | Thư viện / Phương pháp & Mục đích |
---|---|
1 | Error Handling Bao gồm các chức năng xử lý lỗi như khẳng định, lỗi như được giải thích trong Lua - Xử lý lỗi . |
2 | Memory Management Bao gồm các chức năng quản lý bộ nhớ tự động liên quan đến thu gom rác như được giải thích trong Lua - Garbage Collection . |
3 | dofile ([filename]) Nó mở tệp và thực thi nội dung của tệp dưới dạng một đoạn. Nếu không có tham số nào được truyền, thì hàm này thực thi nội dung của đầu vào chuẩn. Các lỗi sẽ được thông báo cho người gọi. |
4 | _G Do đó, biến toàn cục nắm giữ môi trường toàn cục (nghĩa là, _G._G = _G). Bản thân Lua không sử dụng biến này. |
5 | getfenv ([f]) Trả về môi trường hiện tại được sử dụng bởi hàm. f có thể là một hàm Lua hoặc một số chỉ định hàm ở mức ngăn xếp đó - Mức 1 là hàm gọi getfenv. Nếu hàm đã cho không phải là hàm Lua hoặc nếu f bằng 0, hàm getfenv trả về môi trường toàn cục. Giá trị mặc định cho f là 1. |
6 | getmetatable (object) Nếu đối tượng không có đối tượng, trả về nil. Ngược lại, nếu đối tượng có thể đo được có trường "__metatable", trả về giá trị được liên kết. Nếu không, trả về khả năng đáp ứng của đối tượng đã cho. |
7 | ipairs (t) Hàm này tìm nạp các chỉ số và giá trị của bảng. |
số 8 | load (func [, chunkname]) Tải một đoạn bằng cách sử dụng hàm func để lấy các mảnh của nó. Mỗi lệnh gọi đến func phải trả về một chuỗi nối với các kết quả trước đó. |
9 | loadfile ([filename])) Tương tự như tải, nhưng lấy đoạn từ tên tệp hoặc từ đầu vào chuẩn, nếu không có tên tệp nào được cung cấp. |
10 | loadstring (string [, chunkname]) Tương tự như tải, nhưng lấy đoạn từ chuỗi đã cho. |
11 | next (table [, index]) Cho phép chương trình duyệt qua tất cả các trường của bảng. Đối số đầu tiên của nó là một bảng và đối số thứ hai của nó là một chỉ mục trong bảng này. next trả về chỉ mục tiếp theo của bảng và giá trị liên quan của nó. |
12 | pairs (t) Tạm dừng quy trình đăng ký đang chạy. Tham số được truyền cho phương thức này hoạt động như các giá trị trả về bổ sung cho hàm tiếp tục. |
13 | print (...) Tạm dừng quy trình đăng ký đang chạy. Tham số được truyền cho phương thức này hoạt động như các giá trị trả về bổ sung cho hàm tiếp tục. |
14 | rawequal (v1, v2) Kiểm tra xem v1 có bằng v2 hay không mà không cần gọi bất kỳ metamethod nào. Trả về một boolean. |
15 | rawget (table, index) Nhận giá trị thực của bảng [index] mà không cần gọi bất kỳ metamethod nào. table phải là table; chỉ mục có thể là bất kỳ giá trị nào. |
16 | rawset (table, index, value) Đặt giá trị thực của bảng [index] thành value mà không cần gọi bất kỳ metamethod nào. bảng phải là một bảng, lập chỉ mục bất kỳ giá trị nào khác với nil và đánh giá bất kỳ giá trị Lua nào. Hàm này trả về bảng. |
17 | select (index, ...) Nếu chỉ mục là một số, trả về tất cả các đối số sau chỉ mục số đối số. Nếu không, chỉ mục phải là chuỗi "#" và select trả về tổng số đối số phụ mà nó nhận được. |
18 | setfenv (f, table) Đặt môi trường được sử dụng bởi hàm đã cho. f có thể là một hàm Lua hoặc một số chỉ định hàm ở mức ngăn xếp đó - Mức 1 là hàm gọi setfenv. setfenv trả về hàm đã cho. Là một trường hợp đặc biệt, khi f bằng 0 setfenv thay đổi môi trường của luồng đang chạy. Trong trường hợp này, setfenv không trả về giá trị nào. |
19 | setmetatable (table, metatable) Đặt độ chính xác cho bảng đã cho. (Bạn không thể thay đổi độ đo được của các loại khác từ Lua, chỉ từ C.) Nếu độ đo được bằng không, hãy loại bỏ độ đo được của bảng đã cho. Nếu phiên bản gốc có trường "__metatable", thì sẽ xảy ra lỗi. Hàm này trả về bảng. |
20 | tonumber (e [, base]) Cố gắng chuyển đổi đối số của nó thành một số. Nếu đối số đã là một số hoặc một chuỗi có thể chuyển đổi thành số, thì tonumber trả về số này; nếu không, nó trả về nil. |
21 | tostring (e) Nhận một đối số thuộc bất kỳ loại nào và chuyển đổi nó thành một chuỗi ở định dạng hợp lý. Để kiểm soát hoàn toàn cách các số được chuyển đổi, hãy sử dụng string.format. |
22 | type (v) Trả về kiểu đối số duy nhất của nó, được mã hóa dưới dạng chuỗi. Các kết quả có thể có của hàm này là "nil" (một chuỗi, không phải giá trị nil), "number", "string", "boolean", "table", "function", "thread" và "userdata". |
23 | unpack (list [, i [, j]]) Trả về các phần tử từ bảng đã cho. |
24 | _VERSION Một biến toàn cục (không phải là một hàm) chứa một chuỗi chứa phiên bản thông dịch hiện tại. Nội dung hiện tại của biến này là "Lua 5.1". |
25 | Coroutines Bao gồm các chức năng thao tác trên quy trình như được giải thích trong Lua - Coroutines . |
Thư viện mô-đun
Thư viện mô-đun cung cấp các chức năng cơ bản để tải mô-đun trong Lua. Nó xuất trực tiếp một hàm trong môi trường toàn cầu: request. Mọi thứ khác được xuất trong một gói bảng. Chi tiết về thư viện mô-đun được giải thích trong chương trước Lua - Hướng dẫn mô-đun .
Thao tác chuỗi
Lua cung cấp một tập hợp các hàm thao tác chuỗi phong phú. Hướng dẫn Lua - Strings trước đó sẽ trình bày chi tiết về vấn đề này.
Thao tác bảng
Lua phụ thuộc vào các bảng trong hầu hết các hoạt động của nó. Hướng dẫn Lua - Tables trước đó sẽ trình bày chi tiết về vấn đề này.
Đầu vào và đầu ra tệp
Chúng ta thường cần cơ sở lưu trữ dữ liệu trong lập trình và điều này được cung cấp bởi các hàm thư viện tiêu chuẩn cho I / O tệp trong Lua. Nó được thảo luận trong hướng dẫn Lua - File I / O trước đó .
Cơ sở gỡ lỗi
Lua cung cấp một thư viện gỡ lỗi cung cấp tất cả các chức năng nguyên thủy để chúng ta tạo trình gỡ lỗi của riêng mình. Nó được thảo luận trong Lua - Hướng dẫn gỡ lỗi trước đó .
Chúng ta thường cần các phép toán trong tính toán khoa học và kỹ thuật và chúng ta có thể tận dụng điều này bằng cách sử dụng toán học thư viện Lua tiêu chuẩn. Danh sách các hàm có sẵn trong thư viện toán học được hiển thị trong bảng sau.
Sr.No. | Thư viện / Phương pháp & Mục đích |
---|---|
1 | math.abs (x) Trả về giá trị tuyệt đối của x. |
2 | math.acos (x) Trả về cosin cung của x (tính bằng radian). |
3 | math.asin (x) Trả về sin cung của x (tính bằng radian). |
4 | math.atan (x) Trả về tiếp tuyến cung của x (tính bằng radian). |
5 | math.atan2 (y, x) Trả về tiếp tuyến cung của y / x (tính bằng radian), nhưng sử dụng dấu hiệu của cả hai tham số để tìm góc phần tư của kết quả. (Nó cũng xử lý chính xác trường hợp x bằng không.) |
6 | math.ceil (x) Trả về số nguyên nhỏ nhất lớn hơn hoặc bằng x. |
7 | math.cos (x) Trả về cosine của x (giả sử là radian). |
số 8 | math.cosh (x) Trả về cosin hyperbol của x. |
9 | math.deg (x) Trả về góc x (tính bằng radian) theo độ. |
10 | math.exp (x) Trả về giá trị e lũy thừa x. |
11 | math.floor (x) Trả về số nguyên lớn nhất nhỏ hơn hoặc bằng x. |
12 | math.fmod (x, y) Trả về phần còn lại của phép chia x cho y làm tròn thương số về 0. |
13 | math.frexp (x) Trả về m và e sao cho x = m2e, e là số nguyên và giá trị tuyệt đối của m nằm trong khoảng [0,5, 1) (hoặc 0 khi x bằng 0). |
14 | math.huge Giá trị HUGE_VAL, một giá trị lớn hơn hoặc bằng bất kỳ giá trị số nào khác. |
15 | math.ldexp (m, e) Trả về m2e (e phải là một số nguyên). |
16 | math.log (x) Trả về lôgarit tự nhiên của x. |
17 | math.log10 (x) Trả về logarit cơ số 10 của x. |
18 | math.max (x, ...) Trả về giá trị lớn nhất trong số các đối số của nó. |
19 | math.min (x, ...) Trả về giá trị nhỏ nhất trong số các đối số của nó. |
20 | math.modf (x) Trả về hai số, phần nguyên của x và phần thập phân của x. |
21 | math.pi Giá trị của số pi. |
22 | math.pow (x, y) Trả về xy. (Bạn cũng có thể sử dụng biểu thức x ^ y để tính giá trị này.) |
23 | math.rad (x) Trả về góc x (tính bằng độ) tính bằng radian. |
24 | math.random ([m [, n]]) Hàm này là một giao diện với hàm tạo ngẫu nhiên giả đơn giản rand do ANSI C. cung cấp. Khi được gọi mà không có đối số, trả về một số thực giả ngẫu nhiên thống nhất trong phạm vi [0,1). Khi được gọi với số nguyên m, math.random trả về một số nguyên giả ngẫu nhiên thống nhất trong phạm vi [1, m]. Khi được gọi với hai số nguyên m và n, math.random trả về một số nguyên giả ngẫu nhiên thống nhất trong phạm vi [m, n]. |
25 | math.randomseed (x) Đặt x làm "hạt giống" cho trình tạo giả ngẫu nhiên: các hạt giống nhau tạo ra các chuỗi số bằng nhau. |
26 | math.sin (x) Trả về sin của x (giả sử là radian). |
27 | math.sinh (x) Trả về sin hyperbol của x. |
28 | math.sqrt (x) Trả về căn bậc hai của x. (Bạn cũng có thể sử dụng biểu thức x ^ 0,5 để tính giá trị này.) |
29 | math.tan (x) Trả về tang của x (giả sử là radian). |
30 | math.tanh (x) Trả về tiếp tuyến hyperbol của x. |
Hàm lượng giác
Dưới đây là một ví dụ đơn giản sử dụng hàm lượng giác.
radianVal = math.rad(math.pi / 2)
io.write(radianVal,"\n")
-- Sin value of 90(math.pi / 2) degrees
io.write(string.format("%.1f ", math.sin(radianVal)),"\n")
-- Cos value of 90(math.pi / 2) degrees
io.write(string.format("%.1f ", math.cos(radianVal)),"\n")
-- Tan value of 90(math.pi / 2) degrees
io.write(string.format("%.1f ", math.tan(radianVal)),"\n")
-- Cosh value of 90(math.pi / 2) degrees
io.write(string.format("%.1f ", math.cosh(radianVal)),"\n")
-- Pi Value in degrees
io.write(math.deg(math.pi),"\n")
Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau.
0.027415567780804
0.0
1.0
0.0
1.0
180
Các hàm toán học thông thường khác
Dưới đây là một ví dụ đơn giản sử dụng các hàm toán học phổ biến.
-- Floor
io.write("Floor of 10.5055 is ", math.floor(10.5055),"\n")
-- Ceil
io.write("Ceil of 10.5055 is ", math.ceil(10.5055),"\n")
-- Square root
io.write("Square root of 16 is ",math.sqrt(16),"\n")
-- Power
io.write("10 power 2 is ",math.pow(10,2),"\n")
io.write("100 power 0.5 is ",math.pow(100,0.5),"\n")
-- Absolute
io.write("Absolute value of -10 is ",math.abs(-10),"\n")
--Random
math.randomseed(os.time())
io.write("Random number between 1 and 100 is ",math.random(),"\n")
--Random between 1 to 100
io.write("Random number between 1 and 100 is ",math.random(1,100),"\n")
--Max
io.write("Maximum in the input array is ",math.max(1,100,101,99,999),"\n")
--Min
io.write("Minimum in the input array is ",math.min(1,100,101,99,999),"\n")
Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau.
Floor of 10.5055 is 10
Ceil of 10.5055 is 11
Square root of 16 is 4
10 power 2 is 100
100 power 0.5 is 10
Absolute value of -10 is 10
Random number between 1 and 100 is 0.22876674703207
Random number between 1 and 100 is 7
Maximum in the input array is 999
Minimum in the input array is 1
Các ví dụ trên chỉ là một số ví dụ phổ biến, chúng ta có thể sử dụng thư viện toán học dựa trên nhu cầu của mình, vì vậy hãy thử sử dụng tất cả các hàm để quen thuộc hơn.
Trong bất kỳ ứng dụng nào, nó thường được yêu cầu truy cập các chức năng cấp Hệ điều hành và nó được cung cấp sẵn với thư viện Hệ điều hành. Danh sách các chức năng có sẵn được liệt kê trong bảng sau.
Sr.No. | Thư viện / Phương pháp & Mục đích |
---|---|
1 | os.clock () Trả về giá trị gần đúng của thời gian CPU được chương trình sử dụng theo giây. |
2 | os.date ([format [, time]]) Trả về một chuỗi hoặc một bảng chứa ngày và giờ, được định dạng theo định dạng chuỗi đã cho. |
3 | os.difftime (t2, t1) Trả về số giây từ thời điểm t1 đến thời điểm t2. Trong POSIX, Windows và một số hệ thống khác, giá trị này chính xác là t2-t1. |
4 | os.execute ([command]) Chức năng này tương đương với hệ thống chức năng ANSI C. Nó chuyển lệnh để được thực thi bởi một trình bao hệ điều hành. Kết quả đầu tiên của nó là true nếu lệnh kết thúc thành công, hoặc bằng không. |
5 | os.exit ([code [, close]) Gọi lối ra hàm ANSI C để chấm dứt chương trình máy chủ. Nếu mã là true, trạng thái trả về là EXIT_SUCCESS; nếu mã sai, trạng thái trả về là EXIT_FAILURE; nếu mã là một số, trạng thái trả về là số này. |
6 | os.getenv (varname) Trả về giá trị của biến môi trường tiến trình varname hoặc nil nếu biến không được xác định. |
7 | os.remove (filename) Xóa tệp (hoặc thư mục trống, trên hệ thống POSIX) với tên đã cho. Nếu hàm này không thành công, nó sẽ trả về nil, cộng với một chuỗi mô tả lỗi và mã lỗi. |
số 8 | os.rename (oldname, newname) Đổi tên tệp hoặc thư mục có tên cũ thành tên mới. Nếu hàm này không thành công, nó sẽ trả về nil, cộng với một chuỗi mô tả lỗi và mã lỗi. |
9 | os.setlocale (locale [, category]) Đặt ngôn ngữ hiện tại của chương trình. locale là một chuỗi phụ thuộc vào hệ thống chỉ định một ngôn ngữ; danh mục là một chuỗi tùy chọn mô tả danh mục cần thay đổi: "tất cả", "đối chiếu", "ctype", "tiền tệ", "số" hoặc "thời gian"; danh mục mặc định là "tất cả". Hàm trả về tên của ngôn ngữ mới hoặc nil nếu yêu cầu không thể được thực hiện. |
10 | os.time ([table]) Trả về thời gian hiện tại khi được gọi mà không có đối số hoặc thời gian biểu thị ngày và giờ được chỉ định bởi bảng đã cho. Bảng này phải có các trường năm, tháng và ngày và có thể có các trường giờ (mặc định là 12), min (mặc định là 0), giây (mặc định là 0) và isdst (mặc định là nil). Để biết mô tả về các trường này, hãy xem hàm os.date. |
11 | os.tmpname () Trả về một chuỗi có tên tệp có thể được sử dụng cho tệp tạm thời. Tệp phải được mở rõ ràng trước khi sử dụng và xóa rõ ràng khi không cần nữa. |
Các chức năng hệ điều hành phổ biến
Dưới đây là một ví dụ đơn giản sử dụng các hàm toán học phổ biến.
-- Date with format
io.write("The date is ", os.date("%m/%d/%Y"),"\n")
-- Date and time
io.write("The date and time is ", os.date(),"\n")
-- Time
io.write("The OS time is ", os.time(),"\n")
-- Wait for some time
for i=1,1000000 do
end
-- Time since Lua started
io.write("Lua started before ", os.clock(),"\n")
Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả tương tự như sau.
The date is 01/25/2014
The date and time is 01/25/14 07:38:40
The OS time is 1390615720
Lua started before 0.013
Các ví dụ trên chỉ là một vài ví dụ phổ biến, chúng ta có thể sử dụng thư viện OS tùy theo nhu cầu của mình, vì vậy hãy thử sử dụng tất cả các hàm để quen thuộc hơn. Có các chức năng như remove giúp xóa tệp, thực thi giúp chúng ta thực hiện các lệnh hệ điều hành như đã giải thích ở trên.