lua __index __newindex upvalue 示例

項目中有個公會對象,數據大部分存在data中,之前都是 u.data.point這樣訪問,太麻煩了。

于是通過設置__index 使之可以直接訪問屬性,u.point。

但是還是不能直接改屬性,u.point = 4,所以再設置了__newindex。

?

在設置了setmetatable之后,不能直接給u添加新屬性,因為設置了__newindex,新的屬性將直接加到u.data中的。

?

[c-sharp] view plaincopyprint?
  1. Union?=?{??
  2. ????data?=?nil,??
  3. ????dirty?=?nil,??
  4. }??
  5. ---?生成新的對象??
  6. function?Union:new(o)??
  7. ????o?=?o?or?{}??
  8. ????setmetatable(o,self)??
  9. ????self.__index?=?self??
  10. ????return?o??
  11. end??
  12. ---?初始化Union數據??
  13. function?Union:init(data)??
  14. ????self:initTable()??
  15. ????self.data?=?data??
  16. ????local?meta?=?{}??
  17. ????meta.__index?=?function?(table,?key)??
  18. ????????if?Union[key]?~=?nil?then??
  19. ????????????return?Union[key]??
  20. ????????else??
  21. ????????????return?self.data[key]??
  22. ????????end??
  23. ????end??
  24. ????meta.__newindex?=?function(table,key,?value)??
  25. ????????self.data[key]?=?value??
  26. ????end??
  27. ????setmetatable(self,?meta)??
  28. end??
  29. function?Union:initTable()??
  30. ????if?self.data?==?nil?then??
  31. ????????self.data?=?{}??
  32. ????end??
  33. ????if?self.dirty?==?nil?then??
  34. ????????self.dirty?=?{}??
  35. ????end??
  36. end??
  37. function?Union:print()??
  38. ????print(self.point,?self.data.point)??
  39. end??
  40. function?pt()??
  41. ????print(data1.point,?data2.point,?u.point,?u.data.point)??
  42. end??
  43. u?=?Union:new()??
  44. data1?=?{point?=?3}??
  45. data2?=?{point?=?103}??
  46. u:init(data1)??
  47. pt()??
  48. u.point?=?4??
  49. pt()??
  50. u.data?=?data2??
  51. pt()??
  52. u.point?=?104??
  53. pt()??

?

?

?

通過修改__index和__newindex會獲得不同的結果。

?

1.正確結果

[c-sharp] view plaincopyprint?
  1. function?Union:init(data)??
  2. ????self:initTable()??
  3. ????self.data?=?data??
  4. ????local?meta?=?{}??
  5. ????meta.__index?=?function?(table,?key)??
  6. ????????if?Union[key]?~=?nil?then??
  7. ????????????return?Union[key]??
  8. ????????else??
  9. ????????????return?self.data[key]??
  10. ????????end??
  11. ????end??
  12. ????meta.__newindex?=?function(table,key,?value)??
  13. ????????self.data[key]?=?value??
  14. ????end??
  15. ????setmetatable(self,?meta)??
  16. end??

3??? 103??? 3??? 3
4??? 103??? 4??? 4
4??? 103??? 103??? 103
4??? 104??? 104??? 104

?

2.錯誤的__newindex

[c-sharp] view plaincopyprint?
  1. function?Union:init(data)??
  2. ????self:initTable()??
  3. ????self.data?=?data??
  4. ????local?meta?=?{}??
  5. ????meta.__index?=?function?(table,?key)??
  6. ????????if?Union[key]?~=?nil?then??
  7. ????????????return?Union[key]??
  8. ????????else??
  9. ????????????return?self.data[key]??
  10. ????????end??
  11. ????end??
  12. ????meta.__newindex?=?self.data??
  13. ????setmetatable(self,?meta)??
  14. end??

3??? 103??? 3??? 3
4??? 103??? 4??? 4
4??? 103??? 103??? 103
104??? 103??? 103??? 103

3.錯誤的__index

[c-sharp] view plaincopyprint?
  1. function?Union:init(data)??
  2. ????self:initTable()??
  3. ????self.data?=?data??
  4. ????local?meta?=?{}??
  5. ????meta.__index?=?function?(table,?key)??
  6. ????????if?Union[key]?~=?nil?then??
  7. ????????????return?Union[key]??
  8. ????????else??
  9. ????????????return?data[key]??
  10. ????????end??
  11. ????end??
  12. ????meta.__newindex?=?function(table,key,?value)??
  13. ????????self.data[key]?=?value??
  14. ????end??
  15. ????setmetatable(self,?meta)??
  16. end??

3??? 103??? 3??? 3
4??? 103??? 4??? 4
4??? 103??? 4??? 103
4??? 104??? 4??? 104

?對象A在內部可以修改HP.外部對象只能訪問對象A的HP,不能修改.

這東西其實可以用__index和__newindex來實現.

__index指向對象A,這樣就可以訪問;

__newindex重寫,修改hp的話,就禁止.就可以完成他的需求.

下面給出簡單的代碼:

function cannotModifyHp(object)
????local proxy = {}
????local mt = {
????????__index = object,
????__newindex = function(t,k,v)
????????if k ~= "hp" then
????????object[k] = v
????????end
????end
????}
????setmetatable(proxy,mt)
????return proxy
end
??
object = {hp = 10,age = 11}
function object.sethp(self,newhp)
????self.hp = newhp
end
??
o = cannotModifyHp(object)
??
o.hp = 100
print(o.hp)
??
o:sethp(111)
print(o.hp)
??
object:sethp(100)
print(o.hp)
function cannotModifyHp(object)
????local proxy = {}
????local mt = {
????????__index = object,
????__newindex = function(t,k,v)
????????if k ~= "hp" then
????????object[k] = v
????????end
????end
????}
????setmetatable(proxy,mt)
????return proxy
end
object = {hp = 10,age = 11}
function object.sethp(self,newhp)
????self.hp = newhp
end
??
o = cannotModifyHp(object)
??
o.hp = 100
print(o.hp)
??
o:sethp(111)
print(o.hp)
??
object:sethp(100)
print(o.hp)

?

這里影響程序的不同結果是upvalue導致的。

由于一般程序中有可能動態改data。所以建議用function設置__index和__newindex,尤其注意各個不同函數中self指向的是什么對象

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

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

相關文章

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命令都支持正則表達式…

服務器端開發的一些建議

摘要: 本文作為游戲服務器端開發的基本大綱&#xff0c;是游戲實踐開發中的總結。第一部分專業基礎&#xff0c;用于指導招聘和實習考核&#xff0c; 第二部分游戲入門&#xff0c;講述游戲服務器端開發的基本要點&#xff0c;第三部分服務端架構&#xff0c;介紹架構設計中的一…