2017-06-01 60 views
1

我想創建一個包含另一個表的功能,像這樣的表:如何在Lua中創建方法的映射?

party_animal = {} 

function party_animal:dance() 
    -- dance 
end 

function party_animal:dance_furiously() 
    -- extreme dance 
end 

method_map = { 
    'idea_one': party_animal:dance, 
    'idea_two': party_animal:dance_furiously, 
} 

然後,這個我可以援引的這樣的一個功能:method_map[1][2]()。當我使用.運營商代替:時,我可以得到此工作,但我想訪問self

我得到的錯誤是這樣的:

stdin:2: '}' expected (to close '{' at line 1) near ':' 
+0

method_map [1] [2]。 method_map [1]爲零,因此你不能索引method_map [2]。即使method_map [1]是一個表,method_map [1] [2]也是零,你也不能調用nil值。 – Piglet

+0

這是由於我使用錯誤的表格語法? – Matt

+1

@MattDeacalionStevens不,這是因爲您在創建表格時嘗試使用字符串鍵並嘗試使用數字鍵訪問值。 'table [1]'嘗試訪問使用'table [1] = foo'或'table = {foo}'定義的鍵。總之,如果你省略'{}'中的鍵,那麼所有的值將被編號爲從* 1 *開始的數字。 'table = {「a」,「b」,「c」}'將導致'table [1] ==「a」'。 – Green

回答

4

從Lua的參考手冊:https://www.lua.org/manual/5.3/manual.html#3.4.9

表構造器是創建表的表達式。每次評估構造函數時,都會創建一個新表。構造函數可以是 ,用於創建空表或創建表並初始化其字段的某些 。對構造的一般語法

tableconstructor ::= ‘{’ [fieldlist] ‘}’ 
fieldlist ::= field {fieldsep field} [fieldsep] 
field ::= ‘[’ exp ‘]’ ‘=’ exp | Name ‘=’ exp | exp 
fieldsep ::= ‘,’ | ‘;’ 

形式[EXP1] = EXP2中的每一個字段添加到新的表中的條目與 鍵EXP1和值EXP2。表單name = exp的字段爲 ,等效於[「name」] = exp。最後,表單exp的字段爲 ,等同於[i] = exp,其中i是連續的整數,從1開始 ,其他格式的字段不影響此計數。

正如你看到類似

method_map = {'idea_one' : party_animal:dance} 

是不可能的,因爲它爲表構造無效語法。

替換:with =並移除「'使其成爲有效的表達式。

method_map = {idea_one = party_animal:舞蹈}將避免該錯誤消息

標準輸入:2: '}' 預期(以關閉 '{' 在第1行)鄰近 ':'

但是你會看到關於缺少函數參數的另一個錯誤信息。

這是因爲冒號操作符只對函數調用和定義有效。不適用於您實際想要執行的表格元素索引。

method_map = {idea_one = party_animal.dance}不會導致任何錯誤。

當然,你不能通過自己訪問party_animal。

我們該如何做到這一點?調用method_map:dance()將自引用method_map。

但是,如果我們使用語法糖用冒號運算符, 寫

method_map = {idea_one = function() return party_animal.dance(party_animal) end}

或等值

method_map = {idea_one = function() return party_animal:dance() end}

我們終於得到我們想要的東西。

現在自我將把party_animal如果我們調用method_map:dance()

+1

最後一個例子可以改爲'method_map = {idea_one = function()return party_animal:dance()end}'。 – nobody

+0

@當然沒有人哦。我添加了可選的語法糖版本 – Piglet

4
party_animal = {} 

function party_animal:dance() 
    -- dance 
end 

function party_animal:dance_furiously() 
    -- extreme dance 
end 

method_map = { 
    idea_one = party_animal.dance, 
    idea_two = party_animal.dance_furiously, 
} 

如預期這將工作。爲什麼?

首先,請注意您的表格主體已被更改爲匹配lua語法。您得到的錯誤是由Piglet以非常詳細的方式指出的無效表定義引起的。

其次,功能

function table:foo() end 

這個定義是相同的,因爲這一個

function table.foo(self) end 

傳遞函數參照不改變其參數。第一個參數仍然是self,如果您使用:調用此函數,則method_map將作爲self傳遞。

如果你想有party_animalselfmethod_map功能,您將需要使用額外的功能:

method_map = { 
    idea_one = function (...) return party_animal.dance(party_animal, ...) end, 
    idea_two = function (...) return party_animal.dance_furiously(party_animal, ...) end, 
} 

Lua 5.3 Reference Manual on function defining and calling

+0

我想他想通過自己訪問party_animal。在你的例子中,self會引用method_map。同樣使用表格作爲表格名稱並不是很好,因爲它已經用於提供Luas標準表格操作庫。 – Piglet

+0

@Piglet我對此有不同的理解:他擔心沒有':'的傳遞函數會導致無法訪問'self'。那麼我想我們應該等他。 – Green

+0

謝謝,這些徹底的解釋是輝煌的!這兩者都有點,我想傳遞一個表值作爲回調函數,但我希望函數能夠訪問'self' ...我明白':'操作符做到了這一點,但我無法得到它上班。 @ Piglet的答案的最後一點是現貨! – Matt