Lua:冒号和点的函数调用行为不同

我最初在使用LOVE2D开发游戏时遇到了这个问题,但我无法弄清楚为什么。

就我所知,x:foo()只是x.foo(self)的语法糖,但与其他类组合使用会导致一些奇怪的行为。

基本上,我有两个程序

y = {}

function y:bar()
    return self.b
end

x = {}

function x:foo()
    return y.bar(self)
end

print(x.foo({b = 3}))

这将按预期打印3

y = {}

function y:bar()
    return self.b
end

x = {}

function x:foo()
    return y:bar()
end

print(x.foo({b = 3}))

但这会打印nil !!

我不明白,为什么这两个程序打印不同的东西?

点赞
用户731620
用户731620

x:foo()x.foo(x) 的语法糖

这意味着:

function x:foo()
    return y:bar()
end

实际上等同于:

function x:foo()
    return y.bar(y)
end
2018-10-12 14:02:24
用户5525442
用户5525442

重新审视你对 self 的使用

function x:foo()
    return y.bar(self) -- 等同于 y.bar(x)
end

function x:foo()
    return y:bar() -- 等同于 y.bar(y)
end
2018-10-12 15:22:33
用户2226988
用户2226988

x:foo() 只是 x.foo(self) 的语法糖。

在函数定义的上下文中是正确的,但在表达式中则不然。

function x.y.z:foo(a, b)
    print(self, a, b)
end

等同于

function x.y.z.foo(self, a, b)
    print(self, a, b)
end

在一个表字段中设置的函数定义可以是方法(使用 : )。如果键是有效的 Lua 标识符字符串,则可以嵌套表字段,包括方法和非方法,如 x.y.z

但是

print(x.y().z:foo(a, b))

等同于

local _ = x.y().z
print(_.foo(_, a, b))

使用方法调用语法时,冒号的左侧是一个仅评估一次的表达式 (x.y().z)。

2018-10-13 00:34:55