冒号用于方法调用

lua-users home
wiki

在 Lua 中,对实例方法的调用通常使用冒号 ":",而对类/工厂方法或字段的访问使用句点 "。"。

o:test()  -- method call. equivalent to o.test(o)
o.test()  -- regular function call. similar to just test()
o.x = 5   -- field access

有关行为的详细信息在 PIL 中讨论 [1]

这两种表示法与其他各种编程语言不同,包括其他基于原型的语言,如 JavaScript?,它们只使用句点。

// JavaScript example
function print() { WScript.echo("value:" + this.x); }
  
// constructor
function Test() {
  this.x = 5;
  this.print = print;
}
 
t = new Test();
 
print();    // call as function
t.print();  // call as method
t2 = t.print
t2();       // call as function
 
// outputs:
// value:undefined
// value:5
// value:undefined

Rici 指出,在 JavaScript? 中,为了使这种方法起作用,需要进行大量的魔法操作。错误预测 JavaScript? 中 "this" 的引用,可能是常见错误列表中的第 2 或第 3 位。

可以说,访问字段和执行方法调用在语义上是不同的,因此 Lua 中提供的表示法差异是合理的。调用方法就像向对象发送消息。

请参阅 PIL [2],了解使用闭包使方法调用可以使用 "。" 语法的示例。创建许多这样的闭包可能会效率低下。有关此方面的更多信息,请访问 ObjectBenchmarkTests

也许这也可以用 setfenv 实现。无论如何,Lua 只有一个类型的表索引操作("。"),而 ":" 只是语法糖,这是一个特性。与 JavaScript? 不同,Lua 拥有强大的元机制,可以在语言本身中使用;多个表访问操作会显著地使这些机制复杂化。此外,将 Lua 描述为 "基于原型的语言" 并不准确。Lua 本身没有对象模型。您可以实现原型或经典对象模型。--John Belmonte

IMO ":" 有其存在的意义。如果我不想总是将表作为第一个参数传递,我将如何调用存储在表中的函数?如果您这样做,表中函数的隐式 selfthis 参数将是自然而然的下一步。等等,我们不是将所有函数都存储在表中,例如 e._G 吗?我宁愿 Lua 不要走上 OObsession 的道路... --Frank Hirsch

另请参阅 [__methindex] 提案,该提案区分了 ':' 和 '.' 的不同元方法。它可以依赖于这样一个事实,即尽管 ':' 是 '.' 的语法糖,但它们会生成不同的 VM 操作码(前者会生成 SELF 操作码)。


最近更改 · 偏好设置
编辑 · 历史记录
最后编辑于 2010 年 6 月 19 日下午 9:43 GMT (差异)