呼叫方法的冒號 |
|
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」會參照到什麼,可能是造成重複錯誤的第二或第三大原因。
可以說,存取欄位和執行方法呼叫在語意上是不同的,因此 Lua 中提供了符號差異。呼叫方法就像向物件傳送訊息給它。
請參閱 PIL [2],瞭解如何使用閉包,以便方法呼叫可以使用「.」語法。建立很多此類閉包可能效率不彰。有關此內容的更多資訊,請參閱 ObjectBenchmarkTests。
setfenv
來實作。無論如何,Lua 只有單一類型的表格索引運算(「.」),而「:」只是語法糖,這是一個特色。不像 JavaScript?,Lua 擁有可以在語言本身中使用的強大元機制;多重表格存取運算會顯著增加這些機制的複雜性。此外,將 Lua 描述為「基於原型的語言」並不準確。Lua 中開箱即用的狀態下沒有物件模型。您可以實作原型或經典物件模型。--John Belmonte
請參閱 [__methindex] 提案,其中使用不同的元方法來區分「:」和「.」。即使「:」是「.」的語法糖,也可以依賴這樣的事實:它們會產生不同的 VM 操作碼(前者會產生 SELF 操作碼)。