lua面向對象編程之點號與冒號的差異詳細比較

首先,先來一段在lua創建一個與對象的代碼

Class = {}
Class.__index = Class
function Class:new(x,y)
local temp = {}
setmetatable(temp, Class)
temp.x = x
temp.y = y
return temp
end
function Class:test()
print(self.x,self.y)
end
object = Class.new(10,20)
object:test()

猜一下會輸出什么結果呢?

輸出:

>lua -e "io.stdout:setvbuf 'no'" "object.lua"
20??? nil
>Exit code: 0

我們的y值怎么沒了?

這個原因很簡單,因為我們創建一個對象的時候使用了一個 . 號

lua程序設計第二版中,有提到當一項操作所作用的”接受者”,需要一個額外的參數來表示該接受者,這個參數通常稱為self或this

然后我們在這段代碼加上 self

Class = {}
Class.__index = Class
function Class:new(x,y)
local temp = {}
setmetatable(temp, Class)
temp.x = x
temp.y = y
return temp
end
function Class:test()
print(self.x,self.y)
end
object = Class.new(self,10,20)
object:test()

然后我們在看一下輸出

>lua -e "io.stdout:setvbuf 'no'" "object.lua"
10??? 20
>Exit code: 0

這下就正常了!!嗯,每次創建一個對象的時候都有寫一個self,會不會感覺很麻煩呢?lua提供了用冒號的方式在一個方法定義中添加一個額外的參數,以及在一個方法調用中添加一個額外的實參

然后代碼改成

Class = {}
Class.__index = Class
function Class:new(x,y)
local temp = {}
setmetatable(temp, Class)
temp.x = x
temp.y = y
return temp
end
function Class:test()
print(self.x,self.y)
end
object = Class:new(10,20)
object:test()

輸出正常:

>lua -e "io.stdout:setvbuf 'no'" "object.lua"
10??? 20
>Exit code: 0

如果,就這么完的話,本來是一件很歡樂的事情,但是,我嘗試了一下以下代碼

Class = {}
Class.__index = Class
function Class.new(x,y)
local temp = {}
setmetatable(temp, Class)
temp.x = x
temp.y = y
return temp
end
function Class:test()
print(self.x,self.y)
end
object = Class.new(10,20)
object:test()

出乎意料的是:

>lua -e "io.stdout:setvbuf 'no'" "object.lua"
10??? 20
>Exit code: 0

代碼正常運行….這個讓人很費解,本來,號對方法的操作是需要一個額外的接受者,第一段代碼已經說明了這個問題,但是,現在程序有正常運行,令我真是有費解…

然后,我接著嘗試又發現

Class = {}
Class.__index = Class
function Class.new(x,y)
local temp = {}
setmetatable(temp, Class)
temp.x = x
temp.y = y
return temp
end
function Class:test()
print(self.x,self.y)
end
object = Class:new(10,20)
object:test()

輸出結果:

>lua -e "io.stdout:setvbuf 'no'" "object.lua"
table: 003CACA0??? 10
>Exit code: 0

這個只不過跟第一段代碼和冒號的位置調換了一下,就出現了這樣的結果…

如果,你仔細想想,這里第一段代碼的區別,可以發現,其實,這里就可以證明了冒號其實就是默認傳了一個實參到方法中

為了證明冒號的作用,我改動了一下代碼

Class = {}
Class.__index = Class
function Class:new(x,y)
local temp = {}
setmetatable(temp, Class)
temp.x = x
temp.y = y
return temp
end
function Class.test()
print(self.x,self.y)
end
object = Class:new(10,20)
object:test()

輸出的結果是:

>lua -e "io.stdout:setvbuf 'no'" "object.lua"
lua: object.lua:15: attempt to index global 'self' (a nil value)
stack traceback:
??? object.lua:15: in function 'test'
??? object.lua:21: in main chunk
??? [C]: ?
>Exit code: 1

從這里的錯誤可以看出,沒有self這個參數,竟然,方法用的是號,那我們試一下把對象傳進去看下能不能正常運行

Class = {}
Class.__index = Class
function Class:new(x,y)
local temp = {}
setmetatable(temp, Class)
temp.x = x
temp.y = y
return temp
end
function Class.test()
print(self.x,self.y)
end
object = Class:new(10,20)
object:test(object)

遺憾的是這樣的改動是錯誤的,錯誤的結果也是一樣的

>lua -e "io.stdout:setvbuf 'no'" "object.lua"
lua: object.lua:15: attempt to index global 'self' (a nil value)
stack traceback:
??? object.lua:15: in function 'test'
??? object.lua:21: in main chunk
??? [C]: ?
>Exit code: 1

那我們這次嘗試下想剛才那樣,把方法的號搞成一致看下效果怎樣

Class = {}
Class.__index = Class
function Class:new(x,y)
local temp = {}
setmetatable(temp, Class)
temp.x = x
temp.y = y
return temp
end
function Class.test()
print(self.x,self.y)
end
object = Class:new(10,20)
object.test()

遺憾的是跟之前不一樣,還是不能運行

Class = {}
Class.__index = Class
function Class:new(x,y)
local temp = {}
setmetatable(temp, Class)
temp.x = x
temp.y = y
return temp
end
function Class.test()
print(self.x,self.y)
end
object = Class:new(10,20)
object.test()
?
回想一下,冒號的作用可以傳遞一個實參,對于方法的操作我們需要一個接受者,那么進行以下的改動
Class = {}
Class.__index = Class
function Class:new(x,y)
local temp = {}
setmetatable(temp, Class)
temp.x = x
temp.y = y
return temp
end
function Class:test()
print(self.x,self.y)
end
object = Class:new(10,20)
object.test(object)

這次輸出就正常了

>lua -e "io.stdout:setvbuf 'no'" "object.lua"
10??? 20
>Exit code: 0

這段代碼告訴了我們,想要操作一個方法就一定需要一個額外參數來表示該值,對于號,我們必須顯示傳遞一個實參,才能使程序正常運行,而為了方便,我們可以直接使用冒號來簡化操作.

結論:

羅嗦了半天其實,可以用一下一句話來避免這個問題:

lua進行面向對象的編程,聲明方法調用方法統一用冒號,對于屬性的調用全部用

?

搞這么多其實,只是加深理解罷了…歡迎交流批評..

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/444998.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/444998.shtml
英文地址,請注明出處:http://en.pswp.cn/news/444998.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

lua __index __newindex upvalue 示例

項目中有個公會對象,數據大部分存在data中,之前都是 u.data.point這樣訪問,太麻煩了。 于是通過設置__index 使之可以直接訪問屬性,u.point。 但是還是不能直接改屬性,u.point 4,所以再設置了__newindex…

leecode26 刪除排序數組中的重復項

給定一個排序數組,你需要在原地刪除重復出現的元素,使得每個元素只出現一次,返回移除后數組的新長度。 不要使用額外的數組空間,你必須在原地修改輸入數組并在使用 O(1) 額外空間的條件下完成。 示例 1: 給定數組 nums [1,1,2…

MachineLearning(6)-Daviad Silver強化學習課程脈絡整理

強化學習-Daviad Silver強化學習課程脈絡整理1.lecture1 introduction1.1 強化學習簡介1.2 強化學習類別1.3 強化學習的主要問題2.lecture2 Markov Decision Process2.1 MP,MRP,MDP2.2 Bellman Eqution--貝爾曼方程2.3 Bellman Eqution--貝爾曼期望方程2.4 最優策略2.5 最優值函…

lua的VS或者VC環境的搭建調試

安裝完LuaForWindows_v5.1.4 打開vs tools->options->projects->directories executable files 選項添加lua安裝以后的路徑,我的是 C:\Program Files\Lua\5.1 include files選項添加lua include路徑,我的是 C:\Program Files\Lua\5.1include library files 選項添…

leecode53 最大子序列和

給定一個整數數組 nums ,找到一個具有最大和的連續子數組(子數組最少包含一個元素),返回其最大和。 示例: 輸入: [-2,1,-3,4,-1,2,1,-5,4], 輸出: 6 解釋: 連續子數組 [4,-1,2,1] 的和最大,為 6。 思路:…

在頁游中LUA的應用(1)

通常,你希望在你的游戲開始的時候讀取一些信息,以配置你的游戲,這些信息通常都是放到一個文本文件中,在你的游戲啟動的時候,你需要打開這個文件,然后解析字符串,找到所需要的信息。 或許你認為這樣就足夠了,為什么還要使用Lua呢? 應用于“配置”這個目的,Lua提供給你…

Github(3)-本地文件管理

使用github 托管代碼簡單使用教程--本地文件管理1.基本概念2.本地文件管理2.1 git add2.2 git status2.3 git commit2.3 git log2.5 git reset --hard 版本回退2.6 git reflog2.7 git diff2.8 git checkout --file 工作區文件恢復2.9 git rm 刪除版本庫里的文件廖雪峰老師博文學…

linux 中阻塞與非阻塞 同步與異步

簡單點說: 阻塞就是干不完不準回來, 非阻塞就是你先干,我先看看有其他事沒有,完了告訴我一聲。 我們拿最常用的send和recv兩個函數來說吧。比如你調用send函數發送一定的Byte,在系統內部send做的工作其實只是把數據傳輸(Copy)到TCP/IP協議棧…

leecode62 不同路徑

示例 1: 輸入: m 3, n 2 輸出: 3 解釋: 從左上角開始,總共有 3 條路徑可以到達右下角。 1. 向右 -> 向右 -> 向下 2. 向右 -> 向下 -> 向右 3. 向下 -> 向右 -> 向右 示例 2: 輸入: m 7, n 3 輸出: 28 思路:太過于簡單&#xf…

數據庫的查詢優化建議整理

從大多數數據庫應用系統的實例來看,查詢操作在各種數據庫操作中所占據的比重最大,而查詢操作所基于的SELECT語句在SQL語句中又是代價最大的語句。 查詢語句(SELECT)的優化建議 (1)、合理使用索引:where子句中變量順序應與索引字鍵順序相同。 如:create index test_idx…

Github(4)-遠程操作

使用github 托管代碼簡單使用教程--遠程操作3.連接本地倉庫與遠程倉庫3.1 git clone 克隆實現鏈接3.2 git remote add origin4.遠程操作4.1 git checkout -b 切換分支14.2 git branch 查看分支4.3 git merge 合并分支4.3.1 step1:切換成主分支4.3.2 step2&#xff1…

leetcode64 最小路徑和

給定一個包含非負整數的 m x n 網格,請找出一條從左上角到右下角的路徑,使得路徑上的數字總和為最小。 說明:每次只能向下或者向右移動一步。 示例: 輸入: [ [1,3,1], [1,5,1], [4,2,1] ] 輸出: 7 解釋: 因為路徑 1→3→1→1→1 的總…

online游戲服務器架構--網絡架構

啟動:父進程啟動;子進程啟動;網絡架構。 每個父進程攜帶N個子進程,子進程負責處理業務邏輯和其它數據,而父進程只是將客戶端的請求路由到各個子進程,路由的策略非常簡單,父進程將請求包按照輪流…

online游戲服務器架構—用戶登錄數據組織 .

sprite_t類型的數據結構是核心數據結構,每一個登錄用戶對應一個,它的初始化在用戶登錄的時候,此后一直到用戶退出或者離線一直保存在系統內存當中,在此過程中該sprite_t數據結構被保存在兩個哈希表當中,一個是以用戶的…

leetcode300 最長上升子序列

經典題&#xff0c;不解釋&#xff0c;可以看我之前文章。 普通dp public class Solution {public int lengthOfLIS(int[] nums) {if (nums.length 0) {return 0;}int[] dp new int[nums.length];dp[0] 1;int maxans 1;for (int i 1; i < dp.length; i) {int maxval …

Github(5)-開源開發-常見錯誤

使用github 托管代碼簡單使用教程--開源開發-常見錯誤5. github開源開發6. 報錯log6.1 fatal: remote origin already exists.6.2 There is no tracking information for the current branch.6.標簽管理廖雪峰老師博文學習筆記&#xff1a;https://www.liaoxuefeng.com/wiki/89…

online游戲服務器架構--數據庫及事件相關 .

Online服務器的第三部分就是數據層&#xff0c;send_request_to_db開始了數據層的處理邏輯&#xff1a; int send_request_to_db(int cmd, sprite_t* p, int body_len, const void* body_buf, uint32_t id)&#xff1b; 在該函數里首先以懶惰的方式連接數據庫服務器&#xff…

leecode5 最長回文子串

給定一個字符串 s&#xff0c;找到 s 中最長的回文子串。你可以假設 s 的最大長度為 1000。 示例 1&#xff1a; 輸入: "babad" 輸出: "bab" 注意: "aba" 也是一個有效答案。 示例 2&#xff1a; 輸入: "cbbd" 輸出: "bb"…

libxml解析xml文件的一些總結

libxml -- 解析 XML 文檔XML 介紹&#xff1a;XML 和 DOMlibxml 介紹 數據類型 — xmlChar數據結構 創建 XML 文檔解析 XML 文檔修改 xml 文檔Xpath — 處理大型 XML 文檔libxml2 庫函數要注意的函數讀取 xml 文件xml 操作基本結構及其指針類型根節點相關函數 創建子節點相關函…

Linux(7)-正則表達式

正則表達式demo1:在某個文件中尋找命令seddemo2:尋找8位電話號碼正則表達式&#xff1a;用來描述或者匹配某一系列符合某個句法隊則的字符串或者單個字符串。最初正則表達式&#xff0c;出現在自動控制理論和形式化語言理論中。 Linux 中 find grep sed ls命令都支持正則表達式…