一般来说,语法:
for k, v in pairs(t) do
....
end
Run Code Online (Sandbox Code Playgroud)
相当于:
for k, v in next, t do
....
end
Run Code Online (Sandbox Code Playgroud)
但如果t有一个__pairsmetamethod怎么办?标准next()功能会检查这个吗?如果没有,那么在迭代表时总是使用pairs并且从不next()直接调用是不是更好?
有没有人知道lua 5.2的实际实现.metamethod __pairs?换句话说,我如何__pairs在metatable中实现metame方法,以便它与...完全相同pairs()?
我需要覆盖__pairs并希望跳过我在表中添加的一些虚拟变量.
我正在创建一个Array类,为表添加更多用法.我有一个metamethod,允许我组合两个表,例如:
数组(5)..数组(6,10)应该给你{5,6,10}
我知道我可以使用两个循环来做到这一点,但我正在努力使我的代码尽可能干净和高效.解压缩我遇到了一个问题.我正在尝试连接两个表,但它不包括所有值.这是我的代码和输出:
local Array = {}
Array.__index = Array
function Array.__concat(self, other)
return Array.new(unpack(self), unpack(other))
end
function Array:concat(pattern)
return table.concat(self, pattern)
end
function Array.new(...)
return setmetatable({...}, Array)
end
setmetatable(Array, {__call = function(_, ...) return Array.new(...) end})
local x = Array(5, 12, 13) .. Array(6, 9) --concatenate two arrays
print(x:concat(", "))
Run Code Online (Sandbox Code Playgroud)
OUTPUT: 5, 6, 9 (I want it to be "5, 12, 13, 6, 9")
我想知道是否有办法逃避__metatable元方法.我知道没有一个,但我正在尝试做这样的事情,但显然__metatable会阻止这种情况发生:
-- pretend that there is a __metatable field given to a table
setmetatable(_G, {__index = {None="No indexes"}})
-- error: (the string given to the __metatable metamethod)
Run Code Online (Sandbox Code Playgroud)
我在这里尝试做的只是逃避__metatable字段,只是允许自己在_G上设置metatable,它已经有一个.我知道这是不可能做到的,但是我想问一下是否还有机会绕过?
我正试图在Lua中使用我自己的长度方法来处理字符串.我已成功覆盖了字符串的len()方法,但我不知道如何为#manrator执行此操作.
orig_len = string.len
function my_len(s)
print(s)
return orig_len(s)
end
string.len = my_len
abc = 'abc'
Run Code Online (Sandbox Code Playgroud)
如果我打电话:
print(abc:len())
Run Code Online (Sandbox Code Playgroud)
它输出:
abc
3
Run Code Online (Sandbox Code Playgroud)
但
print(#abc)
Run Code Online (Sandbox Code Playgroud)
仅输出'3',这意味着它称为原始长度函数而不是我的.有没有办法让#调用我的长度函数?
我对使用"."的以下两种语法感到困惑.
根据我的理解,__index当一个键不存在于表中但存在于其元表中时调用.那么为什么列表会调用__index然后将其自身分配给list.__index?
list = {}
list.__index = list
setmetatable(list, { __call = function(_, ...)
local t = setmetatable({length = 0}, list)
for _, v in ipairs{...} do t:push(v) end
return t
end })
function list:push(t)
if self.last then
self.last._next = t
t._prev = self.last
self.last = t
else
self.first = t
self.last = t
end
self.length = self.length + 1
end
.
.
.
local l = list({ 2 }, {3}, {4}, { 5 …Run Code Online (Sandbox Code Playgroud)