Latest web development tutorials

องค์ประกอบตาราง 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 ที่ยอดเยี่ยมที่เรียบง่าย