这是我对这个令人难以置信的社区的第一个问题. 在这些日子里,我正在为自己写一个Lua模块.这是问题的最小部分代码 mt = {}bf = {}-------------- bf.new --------------function bf.new(A) local out = A se
在这些日子里,我正在为自己写一个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时,我有我需要的东西.当我通过metamethod使用bf.compare时,它只给我一个“标量”值为true.
有什么建议吗?
编辑
这是输出:
What I want true true false true false false true true true false false false What I get true >Exit code: 0Lua manual声明了__lt元方法的伪代码:
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
如果有一个metamethod,那么这行返回不是h(op1,op2)只返回处理程序h返回的singel(第一个)值,因为不是一元运算符.作为第二个效果,它将处理程序输出转换为标量:not {} == false,而不是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!