องค์ประกอบตาราง Lua (Metatable)
ในตาราง Lua เราสามารถเข้าถึงค่าคีย์ที่สอดคล้องกับการได้รับค่า แต่ก็ไม่สามารถดำเนินการในสองตาราง
ดังนั้น Lua มีองค์ประกอบตาราง (Metatable) ตารางช่วยให้เราสามารถเปลี่ยนพฤติกรรมของแต่ละการกระทำที่เกี่ยวข้องกับวิธีการองค์ประกอบที่สอดคล้องกัน
ตัวอย่างเช่นการใช้ตารางเมตาดาต้าที่เราสามารถกำหนดวิธีการ Lua ตารางการคำนวณผลรวมของทั้งสองดำเนิน A + ข
เมื่อ Lua พยายามเพิ่มสองตารางตรวจสอบก่อนว่ามีหนึ่งในสองหยวนตารางหลังจากการตรวจสอบว่ามีสถานที่ที่เรียกว่า "__add ฟิลด์" หากพบนั้นเรียกค่าที่สอดคล้องกัน "__add" และสนามทันทีอื่น ๆ , ค่าที่สอดคล้องกัน (มักจะเป็นฟังก์ชั่นหรือตาราง) คือ "วิธีการองค์ประกอบ."
มีสองฟังก์ชั่นที่สำคัญมากในการจัดการตารางหยวน ได้แก่ :
- setmetatable (ตาราง metatable): จัดโต๊ะสำหรับองค์ประกอบของตารางที่ระบุ (metatable) ถ้ามี __metatable ตารางองค์ประกอบสำคัญ (metatable) ใน setmetatable ล้มเหลว
- getmetatable (ตาราง): คืนตารางวัตถุเมตาดาต้า (metatable)
ตัวอย่างต่อไปนี้แสดงให้เห็นถึงวิธีการตั้งค่าตารางสำหรับองค์ประกอบของตารางที่ระบุ:
mytable = {} -- 普通表 mymetatable = {} -- 元表 setmetatable(mytable,mymetatable) -- 把 mymetatable 设为 mytable 的元表
รหัสข้างต้นสามารถเขียนได้โดยตรงไปยังบรรทัด:
mytable = setmetatable({},{})
ต่อไปนี้เป็นตารางผลตอบแทนวัตถุข้อมูลเมตา:
getmetatable(mytable) -- 这回返回mymetatable
ส่วนวิธีการ __index
นี้เป็นกุญแจสำคัญ metatable ใช้กันมากที่สุด
เมื่อคุณผ่านกุญแจสำคัญในการเข้าถึงตารางและหากที่สำคัญไม่มีค่าแล้ว Lua จะได้พบกับตารางของ metatable นี้ (สมมติ metatable) ในคีย์ __index หาก __index มีตาราง Lua จะพบกุญแจสำคัญที่สอดคล้องกันในตารางเราสามารถใช้คำสั่ง Lua ที่จะเข้าสู่โหมดการโต้ตอบผู้ชม:
$ lua Lua 5.3.0 Copyright (C) 1994-2015 Lua.org, PUC-Rio > other = { foo = 3 } > t = setmetatable({}, { __index = other }) > t.foo 3 > t.bar nil
หาก __index มีฟังก์ชั่นแล้ว Lua จะเรียกว่าฟังก์ชั่นโต๊ะและคีย์จะถูกส่งผ่านเป็นพารามิเตอร์ไปยังฟังก์ชั่นที่
ส่วนวิธีการ __index เพื่อดูองค์ประกอบตารางที่มีอยู่ถ้าไม่กลับผลที่ได้คือไม่มีถ้ามันมีอยู่โดยผลผลตอบแทน __index
mytable = setmetatable({key1 = "value1"}, { __index = function(mytable, key) if key == "key2" then return "metatablevalue" else return nil end end }) print(mytable.key1,mytable.key2)
ตัวอย่างของการส่งออกเป็น:
value1 metatablevalue
ตัวอย่างการวิเคราะห์:
ตาราง mytable มอบหมาย{key1 = "VALUE1"}
mytable ชุดโต๊ะเมตาส่วนวิธีการ __index
ค้นหา key1 ในตาราง mytable ถ้าพบกลับองค์ประกอบที่ไม่สามารถพบได้อย่างต่อเนื่อง
ค้นหา key2 ในตาราง mytable ถ้าพบกลับ metatablevalue ค้นหาอย่างต่อเนื่อง
การวิเคราะห์ตารางเมตามีวิธี __index ไม่หากวิธี __index เป็นฟังก์ชั่นเรียกใช้ฟังก์ชัน
- ส่วนวิธีการตรวจสอบว่าเข้ามา "key2" คีย์พารามิเตอร์ (ชุด mytable.key2) ถ้าเข้ามา "key2 พารามิเตอร์" ผลตอบแทน "metatablevalue" กุญแจสำคัญที่สอดคล้องกัน mytable มิฉะนั้น
เราสามารถเขียนโค้ดข้างต้นเป็นเรื่องง่าย:
mytable = setmetatable({key1 = "value1"}, { __index = { key2 = "metatablevalue" } }) print(mytable.key1,mytable.key2)
ย่อ
ค้นหา Lua กฎองค์ประกอบตารางเมื่อในความเป็นจริงต่อไปนี้สามขั้นตอน
- 1. ค้นหาในตารางหากพบกลับองค์ประกอบที่ไม่พบให้ดำเนินการต่อ
- 2. ตรวจสอบว่าตารางมีตารางหยวนถ้าไม่มีตารางธาตุตารางเงินดอลลาร์กลับมาศูนย์มีอย่างต่อเนื่อง
- 3. การวิเคราะห์ตารางเมตามีวิธี __index ไม่หากวิธี __index เป็นศูนย์กลับศูนย์ถ้าวิธี __index เป็นตารางซ้ำ 1,2,3 ถ้าวิธี __index เป็นฟังก์ชั่นผลตอบแทนที่ฟังก์ชั่น ค่าตอบแทน
ส่วนวิธีการ __newindex
ส่วนวิธีการ __newindex ถูกนำมาใช้ในการปรับปรุงตาราง __ ดัชนีจะใช้ในการเข้าถึงตาราง
เมื่อคุณได้ให้การกำหนดตารางดัชนีหายไปล่ามจะมีลักษณะ __newindex ส่วนวิธีการ: ถ้าคุณเรียกใช้ฟังก์ชันนี้โดยไม่ได้รับมอบหมาย
ตัวอย่างต่อไปนี้แสดงให้เห็นถึงวิธีการองค์ประกอบการประยุกต์ใช้ __newindex นี้:
mymetatable = {} mytable = setmetatable({key1 = "value1"}, { __newindex = mymetatable }) print(mytable.key1) mytable.newkey = "新值2" print(mytable.newkey,mymetatable.newkey) mytable.key1 = "新值1" print(mytable.key1,mymetatable.key1)
ตัวอย่างของการดำเนินงานของการส่งออกดังกล่าวข้างต้นเป็น:
value1 nil 新值2 新值1 nil
ตัวอย่างของตารางข้างต้นตั้ง __newindex วิธีการองค์ประกอบเมื่อดัชนีคีย์ (Newkey) งานใหม่ (mytable.newkey = "ค่าใหม่ 2") จะเรียกวิธีองค์ประกอบโดยไม่ได้รับมอบหมาย และถ้าคีย์ดัชนีที่มีอยู่ (key1) จะดำเนินการที่ได้รับมอบหมายโดยไม่ต้องเรียกวิธีการองค์ประกอบ __newindex
ตัวอย่างต่อไปนี้ใช้ฟังก์ชัน rawset เพื่ออัพเดตตาราง:
mytable = setmetatable({key1 = "value1"}, { __newindex = function(mytable, key, value) rawset(mytable, key, "\""..value.."\"") end }) mytable.key1 = "new value" mytable.key2 = 4 print(mytable.key1,mytable.key2)
ตัวอย่างของการดำเนินงานของการส่งออกดังกล่าวข้างต้นเป็น:
new value "4"
เพิ่มผู้ประกอบการสำหรับตาราง
ตัวอย่างต่อไปนี้แสดงให้เห็นถึงสองตารางเพิ่มการทำงาน:
-- 计算表中最大值,table.maxn在Lua5.2以上版本中已无法使用 -- 自定义计算表中最大值函数 table_maxn function table_maxn(t) local mn = 0 for k, v in pairs(t) do if mn < k then mn = k end end return mn end -- 两表相加操作 mytable = setmetatable({ 1, 2, 3 }, { __add = function(mytable, newtable) for i = 1, table_maxn(newtable) do table.insert(mytable, table_maxn(mytable)+1,newtable[i]) end return mytable end }) secondtable = {4,5,6} mytable = mytable + secondtable for k,v in ipairs(mytable) do print(k,v) end
ตัวอย่างของการดำเนินงานของการส่งออกดังกล่าวข้างต้นเป็น:
1 1 2 2 3 3 4 4 5 5 6 6
__add องค์ประกอบสำคัญที่มีอยู่ในตารางและเพิ่มการดำเนินงาน รายการของการกระทำที่สอดคล้องกับตารางต่อไปนี้:
โหมด | ลักษณะ |
---|---|
__add | ผู้ประกอบการที่เกี่ยวข้อง '+' |
__sub | สอดคล้องกับผู้ประกอบการ '-' |
__mul | ผู้ประกอบการที่สอดคล้องกัน "*" |
__div | ผู้ประกอบการที่เกี่ยวข้อง '/' |
__mod | ผู้ประกอบการที่เกี่ยวข้อง '%' |
__unm | สอดคล้องกับผู้ประกอบการ '-' |
__concat | ผู้ประกอบการที่สอดคล้องกัน ' .. ' |
__eq | ผู้ประกอบการที่เกี่ยวข้อง '==' |
__lt | ผู้ประกอบการที่เกี่ยวข้อง '<' |
__le | ผู้ประกอบการที่เกี่ยวข้อง '<=' |
ส่วนวิธีการ __call
ส่วนวิธีการ __call จะถูกเรียกเมื่อ Lua เรียกค่า ตัวอย่างต่อไปนี้แสดงให้เห็นถึงตารางการคำนวณขององค์ประกอบและ:
-- 计算表中最大值,table.maxn在Lua5.2以上版本中已无法使用 -- 自定义计算表中最大值函数 table_maxn function table_maxn(t) local mn = 0 for k, v in pairs(t) do if mn < k then mn = k end end return mn end -- 定义元方法__call mytable = setmetatable({10}, { __call = function(mytable, newtable) sum = 0 for i = 1, table_maxn(mytable) do sum = sum + mytable[i] end for i = 1, table_maxn(newtable) do sum = sum + newtable[i] end return sum end }) newtable = {10,20,30} print(mytable(newtable))
ตัวอย่างของการดำเนินงานของการส่งออกดังกล่าวข้างต้นเป็น:
70
ส่วนวิธีการ __tostring
ส่วนวิธีการ __tostring จะใช้ในการปรับเปลี่ยนพฤติกรรมของตารางการส่งออก ตัวอย่างต่อไปนี้ของตารางการส่งออกของเราเองของเนื้อหา:
mytable = setmetatable({ 10, 20, 30 }, { __tostring = function(mytable) sum = 0 for k, v in pairs(mytable) do sum = sum + v end return "表所有元素的和为 " .. sum end }) print(mytable)
ตัวอย่างของการดำเนินงานของการส่งออกดังกล่าวข้างต้นเป็น:
表所有元素的和为 60
จากบทความนี้เราสามารถรู้ตารางธาตุสามารถที่ดีลดความซับซ้อนของฟังก์ชั่นรหัสของเราดังนั้นการทำความเข้าใจตารางเมตาหลัวช่วยให้เราสามารถเขียนโค้ด Lua ที่ยอดเยี่ยมที่เรียบง่าย