Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop Lua:Class方法跳过第一个参数_Oop_Lua_Torch - Fatal编程技术网

Oop Lua:Class方法跳过第一个参数

Oop Lua:Class方法跳过第一个参数,oop,lua,torch,Oop,Lua,Torch,我试图在Lua中实现一个类,该类应该被实例化。但是,我得到一个错误,函数BatchLoader.init的输入参数被移位。我是否缺少实现一个self关键字作为python中任何成员函数的参数输入,或者类定义是否有其他错误 整个类代码如下所示(我去掉了不重要的部分): 但是,当我创建这个类,然后调用函数BatchLoader.init时,似乎y被解释为X,y被解释为sid等等。同样地,batch_size的输入被解释为sids,其中每个参数都从实际参数“移开” 下面的代码就是我在进入该BatchL

我试图在Lua中实现一个类,该类应该被实例化。但是,我得到一个错误,函数
BatchLoader.init
的输入参数被移位。我是否缺少实现一个
self
关键字作为python中任何成员函数的参数输入,或者类定义是否有其他错误

整个类代码如下所示(我去掉了不重要的部分):

但是,当我创建这个类,然后调用函数
BatchLoader.init
时,似乎y被解释为X,y被解释为sid等等。同样地,
batch_size
的输入被解释为
sids
,其中每个参数都从实际参数“移开”

下面的代码就是我在进入该
BatchLoader.init
之前调用的代码。这里的所有内容都按预期打印

local BatchLoader = require "../datahandler/BatchLoader.lua"
local trainLoader = BatchLoader:new()
print(X_data[{{1, 62000}, {}, {}}]:size()) -- Prints size(62000, 8, 16)
print(y_data[{{1, 62000}, {}}]:size())     -- Prints size(62000, 1)
print(sid_data[{{1, 62000}, {}}]:size())   -- Prints size(62000, 1)

local X_train, y_train, sid_train = trainLoader.init(
    X_data[{{1, a}, {}, {}}],
    y_data[{{1, a}, {}}],
    sid_data[{{1, a}, {}}],
    10, true)
我的问题是:这里的类声明有什么问题吗?这是我在Lua中的第一个OOP代码,非常感谢您的任何想法或帮助!:)

在Lua中,此语法:

o:f(x, y)
这是语法糖:

o.f(self, x, y)
这对于定义和调用都是正确的。在这里,您使用冒号语法定义
init
,并使用点语法调用它,因此它将不起作用,因为第一个参数将变成
self
,而其他参数将被一个关闭。解决方案是如下调用
init

local X_train, y_train, sid_train = trainLoader:init(
    X_data[{{1, a}, {}, {}}],
    y_data[{{1, a}, {}}],
    sid_data[{{1, a}, {}}],
    10, true)
这解决了这个问题,但请注意,在您的示例中,构造函数也完全被破坏。因为您使用冒号语法定义它,所以它总是返回
BatchLoader
表本身,而不是新实例。因为它是一个类方法,所以您应该编写它并使用点语法调用它:

function BatchLoader.new()
    local self = setmetatable({}, BatchLoader)
    self.epoch_done = false
    return self
end
local trainLoader = BatchLoader.new()
或者简单地说:

function BatchLoader.new()
    return setmetatable({epoch_done = false}, BatchLoader)
end
然后您还可以使用点语法调用它:

function BatchLoader.new()
    local self = setmetatable({}, BatchLoader)
    self.epoch_done = false
    return self
end
local trainLoader = BatchLoader.new()
为了理解这些内容,如果您还没有完成,我强烈建议您购买最新版本的Lua编程,并阅读有关面向对象编程的部分。

在Lua中,以下语法:

o:f(x, y)
这是语法糖:

o.f(self, x, y)
这对于定义和调用都是正确的。在这里,您使用冒号语法定义
init
,并使用点语法调用它,因此它将不起作用,因为第一个参数将变成
self
,而其他参数将被一个关闭。解决方案是如下调用
init

local X_train, y_train, sid_train = trainLoader:init(
    X_data[{{1, a}, {}, {}}],
    y_data[{{1, a}, {}}],
    sid_data[{{1, a}, {}}],
    10, true)
这解决了这个问题,但请注意,在您的示例中,构造函数也完全被破坏。因为您使用冒号语法定义它,所以它总是返回
BatchLoader
表本身,而不是新实例。因为它是一个类方法,所以您应该编写它并使用点语法调用它:

function BatchLoader.new()
    local self = setmetatable({}, BatchLoader)
    self.epoch_done = false
    return self
end
local trainLoader = BatchLoader.new()
或者简单地说:

function BatchLoader.new()
    return setmetatable({epoch_done = false}, BatchLoader)
end
然后您还可以使用点语法调用它:

function BatchLoader.new()
    local self = setmetatable({}, BatchLoader)
    self.epoch_done = false
    return self
end
local trainLoader = BatchLoader.new()
为了理解这些东西,如果您还没有做过,我强烈建议您购买最新版本的Lua编程,并阅读面向对象编程部分。

方法语法(使用
foo:bar
而不是
foo.bar
)自动引入
self
参数

在函数定义上,
函数Foo:bar(…)
相当于
函数Foo.bar(self…)
。在函数调用中,
foo:bar(…)
大致相当于
foo.bar(foo,…)
(后者计算
foo
两次)

让我们来分析一下您的代码:

function BatchLoader:new()
    setmetatable({}, BatchLoader) -- creates a table & throws it away
    self.epoch_done = false       -- self is the hidden first argument
    return self
end

local trainLoader = BatchLoader:new()  -- i.e. BatchLoader.new( BatchLoader )
这意味着你在有效地跑步

function BatchLoader:new()
    setmetatable({}, BatchLoader)
    BatchLoader.epoch_done = false
    return BatchLoader
end
这肯定不是你想要的。做你想做的事情的几种方法是

-- fixed creation scheme
function BatchLoader.new( )
   local self = { epoch_done = false }
   return setmetatable( self, BatchLoader )
end

-- acceptable uses:
local trainLoader = BatchLoader.new( )
local trainLoader = BatchLoader:new( ) -- ignores passed self

或者其他很多选择

您同样混淆了另一个调用的方法表示法:

function BatchLoader:init(X, y, sids, batch_size, argshuffle)
很好,相当于

function BatchLoader.init(self, X, y, sids, batch_size, argshuffle)
而你却错误地称之为

local X_train, y_train, sid_train = 
  trainLoader.init( X, y, ... )
(看看为什么一切都变了?)

使用
trainLoader:init(X,y,…)
trainLoader
传递为
self

方法语法(使用
foo:bar
而不是
foo.bar
)自动引入
self
参数

在函数定义上,
函数Foo:bar(…)
相当于
函数Foo.bar(self…)
。在函数调用中,
foo:bar(…)
大致相当于
foo.bar(foo,…)
(后者计算
foo
两次)

让我们来分析一下您的代码:

function BatchLoader:new()
    setmetatable({}, BatchLoader) -- creates a table & throws it away
    self.epoch_done = false       -- self is the hidden first argument
    return self
end

local trainLoader = BatchLoader:new()  -- i.e. BatchLoader.new( BatchLoader )
这意味着你在有效地跑步

function BatchLoader:new()
    setmetatable({}, BatchLoader)
    BatchLoader.epoch_done = false
    return BatchLoader
end
这肯定不是你想要的。做你想做的事情的几种方法是

-- fixed creation scheme
function BatchLoader.new( )
   local self = { epoch_done = false }
   return setmetatable( self, BatchLoader )
end

-- acceptable uses:
local trainLoader = BatchLoader.new( )
local trainLoader = BatchLoader:new( ) -- ignores passed self

或者其他很多选择

您同样混淆了另一个调用的方法表示法:

function BatchLoader:init(X, y, sids, batch_size, argshuffle)
很好,相当于

function BatchLoader.init(self, X, y, sids, batch_size, argshuffle)
而你却错误地称之为

local X_train, y_train, sid_train = 
  trainLoader.init( X, y, ... )
(看看为什么一切都变了?)


使用
trainLoader:init(X,y,…)
trainLoader
传递为
self

您已经用冒号(而不是点)定义了
BatchLoader:init
,所以您也必须用冒号来传递
trainLoader:init
。非常感谢,我的错误,太愚蠢了!您还可以编写类似于
函数Foo.init(…)local的代码,如果…==Foo然后uu,a,b=。。。否则a,b=。。。end print(a,b)end
您已经用冒号(而不是点)定义了
BatchLoader:init
,所以您必须使用
trainLoader:init
和冒号。非常感谢,我的错误,太愚蠢了!您还可以编写类似于
函数Foo.init(…)local的代码,如果…==Foo然后uu,a,b=。。。否则a,b=。。。结束打印(a、b)结束