LUAのコロン、ポイント、self

3735 ワード


Luaプログラミングでは、tableのメンバー関数をポイントで定義したり、コロンを使用したりすることがよく見られますが、呼び出すときもそうです.では、ドットとコロンはどのような違いがありますか?それらとselfの間にはどのような関係がありますか?少し落ち着いて、次の答えは一つ一つあなたのために明らかになります.
 
まず例を見てみましょう
Class = {}
Class.__index = Class
  
function Class.new(x,y)
    local cls = {}
    setmetatable(cls, Class)
    cls.x = x
    cls.y = y
    return cls
end
function Class:test()
--    
-- function Class.test(self)
    print(self.x,self.y)
end
  
  
object = Class.new(10,20)  
object:test() --10 20
--    
object.test(object) --10 20

 
次のように表示されます.
(1)定義時:Class:test()とClass.test(self)は等価である.
(2)呼び出し時:object:test()とobject.test(object)は等価です.
 
しかし、例のコードを小さな変更すると、注意してください.
object = Class.new(10,20)
に改心
object = Class:new(10,20)
 
最終的な出力結果を当ててみましょうか?
最終的な出力結果:
table: 00FFE788 10
table: 00FFE788 10
 
あなたは驚いたのではないでしょうか.出力の結果は私たちの予想とは完全に雲泥の差です.では、なぜこのような出力結果が得られるのでしょうか.深層の原因は何ですか.次は一つ一つ来ます.
 
ここでは、呼び出し時にドットをコロンに変更し、コロンを使用するとselfパラメータが暗黙的に渡され、呼び出しオブジェクトを表す.これにより、Class:new(10,20)のような関数呼び出しには実際にself,10,20の3つの実パラメータがあるが、function Calss.new(x,y)のように点番号で実現される関数定義は実際には2つのパラメータしかなく,このようにパラメータ伝達の結果は
self ——> x
10 ——> y
20——>破棄
 
したがって,最終的に我々が印刷したxとyの値はselfと10であり,selfは実際にはtable Classである.もし私たちがClassをnewメソッドを少し修正すると以下のようになります.
 
function Class.new(self, x,y)
    local cls = {}
    setmetatable(cls, Class)
    cls.x = x
    cls.y = y
    return cls
end
 
または
 
function Class:new(x,y)
    local cls = {}
    setmetatable(cls, Class)
    cls.x = x
    cls.y = y
    return cls
end
 
最終的な出力結果は、次のようになります.
10 20
10 20
 
以上の解析から,ドット番号とコロンの最も主要な違いは,暗黙的パラメータselfが含まれているかどうかであり,コロンフォーマット定義や関数メソッドの呼び出しを使用すると,Luaは呼び出し元オブジェクトをデフォルトで隠すことができるが,隠すことはできないが,信じるか信じないかにかかわらず,そこにあり,左でも右でもない存在性を無視することはできないことが分かる.一方、ポイントフォーマットを使用して関数メソッドを定義または呼び出す場合、すべてのパラメータは表示されて宣言され、隠されず、どれだけの量があるかが示されます.したがって、呼び出し元オブジェクトを渡す必要がある場合は、宣言を表示する必要があります.
 
いくつかの例を見てみましょう
 
例1
a = { x = 1 } function a.fun(self)    print(self.x) end
a.fun(a)--出力1,a自身をパラメータとしてfun関数のselfに渡す
 
ポイントフォーマットでfunを定義し、ポイントフォーマットで関数funを呼び出します.定義時にselfパラメータが呼び出し元オブジェクトを受信するために与えられたことを表示します.呼び出し時には、呼び出し元オブジェクトが実パラメトリックとして入力されていることを表示する必要があります.
 
例2
function a:fun()     print(self.x) end
a.fun(a)
 
funはコロン形式で定義され、ポイント番号で呼び出されます.定義時に形パラメータselfが隠されています.見えませんが、selfは客観的に存在します.そのため、関数の内部でselfを直接使用することができます.呼び出し時に、呼び出し元オブジェクトが実パラメトリックとして入力されたことが表示されます.
 
例3
function a:fun()     print(self.x) end
a:fun()
 
funをコロン形式で定義および呼び出します.定義時に形パラメータselfが非表示になり、呼び出し時に呼び出し者オブジェクトという実パラメータも非表示になります.見えませんが、aという実パラメータは確かにselfに渡されます.
 
上で議論したのは関数メソッドの定義と呼び出しですが、非関数のデータメンバーについてはどうでしょうか.データ・メンバーへのアクセスも、コロンまたはドットで行うことができますか?残念ながら答えは否定的です.
 
例を見て
girl = {money = 200}
function girl.goToMarket(girl ,someMoney)    girl.money = girl.money - someMoney end
girl.goToMarket(girl ,100) print(girl.money)
 
出力結果
100
 
girl = {money = 200} function girl.goToMarket(girl ,someMoney)    girl.money = girl.money - someMoney end girl.goToMarket(girl ,100) print(girl:money)
 
出力結果
error:function arguments expected near ')'
 
上記の例では、非メンバー関数のデータ・メンバーへのアクセスは、ポイント番号の形式では使用できますが、コロンの形式では使用できません.
 
以上のように、文句のない約束をします.
luaでオブジェクト向けのプログラミングを行い,メンバーメソッドの宣言と呼び出しは統一的にコロン形式,データメンバーの呼び出しはすべてドット形式で行う.
 
(全文完了)