[Lua] 函式定義與呼叫中,t.f() 和 t:f() 的差別

[Lua] 函式定義與呼叫中,t.f() 和 t:f() 的差別

Lua 可以在 table 上定義函式,看起來會有點像是 C/C++ 的類別函式。

不過它有兩種定義方式,一種是用 

.
. ,一種是用 
:
: ,

我常常搞不懂,今天決定來實驗一下~

 

下面定義一個 table  

t
t ,

然後分別定義一個 

t.f()
t.f() 和 
t:g()
t:g() 函式:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
> t = {a=1, b=2}
> function t.f() print("in f function") end
> function t:g() print("in g function", self.a, self.b) end
> t = {a=1, b=2} > function t.f() print("in f function") end > function t:g() print("in g function", self.a, self.b) end
> t = {a=1, b=2}
> function t.f() print("in f function") end
> function t:g() print("in g function", self.a, self.b) end

 

以 

t.f()
t.f() 來說,它可以直接被呼叫:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
> t.f()
in f function
> t.f() in f function
> t.f()
in f function

 

但如果呼叫 

t.g()
t.g() 會失敗,錯誤訊息是說 
self
self 是 nil,這是為什麼呢?

看起來是因為 

t:g()
t:g() 函式定義其實就代表 
t.g(self)
t.g(self)  (: 寫法是語法糖),

因此直接呼叫 

t.g()
t.g() 時,相當於 
self
self 給了 nil:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
> t.g()
stdin:1: attempt to index a nil value (local 'self')
stack traceback:
stdin:1: in function <stdin:1>
(...tail calls...)
[C]: in ?
> t.g() stdin:1: attempt to index a nil value (local 'self') stack traceback: stdin:1: in function <stdin:1> (...tail calls...) [C]: in ?
> t.g()
stdin:1: attempt to index a nil value (local 'self')
stack traceback:
    stdin:1: in function <stdin:1>
    (...tail calls...)
    [C]: in ?

 

如果是用

t:g()
t:g() 方式呼叫的話,相當於呼叫  
t.g(t)
t.g(t) ,

也就是把 

t
t 代入  
self
self 裡面,

因此函式 

g()
g() 裡面就可以正確的拿到 
self.a
self.a 和 
self.b
self.b 等值:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
> t:g()
in g function 1 2
> t:g() in g function 1 2
> t:g()
in g function	1	2

 

Lua 裡也可以把函式指定到一個變數裡面,這時會怎麼樣呢?

我們可以拿這變數當函式一樣使用:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
> h = t.f
> h()
in f function
> h = t.f > h() in f function
> h = t.f
> h()
in f function

 

但如果是 

t.g
t.g 的話,這裡呼叫 
h()
h() 就等於呼叫 
t.g()
t.g() ,

因此會和前面一樣遇到 

self
self 為 nil 的問題:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
> h = t.g
> h()
stdin:1: attempt to index a nil value (local 'self')
stack traceback:
stdin:1: in function 'h'
(...tail calls...)
[C]: in ?
> h = t.g > h() stdin:1: attempt to index a nil value (local 'self') stack traceback: stdin:1: in function 'h' (...tail calls...) [C]: in ?
> h = t.g
> h()
stdin:1: attempt to index a nil value (local 'self')
stack traceback:
    stdin:1: in function 'h'
    (...tail calls...)
    [C]: in ?

 

那要怎麼正確的呼叫

h()
h() 函式呢?

其實就和呼叫

t.g()
t.g() 函式一樣,把  
t
t 代入  
self
self 裡面:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
> h(t)
in g function 1 2
> h(t) in g function 1 2
> h(t)
in g function	1	2

 

Lua 中 

.
.
:
:的分別大概就是這樣囉~

(本頁面已被瀏覽過 162 次)

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料