gpt4 book ai didi

Lua:__lt 元方法设置无法正常工作

转载 作者:行者123 更新时间:2023-12-04 14:15:35 28 4
gpt4 key购买 nike

这是我对这个令人难以置信的社区的第一个问题。

这些天来,我正在为自己编写一个 Lua 模块。这是有问题的代码的最小部分

mt = {}

bf = {}

------------
-- bf.new --
------------
function bf.new(A)

local out = A
setmetatable(out,mt)
return out

end

-----------------
-- bf.tostring --
-----------------
function bf.tostring(A)

local typeA = type(A)
local out = ""
if typeA=="number" or typeA=="boolean" then
print(tostring(A))
elseif typeA=="table" then
local col = ""
local m = #A
local typeA1 = type(A[1])
for i=1,m do
if typeA1=="table" then
n = #A[1]
for j=1,n do
out = out.." "..tostring(A[i][j])
if j==n then
out = out.."\n"
end
end
elseif (typeA1=="number" or typeA1=="boolean") then
row = row.." "..tostring(A[i][j])
end
end
end
return out
end

-----------------------------
-- bf.compare(A,logical,B) --
-----------------------------
function bf.compare(A,logical,B)

if (logical~="<" and
logical~=">" and
logical~="<=" and
logical~=">=" and
logical~="==" and
logical~="~=") then
error("second input input must be a logical operator written into a string")
end
local out = {}
local ind = {}
local count = 0
if type(B)=="number" then
if type(A[1])=="table" then
for i=1,#A do
out[i] = {}
for j=1,#A[1] do
loadstring("cond ="..A[i][j]..logical..B)()
if cond then
out[i][j] = true
count = count+1
ind[count] = (i-1)*#A[1]+j
else
out[i][j] = false
end
end
end
elseif type(A[1])=="number" then
for j=1,#A do
loadstring("cond ="..A[j]..logical..B)()
if cond then
out[j] = true
count = count+1
ind[count] = j
else
out[j] = false
end
end
end
else
if (type(A[1])=="table" and type(B[1])=="table") then
if (#A==#B and #A[1]==#B[1]) then
for i=1,#A do
out[i] = {}
for j=1,#A[1] do
loadstring("cond ="..A[i][j]..logical..B[i][j])()
if cond then
out[i][j] = true
count = count+1
ind[count] = (i-1)*#A[1]+j
else
out[i][j] = false
end
end
end
else
error("The comparison can be done between "..
"two matrix with same dimension "..
"or between a matrix with a scalar value")
end
elseif (type(A[1])=="number" and type(B[1])=="number") then
if (#A==#B) then
for j=1,#A do
loadstring("cond ="..A[j]..logical..B[j])()
if cond then
out[j] = true
count = count+1
ind[count] = j
else
out[j] = false
end
end
else
error("Comparison between "..
"two vector with different dimension")
end
else
error("The comparison can be done between "..
"two matrix with same dimension "..
"or between a matrix with a scalar value")
end
end
return setmetatable(out,mt)--,ind

end

------------------------
-- metamethod setting --
------------------------
mt.__tostring = bf.tostring
mt.__lt = function(A,B) return bf.compare(A,"<",B) end

--------------------------
-- use of my metamethod --
--------------------------
A = bf.new{{1,2,3,4},{5,6,7,8},{9,10,11,12}}
B = bf.new{{3,6,1,8},{1,3,87,20},{11,2,5,7}}
C1 = bf.compare(A,"<",B)
C2 = A<B
print("What I want")
print(C1)
print("What I get")
print(C2)

如果你运行这个小脚本,你可以看到当我直接使用函数 bf.compare 时,我得到了我需要的东西。当我通过元方法使用 bf.compare 时,它​​只给了我一个 true 的“标量”值。

有什么建议吗?

编辑

这是输出:
What I want
true true false true
false false true true
true false false false

What I get
true
>Exit code: 0

最佳答案

Lua manual声明 __lt metamethod 的伪代码:

function lt_event (op1, op2)
if type(op1) == "number" and type(op2) == "number" then
return op1 < op2 -- numeric comparison
elseif type(op1) == "string" and type(op2) == "string" then
return op1 < op2 -- lexicographic comparison
else
local h = getbinhandler(op1, op2, "__lt")
if h then
return not not h(op1, op2)
else
error(···)
end
end
end

如果有元方法,那么这一行 return not not h(op1, op2)仅返回处理程序返回的单个(第一个)值 h ,如 not是一元运算符。作为第二个效果,它将处理程序输出转换为标量: not {} == false , 和 not false == true .

另一个需要注意的小事:Lua 表总是通过引用传递。将表分配给另一个变量只会导致复制指针。因此,如果您执行以下操作:
function myFun(A)
local out=A
out[1]='bar'
return out
end
A={'foo',1,2,3}
B=myFun(A)
print(table.concat(B,', ')) -- OK
print(table.concat(A,', ')) -- A also changed, because:
print(A,B) -- they are the same table!

关于Lua:__lt 元方法设置无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8605265/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com