との差 。そして:ルアで


174

関数呼び出しvia .とviaの違いについて混乱しています:

> x = {foo = function(a,b) return a end, bar = function(a,b) return b end, }
> return x.foo(3,4)
3
> return x.bar(3,4)
4
> return x:foo(3,4)
table: 0x10a120
> return x:bar(3,4)
3

何し:てるの?


回答:


237

コロンはself、最初のパラメーターとして渡すメソッドを実装するためのものです。したがってx:bar(3,4)、と同じである必要がありx.bar(x,3,4)ます。


55
ああ...オブジェクト指向の構文糖です。
Jason S、

7
丁度。リファレンスマニュアル全体では、「コロンの構文は、メソッド、つまり、暗黙の追加パラメーターselfを定義する関数を定義するために使用されます」と述べています。(5.0マニュアル、PDFページ19の下部)
BMitch

2
ああああ...私は公式文書がこれについてどこにあるのか尋ねるつもりでした、しかしあなたは私をそれに打ち負かしました。うまくやった。:-)
ジェイソンS

1
@keyle self最初のパラメータとそのプロパティ値として行くオブジェクトに依存します。
Hydroper

8
@keyleコロン構文は、呼び出しているオブジェクトがローカルでない場合、仮想マシンが一度しか取得しないため、少し高速になります。基本的に、2回object.method(object,args)取得するようなドット構文は1回しか取得しません。がグローバル、アップバリュー、またはテーブルフィールドの場合は、よりも高速です。よりも速くなることはありません。objectobject:method(arg)objectobject:..:
negamartin

28

定義については、自分で手動で指定するのとまったく同じです。コンパイル時に同じバイトコードが生成されることもあります。すなわちfunction object:method(arg1, arg2)と同じfunction object.method(object, arg1, arg2)です。

使用時:ほぼ同じです.-特別な種類の呼び出しが内部で使用され、確認objectと計算/アクセスの可能性のある副作用が1回だけ計算されます。object:method(arg1, arg2)それ以外の呼び出しはと同じobject.method(object, arg1, arg2)です。


21

完全に正確にobj:method(1, 2, 3)は、と同じです

do
  local _obj = obj
  _obj.method(_obj, 1, 2, 3)
end

なぜローカル変数なのか?多くの人が指摘したように、一度取得するのは一度obj:method()だけ_ENVですobj。これは通常、速度を考慮するときに重要ですが、次の状況を考慮してください。

local tab do
  local obj_local = { method = function(self, n) print n end }
  tab = setmetatable({}, {__index = function(idx)
    print "Accessing "..idx
    if idx=="obj" then return obj_local end
  end})
end
tab.obj.method(tab.obj, 20)
--> Accessing obj
--> Accessing obj
--> 20
tab.obj:method(10)
--> Accessing obj
--> 10

__indexメタメソッドが単に何かを出力する以上のことを想像してください。カウンターを増やしたり、何かをファイルに記録したり、データベースからランダムなユーザーを削除したりしたとします。これを2回行うか1回だけ行うかには大きな違いがあります。この場合、との間には明らかな違いがobj.method(obj, etc)ありobj:method(etc)ます。


あなたは本当にそのようなものについて心配するべきではありません。あなたがしなければならない場合は、あなたのアーキテクチャにひどく何かが間違っています。
ヴァルはモニカを復活させる

2
それは逆です。優れたコードでは、無関係なコードの実装の詳細について何も仮定しないでください。関数呼び出しはメモ化される場合とされない場合があります。それは、必要以上に頻繁に呼び出すことが良い習慣であることを意味しません。
DarkWiiPlayer
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.