Trợ giúp
Trợ giúp là một tập hợp các chức năng trợ giúp Lua để làm việc thoải mái trong dự án.
Các chức năng trợ giúp này mở rộng đáng kể khả năng tiêu chuẩn của Lua và đơn giản hóa việc phát triển.
String
Phương thức được cung cấp bởi Luanti:
string:lower()
Chuyển đổi chuỗi thành chữ thường với hỗ trợ tiếng Cyrillic.
print(('ПРИВЕТ МИР'):lower()) -- 'привет мир'string:upper()
Chuyển đổi chuỗi thành chữ hoa với hỗ trợ tiếng Cyrillic.
print(string.upper('привет мир')) -- 'ПРИВЕТ МИР'string:is_one_of(table)
Kiểm tra xem chuỗi có phải là một trong các giá trị trong mảng được truyền hay không.
(Tương tự ngữ nghĩa của table.contains, kiểm tra xem chuỗi có được chứa trong mảng được truyền hay không.)
local text = 'hello'
local options = { 'hello', 'world', 'lua' }
print(text:is_one_of(options)) -- truestring:first_to_upper()
Chuyển đổi chữ cái đầu tiên thành chữ hoa.
local text = 'hello world'
print(text:first_to_upper()) -- 'Hello world'string :title()/:to_headline()
Chuyển đổi chữ cái đầu tiên của mỗi từ thành title case.
Tên thay thế: string:to_headline()
local text = 'hello world from lua'
print(text:title()) -- 'Hello World From Lua'
print(text:to_headline()) -- 'Hello World From Lua'string:starts_with(prefix)
Kiểm tra xem chuỗi có bắt đầu bằng tiền tố được chỉ định hay không.
local filename = 'config.json'
print(filename:starts_with('config')) -- true
print(filename:starts_with('settings')) -- falsestring:ends_with(suffix)
Kiểm tra xem chuỗi có kết thúc bằng hậu tố được chỉ định hay không.
local filename = 'config.json'
print(filename:ends_with('.json')) -- true
print(filename:ends_with('.conf')) -- falsestring:contains(sub_string)
Kiểm tra sự hiện diện của chuỗi con.
local text = 'Hello, World !!!'
print(text:contains('World')) -- true
print(text:contains('world')) -- false (phân biệt chữ hoa/thường)string:replace(pattern, replacement, n?)
Thay thế chuỗi con (tương tự của gsub, nhưng chỉ trả về chuỗi không có số lần thay thế).
Xem tài liệu cho string.gsub và Patterns
local text = 'Hello, World, World!'
local result = text:replace('World', 'Lua')
print(result) -- 'Hello, Lua, Lua!'
-- Chỉ thay thế lần xuất hiện đầu tiên
local result2 = text:replace('World', 'Lua', 1)
print(result2) -- 'Hello, Lua, World!'string:remove(pattern, n?)
Xóa chuỗi con.
Xem tài liệu cho string.gsub và Patterns
local text = 'Hello, World!'
print(text:remove(', ')) -- 'HelloWorld!'
print(text:remove('o', 1)) -- 'Hell, Wrld!' (chỉ xóa 'o' đầu tiên)string:reg_escape()
Thoát các ký tự đặc biệt cho biểu thức chính quy.
Xem Patterns
local pattern = 'file.txt'
print(pattern:reg_escape()) -- 'file%.txt'
local pattern2 = '^$()%.[]*+-?)'
print(pattern2:reg_escape()) -- '%^%$()%.%[%]%*%+\-%?)'string:vxr_split(delimiter?, processor?)
Chia chuỗi theo delimiter được chỉ định với khả năng xử lý các phần.
Luanti có phương thức string.split riêng, nhưng không hỗ trợ xử lý các phần.
Phương thức này thêm khả năng xử lý các phần của chuỗi.
-- Không xử lý
('hello world'):vxr_split() -- { 'hello', 'world' }
('apple,banana,cherry'):vxr_split(',') -- { 'apple', 'banana', 'cherry' }
-- Với xử lý
local numbers = '1,2,3,4,5'
local squared = numbers:vxr_split(',', function(x)
return tonumber(x)^2
end)
print(squared[1], squared[2], squared[3], squared[4], squared[5])
-- 1 4 9 16 25string.or_nil(value)
Chuyển đổi thành chuỗi hoặc trả về nil.
print(string.or_nil('hello')) -- 'hello'
print(string.or_nil(42)) -- '42'
print(string.or_nil(nil)) -- nil
print(tostring(nil)) -- 'nil' (so sánh)Phương thức được cung cấp bởi Luanti :
Luanti string.split()
Xem thêm: string.vxr_split(delimiter?, processor?)
Chia chuỗi thành các phần theo dấu phân cách được chỉ định. Trả về mảng chuỗi. Tham số:
separator?dấu phân cách, mặc định:","include_empty?mặc định:falsemax_splits?nếu âm, chia không giới hạn, mặc định:-1sep_is_pattern?nếu dấu phân cách là chuỗi thông thường hay pattern (regex), mặc định:false
local text = 'apple,banana,cherry'
local parts = text.split(',')
print(parts[1], parts[2], parts[3]) -- 'apple', 'banana', 'cherry'
-- Chia theo khoảng trắng
local words = 'hello world lua'.split(' ')
print(words[1], words[2], words[3]) -- 'hello', 'world', 'lua'Luanti string.trim()
Xóa các ký tự khoảng trắng ở đầu và cuối chuỗi.
print(("\n \t\tfoo bar\t "):trim()) -- 'foo bar'Luanti string.pack()
Đóng gói các giá trị vào chuỗi nhị phân theo định dạng.
Backport từ Lua 5.4.
-- Đóng gói số nguyên
local packed = string.pack('i4', 42)
print(#packed) -- 4 (kích thước byte)
-- Đóng gói nhiều giá trị
local data = string.pack('i4f8', 100, 3.14)
print(#data) -- 12 (4 + 8 byte)Luanti string.unpack()
Giải nén chuỗi nhị phân thành các giá trị theo định dạng.
Backport từ Lua 5.4.
local packed = string.pack('i4f8', 100, 3.14)
local num, float, next_pos = string.unpack('i4f8', packed)
print(num, float) -- 100, 3.14
print(next_pos) -- 13 (vị trí sau giải nén)
-- Giải nén từ vị trí được chỉ định
local value = string.unpack('i4', packed, 5)
print(value) -- 3.14 (như float)Luanti string.packsize()
Trả về kích thước của chuỗi sẽ được tạo bởi string.pack.
Backport từ Lua 5.4.
local size = string.packsize('i4f8')
print(size) -- 12 (4 + 8 byte)
-- Cho định dạng phức tạp
local complex_size = string.packsize('i4c10f8')
print(complex_size) -- 22 (4 + 10 + 8 byte)Table
Phương thức, được cung cấp bởi Luanti :
table.copy()table.copy_with_metatables()table.insert_all()
table.indexof()table.keyof()table.key_value_swap()table.shuffle()
table.keys(table)
Trả về một mảng các khóa của bảng.
local data = { name = 'Alek', age = 25, city = 'Vladivostok' }
local keys = table.keys(data)
-- `keys` chứa `{ 'name', 'age', 'city' }` (thứ tự có thể thay đổi)table.values(table)
Trả về một mảng các giá trị của bảng.
local data = { name = 'Alek', age = 25, city = 'Vladivostok' }
local values = table.values(data)
-- `values` chứa { 'Alek', 25, 'Vladivostok' }table.has_key(table, key)
Kiểm tra xem một khóa có tồn tại trong bảng hay không.
local data = { name = 'Alek', age = 25 }
print(table.has_key(data, 'name')) -- true
print(table.has_key(data, 'city')) -- falsetable .contains/has_value(table, value)
Kiểm tra xem một giá trị có tồn tại trong bảng hay không.
local fruits = { 'apple', 'banana', 'cherry' }
print(table.contains(fruits, 'banana')) -- true
print(table.contains(fruits, 'orange')) -- falseBạn cũng có thể sử dụng string:is_one_of():
print('banana':is_one_of(fruits)) -- true
print('orange':is_one_of(fruits)) -- falseTên thay thế: table.has_value
local data = { x = 10, y = 20 }
print(table.has_value(data, 10)) -- true
print(table.has_value(data, 30)) -- falsetable.keys_of(table, value)
Trả về một bảng với các khóa của bảng được chỉ định có giá trị được chỉ định.
local data = { a = 10, b = 20, c = 10, d = 30 }
local keys = table.keys_of(data, 10)
print(dump(keys)) -- { 'a', 'c' }
local keys2 = table.keys_of(data, 99)
print(keys2) -- nil (không có khóa nào như vậy)table.has_any_key(table, find_keys)
Kiểm tra xem các khóa của bảng có chứa ít nhất một giá trị từ mảng được chỉ định hay không.
local data = { name = 'test', age = 25, active = true }
local find_keys = { 'name', 'email', 'phone' }
print(table.has_any_key(data, find_keys)) -- true (khóa 'name' có trong find_keys)
local find_keys2 = { 'email', 'phone', 'address' }
print(table.has_any_key(data, find_keys2)) -- falsetable.equals(table1, table2)
So sánh đệ quy hai bảng để kiểm tra sự bằng nhau hoàn toàn.
local table1 = { a = 1, b = { c = 2, d = 3 } }
local table2 = { a = 1, b = { c = 2, d = 3 } }
local table3 = { a = 1, b = { c = 2, d = 4 } }
print(table.equals(table1, table2)) -- true
print(table.equals(table1, table3)) -- falsetable.is_empty(table)
Kiểm tra xem bảng có rỗng hay không.
print(table.is_empty({})) -- true
print(table.is_empty({ a = 1 })) -- falsetable.is_position(table)
Kiểm tra xem bảng có đại diện cho tọa độ hay không.
print(table.is_position({ x = 10, y = 20, z = 30 })) -- true
print(table.is_position({ x = 10, y = 20 })) -- false
print(table.is_position({ a = 1, b = 2, c = 3 })) -- falsetable.each_value_is(table, value)
Kiểm tra rằng tất cả các phần tử của bảng bằng với giá trị được chỉ định. Mặc định kiểm tra cho true.
local data1 = { true, true, true }
print(table.each_value_is(data1)) -- true
local data2 = { 5, 5, 5, 5 }
print(table.each_value_is(data2, 5)) -- true
local data3 = { 1, 2, 3 }
print(table.each_value_is(data3, 1)) -- falsetable.count(table)
Đếm số lượng phần tử trong bảng.
NOTE
Đối với bảng có khóa nguyên, sử dụng #table.
Vì toán tử # không hoạt động trên bảng có khóa không nguyên, sử dụng table.count cho chúng.
local data = { a = 1, b = 2, c = 3 }
print(table.count(data)) -- 3
print(#data) -- 0, vì toán tử `#` không hoạt động với khóa không nguyên.
local array = { 1, 2, 3, 4, 5 }
print(#array) -- 5table.generate_sequence(max, start_from?, step?)
Tạo chuỗi số.
local seq1 = table.generate_sequence(5)
print(dump(seq1)) -- { 1, 2, 3, 4, 5 }
local seq2 = table.generate_sequence(10, 2, 2)
print(dump(seq2)) -- { 2, 4, 6, 8, 10 }
local seq3 = table.generate_sequence(1, 5, -1)
print(dump(seq3)) -- { 5, 4, 3, 2, 1 }table.only(table, only)
Trả về một bảng mới chứa dữ liệu chỉ với các khóa được chỉ định.
local data = { name = 'Alek', age = 25, city = 'Vladivostok', country = 'Russia' }
local filtered = table.only(data, { 'name', 'age' })
-- `filtered` chứa `{ name = 'Alek', age = 25 }`
print(filtered.name, filtered.age) -- 'Alek', 25
print(filtered.city) -- niltable.except(table, keys)
Trả về một bảng mới chứa dữ liệu không có các khóa được chỉ định.
(sao chép bảng, loại trừ các khóa được chỉ định)
local data = { name = 'Alek', age = 25, city = 'Vladivostok', country = 'Russia' }
local filtered = table.except(data, { 'age', 'country' })
-- `filtered` chứa `{ name = 'Alek', city = 'Vladivostok' }`
print(filtered.name, filtered.city) -- 'Alek', 'Vladivostok'
print(filtered.age, filtered.country) -- nil, niltable.merge(table1, table2, overwrite?)
Hợp nhất các bảng một cách đệ quy.
Mặc định, bảng đầu tiên không bị ghi đè, bảng mới được tạo.
local defaults = { theme = 'dark', font = { size = 12, family = 'Arial' } }
local user_config = { font = { size = 16 }, language = 'en' }
local merged = table.merge(defaults, user_config)
print(dump(merged))
-- {
-- theme = "dark",
-- font = {
-- size = 16,
-- family = "Arial",
-- },
-- language = "en",
-- }Ghi đè lên bảng đầu tiên:
table.merge(defaults, user_config, true)TIP
Nên sử dụng table.overwrite() để dễ đọc hơn.
table.join(table1, table2, recursively?)
Thêm các khóa bị thiếu từ table2 vào table1.
Các giá trị là bảng được sao chép bằng table.copy().
local base = { a = 1, b = 2 }
local addition = { b = 10, c = 3 }
table.join(base, addition)
print(dump(base)) -- { a = 1, b = 2, c = 3 }Nếu recursively là true, hàm sẽ được áp dụng đệ quy chỉ cho các giá trị là bảng trong cả table1 và table2.
local base = { a = 1, b = { c = 2 } }
local addition = { b = { c = 10, d = 20 } }
table.join(base, addition, true)
print(dump(base))
-- {
-- a = 1,
-- b = {
-- c = 2,
-- d = 20,
-- },
-- }table.overwrite(table1, table2)
Ghi đè hoàn toàn table1 bằng các giá trị từ table2.
Biến thể ngữ nghĩa cho table.merge(table1, table2, true).
table.merge_values(table1, table2)
Hợp nhất các giá trị của hai bảng thành một, loại bỏ trùng lặp.
Thứ tự được bảo tồn - đầu tiên các giá trị từ table1, sau đó từ table2 không có trong table1.
local table1 = { 'apple', 'banana', 'cherry' }
local table2 = { 'banana', 'date', 'apple', 'elderberry' }
local merged = table.merge_values(table1, table2)
print(dump(merged)) -- { 'apple', 'banana', 'cherry', 'date', 'elderberry' }table.map(table, callback, overwrite?)
Áp dụng hàm cho mỗi phần tử của bảng.callback: fun(value: any, key: any): any - chấp nhận giá trị và khóa, trả về giá trị mới.
Mặc định trả về một bảng mới.
local numbers = { 1, 2, 3, 4, 5 }
local squared = table.map(numbers, function(x) return x * x end)
print(dump(squared))
-- { 1, 4, 9, 16, 25 }
local data = { a = 10, b = 20 }
local doubled = table.map(data, function(value, key)
print(key, value)
return value * 2
end)
-- a 10
-- b 20
print(dump(doubled))
-- { a = 20, b = 40 }Nếu overwrite là true, thì hàm sửa đổi bảng gốc.
local data = { a = 10, b = 20 }
table.map(data, function(value, key) return value * 2 end, true)
print(dump(data)) -- { a = 20, b = 40 }table .walk/.each(table, callback)
Lặp qua bảng áp dụng hàm (không sửa đổi bảng).callback: fun(value: any, key: any): void - chấp nhận giá trị và khóa; không trả về gì cả.
local data = { a = 10, b = 20, c = 30 }
table.walk(data, function(value, key)
print(key, value)
end)
-- a 10
-- c 30
-- b 20Tên thay thế: table.each()
local data = { a = 10, b = 20, c = 30 }
table.each(data, function(value, key)
data[key] = value * 2
-- Không có gì ngăn cản truy cập vào upvalue `data`. Bây giờ `data` đã bị ghi đè.
end)
print(dump(data)) -- { a = 20, b = 40, c = 60 }table.multiply_each_value(table, multiplier_table)
Nhân mỗi giá trị của bảng với giá trị tương ứng từ multiplier_table theo khóa.
local data = { a = 10, b = 20, c = 30 }
local multipliers = { a = 2, b = 0.5, c = 3 }
local result = table.multiply_each_value(data, multipliers)
print(dump(result)) -- { a = 20, b = 10, c = 90 }
-- Các khóa không có nhân tử giữ nguyêntable.add_values(table1, table2, empty_value?, overwrite?)
Thêm các giá trị có cùng khóa từ hai bảng.
local table1 = { a = 10, b = 20 }
local table2 = { b = 5, c = 15 }
local result = table.add_values(table1, table2)
print(dump(result)) -- { a = 10, b = 25, c = 15 }
-- Với giá trị rỗng cho các khóa bị thiếu
local result2 = table.add_values(table1, table2, 0)
print(dump(result2)) -- { a = 10, b = 25, c = 15 }table.sub_values(table1, table2, empty_value?, overwrite?)
Trừ các giá trị table2 từ table1 cho các khóa giống nhau.
local table1 = { a = 10, b = 20, c = 30 }
local table2 = { b = 5, c = 10, d = 5 }
local result = table.sub_values(table1, table2)
print(dump(result)) -- { a = 10, b = 15, c = 20, d = -5 }table.mul_values(table1, table2, empty_value?, overwrite?)
Nhân các giá trị có cùng khóa từ hai bảng.
local table1 = { a = 2, b = 3 }
local table2 = { b = 4, c = 5 }
local result = table.mul_values(table1, table2)
print(dump(result)) -- { a = 2, b = 12, c = 5 }table.div_values(table1, table2, empty_value?, overwrite?)
Chia các giá trị table1 bằng các giá trị table2 cho các khóa giống nhau.
local table1 = { a = 10, b = 20, c = 30 }
local table2 = { b = 5, c = 10, d = 2 }
local result = table.div_values(table1, table2)
print(dump(result)) -- { a = 10, b = 4, c = 3, d = 0.5 }Math
math .limit/.clamp(value, min, max)
Giới hạn giá trị đến khoảng được chỉ định.
Tên thay thế: math.clamp().
local health = 150
local max_health = 100
local clamped_health = math.limit(health, 0, max_health)
print(clamped_health) -- 100math.is_within(value, min, max)
Kiểm tra rằng giá trị nằm trong khoảng một cách nghiêm ngặt (min < value < max).
print(math.is_within(5, 1, 10)) -- true
print(math.is_within(1, 1, 10)) -- false (giới hạn không bao gồm)
print(math.is_within(10, 1, 10)) -- falsemath.is_among(value, min, max)
Kiểm tra rằng giá trị nằm trong khoảng, bao gồm giới hạn (min <= value <= max).
print(math.is_among(5, 1, 10)) -- true
print(math.is_among(1, 1, 10)) -- true
print(math.is_among(10, 1, 10)) -- truemath.is_in_range(value, min, max)
Kiểm tra rằng giá trị nằm trong khoảng bán mở (min, max] (min < value <= max).
print(math.is_in_range(5, 1, 10)) -- true
print(math.is_in_range(1, 1, 10)) -- false (bằng giá trị tối thiểu)
print(math.is_in_range(10, 1, 10)) -- true (bằng giá trị tối đa)math.is_near(value, near, gap?)
Kiểm tra rằng giá trị gần với giá trị được chỉ định (|value - near| <= gap).
print(math.is_near(10, 12)) -- false (gap = 1 mặc định)
print(math.is_near(11, 12)) -- true
print(math.is_near(10, 12, 3)) -- true (gap = 3)math.quadratic_equation_roots(a, b, c)
Giải phương trình bậc hai của dạng y = a*x^2 + b*x + c.
local root1, root2 = math.quadratic_equation_roots(1, -5, 6)
print(root1, root2) -- 3, 2
-- Không có nghiệm thực
local r1, r2 = math.quadratic_equation_roots(1, 0, 1)
print(r1, r2) -- nil, nilmath.point_on_circle(radius, angle)
Tính toán một điểm trên vòng tròn.
local x, z = math.point_on_circle(5, math.pi/4)
print(x, z) -- tọa độ của một điểm trên vòng tròn bán kính 5 tại góc 45°Debug
__FILE__(depth?, full?)
Trả về tên tệp hiện tại hoặc tệp của hàm gọi tùy thuộc vào độ sâu stack.
depth?- độ sâu stack gọi (mặc định0)full?- hiển thị đường dẫn đầy đủ (mặc địnhfalse)
-- Lấy đường dẫn tương đối của tệp
print(__FILE__()) -- 'mods/Voxrame/helpers/src/lua_ext/debug.lua'
-- Lấy đường dẫn đầy đủ của tệp
print(__FILE__(0, true)) -- '/home/alek13/projects/my-game/mods/Voxrame/helpers/src/lua_ext/debug.lua'
-- Lấy tệp 2 cấp trên trong stack gọi
print(__FILE__(2)) -- tệp của hàm đã gọi hàm gọi__LINE__(depth?)
Trả về số dòng hiện tại hoặc số dòng của hàm gọi tùy thuộc vào độ sâu stack.
print(__LINE__()) -- 57
-- Lấy số dòng của hàm gọi
print(__LINE__(1)) -- số dòng trong tệp gọi__FILE_LINE__(depth?, full?)
Trả về tệp và dòng theo định dạng "đường/dẫn/tương/đối/tệp:dòng".
print(__FILE_LINE__()) -- 'mods/Voxrame/helpers/src/lua_ext/debug.lua:65'
-- Với đường dẫn đầy đủ
print(__FILE_LINE__(0, true)) -- '/home/alek13/projects/my-game/mods/Voxrame/helpers/src/lua_ext/debug.lua:65'__DIR__(depth?)
Trả về thư mục của tệp hiện tại hoặc tệp của hàm gọi tùy thuộc vào độ sâu stack.
print(__DIR__()) -- 'mods/Voxrame/helpers/src/lua_ext/'__FUNC__(depth?)
Trả về tên của hàm hiện tại.
function my_function()
print(__FUNC__()) -- 'my_function'
endprint_dump(depth, with_trace, ...)
In nội dung của tất cả các tham số được truyền ....
Trước khi in, thêm tên tệp và dòng @ <file>:<line>.
Nếu with_trace là true, thêm in stack trace.
NOTE
Nếu terminal của bạn hỗ trợ liên kết, mỗi @ <file>:<line> sẽ được liên kết đến mở IDE, xem readme.md để cấu hình.
TIP
Sử dụng pd() và pdt() để cú pháp ngắn gọn hơn. Xem ví dụ dưới đây.
pd(...)
Viết tắt cho print_dump. Gọi print_dump với with_trace == false.
local player_name = 'test_player'
local position = { x = 10, y = 20, z = 30 }
pd(player_name, position)output:
[93m@ [0m[33mmods/lord/Core/map/src/map/Corridor.lua[0m[97m:[0m[32m14[0m
[36mplayer_name:[0m "test_player"
[36m position:[0m {
x = 10,
y = 20,
z = 30,
}pdt(...)
Viết tắt cho print_dump traced. Gọi print_dump với with_trace == true.
local player_name = 'test_player'
local position = { x = 10, y = 20, z = 30 }
pdt(player_name, position)output:
[93m@ [0m[33mmods/lord/Core/map/src/map/Corridor.lua[0m[97m:[0m[32m14[0m
[3m[2m 1 [0m[93m@[0m [C][36m: in dofile[0m
[3m[2m 2 [0m[93m@ [0m[33mmods/lord/Core/builtin_ext/src/mod/require.lua[0m[97m:[0m[32m29[0m[36m: in require[0m
[3m[2m 3 [0m[93m@ [0m[33mmods/lord/Core/map/src/map.lua[0m[97m:[0m[32m9[0m[36m: in main[0m
[3m[2m 4 [0m[93m@ [0m [C][36m: in dofile[0m
[3m[2m 5 [0m[93m@ [0m[33mmods/lord/Core/builtin_ext/src/mod/require.lua[0m[97m:[0m[32m29[0m[36m: in require[0m
[3m[2m 6 [0m[93m@ [0m[33mmods/lord/Core/map/init.lua[0m[97m:[0m[32m4[0m[36m: in mod_init_function[0m
[3m[2m 7 [0m[93m@ [0m[33mmods/lord/Core/builtin_ext/src/mod.lua[0m[97m:[0m[32m80[0m[36m: in mod[0m
[3m[2m 8 [0m[93m@ [0m[33mmods/lord/Core/map/init.lua[0m[97m:[0m[32m3[0m[36m: in main[0m
[36mplayer_name:[0m "test_player"
[36m position:[0m {
x = 10,
y = 20,
z = 30,
}debug.measure(name, callback, print_result?)
Đo thời gian thực thi của hàm.
local function heavy_calculation()
local sum = 0
for i = 1, 2000000 do
sum = sum + math.random(1, 100) + math.sin(i)
end
end
-- Đo với kết quả in
debug.measure('calculation', heavy_calculation, true)
debug.measure('calculation', heavy_calculation, true)
debug.measure('calculation', heavy_calculation, true)
debug.measure('calculation', heavy_calculation, true)
debug.measure('calculation', heavy_calculation, true)
-- output:
-- Measure of [calculation]: Time: 42 ms ; Average: 42 ms
-- Measure of [calculation]: Time: 58 ms ; Average: 50 ms
-- Measure of [calculation]: Time: 58 ms ; Average: 53 ms
-- Measure of [calculation]: Time: 35 ms ; Average: 48 ms
-- Measure of [calculation]: Time: 33 ms ; Average: 45 ms
-- Đo không có kết quả
local time, avg, count = debug.measure('calculation', heavy_calculation)
print(time, avg, count)
local time, avg, count = debug.measure('calculation', heavy_calculation)
print(time, avg, count)
-- output:
-- 33.075 43.170833333333 6
-- 33.135 41.737142857143 7debug.mesure_print(name)
In thống kê của các phép đo trước đó name được thu được từ các lệnh gọi đến debug.measure(name, ....).
debug.mesure_print('calculation')
-- output:
-- Measure of [calculation]: Average time: 42 ms ; Last time: 33 ms ; Count of mesures: 7Global
errorf(message, ...)
Tương tự như error() trong Lua, nhưng message có thể là một chuỗi mẫu với các tham số được chỉ định, tương tự như string.format().
local player_name = nil
errorf('Người chơi '%s' không tìm thấy', player_name)
-- Lỗi: Người chơi 'nil' không tìm thấyoutput (khi debug được kích hoạt):
[93m@ [0m[33mmods/lord/Core/map/src/map/Corridor.lua[0m[97m:[0m[32m9[0m
[32m++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++[0m
[1m[91mERROR:[0m
[91m Người chơi `nil` không tìm thấy[0m
[1m[91mStack trace:[0m
[3m[2m 1 [0m[93m@[0m [C][36m: in error[0m
[3m[2m 2 [0m[93m@ [0m[33mmods/lord/Core/helpers/src/lua_ext/global.lua[0m[97m:[0m[32m9[0m[36m: in errorf[0m
[3m[2m 3 [0m[93m@ [0m[33mmods/lord/Core/map/src/map/Corridor.lua[0m[97m:[0m[32m12[0m[36m: in main[0m
[3m[2m 4 [0m[93m@ [0m [C][36m: in dofile[0m
[3m[2m 5 [0m[93m@ [0m[33mmods/lord/Core/builtin_ext/src/mod/require.lua[0m[97m:[0m[32m29[0m[36m: in require[0m
[3m[2m 6 [0m[93m@ [0m[33mmods/lord/Core/map/src/map.lua[0m[97m:[0m[32m9[0m[36m: in main[0m
[3m[2m 7 [0m[93m@ [0m [C][36m: in dofile[0m
[3m[2m 8 [0m[93m@ [0m[33mmods/lord/Core/builtin_ext/src/mod/require.lua[0m[97m:[0m[32m29[0m[36m: in require[0m
[3m[2m 9 [0m[93m@ [0m[33mmods/lord/Core/map/init.lua[0m[97m:[0m[32m4[0m[36m: in mod_init_function[0m
[3m[2m 10 [0m[93m@ [0m[33mmods/lord/Core/builtin_ext/src/mod.lua[0m[97m:[0m[32m80[0m[36m: in mod[0m
[3m[2m 11 [0m[93m@ [0m[33mmods/lord/Core/map/init.lua[0m[97m:[0m[32m3[0m[36m: in main[0m
[32m++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++[0mXử lý lỗi trong Luanti
WARNING
Stack trace sẽ chứa các dòng bổ sung, vì Luanti không chuyển level được chỉ định đến core.error_handler().
errorlf(message, level, ...)
Như trong errorf() bạn có thể truyền chuỗi định dạng và tham số, và cũng chỉ định mức trace.
errorlf('Lỗi trong dữ liệu', 3, 'giá trị: %d', 42)
-- Lỗi với trace 3 cấp trênassertf(condition, message, ...)
Tương tự như assert() trong Lua, nhưng làm message bạn có thể chỉ định chuỗi định dạng với tham số, tương tự như string.format().
Gọi
errorf()nếu điều kiệnconditionkhông được thỏa mãn.
-- Tiếp tục thực thi nếu player tồn tại, nếu không thì lỗi
local player = nil
assertf(player, 'Người chơi `%s` không tìm thấy', player)IO
io.file_exists(name)
Kiểm tra xem tệp có tồn tại hay không.
if io.file_exists('config.txt') then
print('Tệp cấu hình được tìm thấy')
else
print('Thiếu tệp cấu hình')
endio.dirname(path)
Trả về thư mục từ đường dẫn.
print(io.dirname('/home/user/project/file.txt')) -- '/home/user/project'
print(io.dirname('relative/path/file.txt')) -- 'relative/path'
print(io.dirname('file.txt')) -- '.'io.write_to_file(filepath, content, mode?)
Ghi nội dung vào tệp.
local success, error_code, error_message = io.write_to_file('data.txt', 'Hello, World!')
if success then
print('Dữ liệu được ghi thành công')
else
print('Lỗi ghi:', error_code, error_message)
end
-- Thêm vào cuối tệp
io.write_to_file('log.txt', 'Mục mới\n', 'a')io.read_from_file(filepath, mode?)
Đọc toàn bộ nội dung từ tệp.
Trả về chuỗi với nội dung tệp nếu thành công hoặc false, error_code, error_message nếu lỗi.
local content = io.read_from_file('config.json')
if content then
print('Nội dung tệp:', content)
else
print('Lỗi đọc tệp')
endXử lý lỗi
local success, error_code, error_message = io.read_from_file('nonexistent.txt')
if not success then
print('Lỗi:', error_code, error_message)
end
-- Lỗi: 2 nonexistent.txt: No such file or directoryhoặc:
local success = io.read_from_file('nonexistent.txt')
if not success then
local error_code, error_message = io.get_file_error()
print('Lỗi:', error_code, error_message)
end
-- Lỗi: 2 nonexistent.txt: No such file or directoryĐọc ở chế độ nhị phân
local binary_content = io.read_from_file('image.png', 'rb')
if binary_content then
print('Kích thước tệp:', #binary_content, 'byte')
endio.get_file_error()
Trả về mã và thông báo lỗi cuối cùng từ các hàm io.read_from_file() hoặc io.write_to_file().
local success = io.read_from_file('nonexistent.txt')
if not success then
local error_code, error_message = io.get_file_error()
print('Lỗi:', error_code, error_message)
end
-- Output: Lỗi: 2 nonexistent.txt: No such file or directorylocal success = io.write_to_file('/readonly/file.txt', 'data')
if not success then
local error_code, error_message = io.get_file_error()
print('Lỗi ghi:', error_code, error_message)
end
-- Output: Lỗi ghi: 13 /readonly/file.txt: Permission deniedOS
os.DIRECTORY_SEPARATOR
Dấu phân cách thư mục cho hệ điều hành hiện tại.
local DS = os.DIRECTORY_SEPARATOR
print(DS) -- '/' trên Linux/Mac, '\' trên Windows
print('folder' .. DS .. 'file.txt')
-- trên Linux/Mac: 'folder/file.txt'
-- trên Windows: 'folder\file.txt'