在使用Lua使用闭包和递归从树形 struct 生成字符串时,我发现了一个意外的行为.
我将代码简化为这样,并制作了一个JS版本.JS版本的工作与预期一样,但我不明白为什么,也不知props 体是怎么回事.
代码是:
function union(children)
local union = {}
function union:method(p)
print("union method", p, #children)
-- rename p2 to p to make it work as expected
function f(p2, children)
print("union f", p, #children)
local result = nil
if #children == 1 then
result = children[1]:method(p)
elseif #children == 2 then
result = children[1]:method(p) .. children[2]:method(p)
else
local first_child = table.remove(children)
result = first_child:method(p) .. f(p, children)
end
return result
end
return f(p, children)
end
return union
end
function transform(children)
local child = children[1]
local transform = {}
function transform:method(p)
print("transform start")
res = child:method(p .. "TRANSFORMED ")
print("transform end")
return res
end
return transform
end
function leaf()
local leaf = {}
function leaf:method(p)
return p
end
return leaf
end
root = union({leaf(), leaf(), transform({union({leaf()})}) })
print(root:method("p"))
输出为:"pTRANSFORMED"
但我预计:"pTRANSFORMED pp"
总之,我不明白为什么"转换" node 会影响三片叶子,而不是只影响一片叶子.
JS代码为:
function union(children){
const union = {}
union.getField = (p) =>{
function f(p2, children){
console.log("union", p, p2, children.length)
let result = null
if (children.length == 1 ){
result = children[0].getField(p)
}else if ( children.length == 2 ){
result = children[0].getField(p) + children[1].getField(p)
}else {
const first_child = children.pop()
result = first_child.getField(p) + f(p, children)
}
return result
}
return f(p, children)
}
return union
}
function transform(children){
const child = children[0]
const transform = {}
transform.getField = (p)=>{
return child.getField(p + "TRANSFORMED ")
}
return transform
}
function leaf(){
const leaf = {}
leaf.getField = (p) =>{
return p
}
return leaf
}
const root = union([leaf(), leaf(), transform([union([leaf()])]) ])
console.log(root.getField("p"))