天天看點

【Lua程式設計基礎】實測Lua中點和冒号的差別

歡迎加入Unity業内qq交流群:956187480

Lua中成員函數的定義應該約定一種形式而不要點和冒号同時使用

一:在lua中面向對象程式設計的時候都要用冒号

使用冒号聲明函數的時候會把self作為參數隐藏在裡面,如果這個時候用點就會報錯

-- 基礎類方法 new
function Shape:new (o,side)
  o = o or {}
  setmetatable(o, self)
  self.__index = self
  side = side or 0
  self.area = side*side;
  self.perimeter = side*4;
  return o
end

-- 基礎類方法 printArea
function Shape:printArea ()
  print("面積為 :",self.area)
end

-- 基礎類方法 perimeter
function Shape:printperimeter ()
   print("面積為 :",self.perimeter)
end

-- 建立對象
myshape = Shape:new(nil,10)

myshape:printArea();
myshape:printperimeter();

---------------------------------------
面積為 : 100
周長為 : 40
[Finished in 0.1s]      

二:通路屬性和成員函數

我們可以使用點号(.)來通路類的屬性;我們可以使用冒号 : 來通路類的成員函數

myshape = Shape:new(nil,10)

myshape:printArea();
myshape:printperimeter();
print(myshape.area)


----------------------------
面積為 : 100
周長 :  40
100
[Finished in 0.1s]      

三:定義成員函數

Lua在函數定義時可以用點也可以用冒号

1.冒号聲明并調用

mytable ={a=2,b=3}
function mytable:Add(p)
  print(self)
  print(self.a)
  print(p)
end

mytable:Add(5)

-----------------------
table: 0035B850
2
5
[Finished in 0.1s]      

如果用冒号聲明的函數用點來調用 mytable.Add(5) 就會報錯或者出現self為nil的結果;

如果我們用點調用的話就需要傳入一個參數來充當self的角色

mytable ={a=2,b=3}
function mytable:Add(p)
  print(self)
  print(self.a)
  print(p)
end

mytable.Add(mytable,5)


-----------
table: 0075B850
2
5
[Finished in 0.1s]      

2.點聲明并調用

function mytable.Subtract(m,n)
  print(m)
  print(n)
end

mytable.Subtract(7,10)

---------------
7
10
[Finished in 0.1s]      

如果用冒号調用點聲明的函數:結果第一個不是我們傳入的參數m=7,而是一個table,而第二個才是我們傳入的參數7;

冒号調用以點定義的函數時,函數的參數的意義發生了變化,第一個參數強制變為了表示自身的變量(此時的m等同于self),

mytable:Subtract(7,10)
------------------------
table: 009BB8A0
7
[Finished in 0.1s]      

綜上:

1.冒号定義成員函數相比點定義可以減少一個需要傳入自身的參數,内部用self來通路自身;

2.點調用冒号定義的函數時,需要多傳入一個參數,傳入的第二個參數開始才對應于原函數的參數清單,函數内部用到的self則變為對應于傳入的第一個參數的普通變量,故傳入的第一個參數應該當是調用者自身(當然如果函數内部并沒有用到self則第一個參數随便傳個什麼都行);

3.冒号調用點定義的函數時,原函數的第一個參數強制變為等同于self的變量,傳入的參數從原參數的第二個參數開始才能一一對應上,是以通常這樣調用都是會出錯的(除非函數内部原本就把第一個參數在當self用...)。