在Lua中,使用"的函数之间有什么区别:"和没有的功能?

时间:2014-10-26 18:50:35

标签: function inheritance lua arguments

假设我们有两个函数声明:

function MyData:New 
end

function New(MyData)
end

他们之间有什么区别?使用:在继承和OOP方面有什么特殊用途吗?我是否可以使用:调用使用:声明的函数?

我来自仅使用C# - 所以如果有任何比较,它会是什么?

3 个答案:

答案 0 :(得分:5)

改编自manual, end of §3.4.10

  

冒号语法用于定义方法,即具有隐式额外参数self的函数。因此,声明

     

function t:f (params) body end

     

的语法糖      

t.f = function (self, params) body end

答案 1 :(得分:2)

你应该搜索SO,因为有很多问题,但你有一组问题,所以我不能说这是重复的。

Q值。他们之间有什么区别? A.带冒号的方法会导致一个方法被添加到MyData表中,而Lua解释器会在调用第一个参数之前自动插入一个“self”,这个“self”指向MyData实例的“方法”正在被召唤。它与撰写MyData.New = function(self) end相同。第二个签名有一个名为MyData的参数,是一个全局函数。它与MyData表(或类)无关。

Q值。使用“:”在继承和OOP方面有什么特殊用途吗? A.不;它只是语法糖,因此当你致电MyData.New时,你可以写MyData:New()而不是笨重的MyData.New(MyData)。请注意,“new”函数通常用于创建类的实例,因此您不会将此类函数作为方法,而只是MyData表中的函数。对于继承和OOP,您使用metatables,这不会以任何特殊方式与以下内容交互:

Q值。我只能使用“:”来调用用“:”声明的函数吗? A.不,如上所述,它只是语法糖,你可以定义一种方式,并以不同的方式调用。

Q值。我来自仅使用C# - 所以如果有任何比较,它会是什么? A.对于功能,:就像是。在C#中,无论是在调用还是定义中使用。 “。”在Lua中更像是“属性”,C#中没有等效的函数。

MyData = {} -- a table 
function MyData.func(self) 
    print('hello')
end
MyData:func()
MyData.func(MyData) -- same as previous

function MyData:func2() -- self is implicit
    print('hello')
end
MyData:func2()
MyData.func2(MyData) -- same as previous

请注意,上面定义的MyData不是类,因为您无法创建它的“实例”(不执行其中未显示的额外工作)。绝对阅读Lua.org网站上的Lua在线书籍编程,对这些概念进行了大量有用的讨论。

答案 2 :(得分:1)

Lua本身没有声明的功能;它有函数定义表达式。您使用的语法是函数定义表达式和赋值的简写。

您的示例中唯一的区别是,在执行第一个语句时,创建了一个新函数并将其分配给变量MyData引用的表中的New字段,而第二个是对非字段变量的赋值(local ,如果先前已声明,则为全局)。

请记住,这些只是对创建的函数值的第一次引用。与任何其他值一样,您可以将函数的引用分配给任何变量,并将它们作为参数传递。

如果向正文中添加形式参数用法,那么还有另一个区别:第一个参数有一个名为self的隐式第一个参数。

如果向场景添加函数调用,则“:”语法与左侧的表达式一起使用。它应该引用一个表。右边的标识符应该是该表中的一个字段,它应该引用一个函数。左表达式的值作为第一个实际参数传递给函数,后面跟着任何其他参数。

带有“:”的函数定义称为方法。带有“:”的函数调用称为方法调用。您可以构造对函数值的函数调用,该函数值是表中的字段,第一个参数是使用您希望的任何函数调用语法对表的引用。 Lua方法定义和方法调用语法使其更容易,就好像该函数是实例方法一样。这样,Lua方法就像C#扩展方法。