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