Bài 15 : Lua – Metatables

Bài 15 : Lua – Metatables

Lua – Metatables  Trang trướcTrang tiếp theo   Khả năng đáp ứng là một bảng giúp sửa đổi hành vi của […]

Learn more »

Lua – Metatables


 Trang trướcTrang tiếp theo  

Khả năng đáp ứng là một bảng giúp sửa đổi hành vi của bảng mà nó được gắn vào với sự trợ giúp của tập khóa và các phương thức meta liên quan. Các phương thức meta này là chức năng Lua mạnh mẽ cho phép các tính năng như –

  • Thay đổi / thêm chức năng cho các toán tử trên bảng.
  • Tìm kiếm các dữ liệu có thể đo được khi khóa không có sẵn trong bảng bằng cách sử dụng __index trong hệ thống đo được.

Có hai phương pháp quan trọng được sử dụng để xử lý các bảng đo bao gồm:

  • setmetatable (bảng, có thể đo được) – Phương pháp này được sử dụng để thiết lập có thể đo được cho một bảng.
  • getmetatable (table) – Phương pháp này được sử dụng để lấy metatable của một bảng.

Trước tiên, hãy xem cách đặt một bảng giống như một bảng khác. Nó được hiển thị bên dưới.

mytable = {} mymetatable = {} setmetatable(mytable,mymetatable) 

Đoạn mã trên có thể được biểu diễn trong một dòng như hình dưới đây.

mytable = setmetatable({},{}) 

_mục lục

Dưới đây là một ví dụ đơn giản về khả năng đáp ứng để tra cứu bảng meta khi nó không có sẵn trong bảng.Bản thử trực tiếp

mytable = setmetatable({key1 = "value1"}, {    __index = function(mytable, key) 	       if key == "key2" then          return "metatablevalue"       else          return mytable[key]       end    end })  print(mytable.key1,mytable.key2)

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau.

value1 metatablevalue 

Hãy để chúng tôi giải thích những gì đã xảy ra trong ví dụ trên theo các bước.

  • Mytable ở đây là {key1 = “value1”} .
  • Metatable được đặt cho mytable có chứa một hàm cho __index, mà chúng tôi gọi là metamethod.
  • Metamethod thực hiện một công việc đơn giản là tìm kiếm một chỉ mục “key2”, nếu nó được tìm thấy, nó sẽ trả về “metatablevalue”, nếu không thì trả về giá trị của mytable cho chỉ mục tương ứng.

Chúng ta có thể có một phiên bản đơn giản của chương trình trên như hình dưới đây.

mytable = setmetatable({key1 = "value1"},     { __index = { key2 = "metatablevalue" } }) print(mytable.key1,mytable.key2)

__newindex

Khi chúng tôi thêm __newindex vào metatable, nếu các khóa không có sẵn trong bảng, hoạt động của các khóa mới sẽ được xác định bằng các phương thức meta. Dưới đây là một ví dụ đơn giản trong đó chỉ mục của metatable được đặt khi chỉ mục không có sẵn trong bảng chính.Bản thử trực tiếp

mymetatable = {} mytable = setmetatable({key1 = "value1"}, { __newindex = mymetatable })  print(mytable.key1)  mytable.newkey = "new value 2" print(mytable.newkey,mymetatable.newkey)  mytable.key1 = "new  value 1" print(mytable.key1,mymetatable.newkey1)

Khi bạn chạy chương trình trên, bạn nhận được kết quả sau.

value1 nil	new value 2 new  value 1	nil 

Bạn có thể thấy trong chương trình trên, nếu một khóa tồn tại trong bảng chính, nó chỉ cập nhật nó. Khi một khóa không có sẵn trong phần có thể bảo trì, nó sẽ thêm khóa đó vào phần có thể đo được.

Một ví dụ khác cập nhật cùng một bảng bằng cách sử dụng hàm rawset được hiển thị bên dưới.Bản thử trực tiếp

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)

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau.

new value	"4" 

rawset đặt giá trị mà không sử dụng __newindex có thể đo được. Tương tự, có rawget nhận giá trị mà không cần sử dụng __index.

Thêm Hành vi của Người vận hành vào Bảng

Dưới đây là một ví dụ đơn giản để kết hợp hai bảng bằng cách sử dụng + toán tử:Bản thử trực tiếp

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

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau.

1	1 2	2 3	3 4	4 5	5 6	6 

Khóa __add được bao gồm trong biến thể để thêm hành vi của toán tử +. Bảng các phím và toán tử tương ứng được hiển thị bên dưới.

Sr.No.Chế độ & Mô tả
1__cộngThay đổi hành vi của toán tử ‘+’.
2__subThay đổi hành vi của toán tử ‘-‘.
3__mulThay đổi hành vi của toán tử ‘*’.
4__divThay đổi hành vi của toán tử ‘/’.
5__modThay đổi hành vi của toán tử ‘%’.
6__unmThay đổi hành vi của toán tử ‘-‘.
7__concatThay đổi hành vi của toán tử ‘..’.
số 8__eqThay đổi hành vi của toán tử ‘==’.
9__ltThay đổi hành vi của toán tử ‘<‘.
10__leThay đổi hành vi của toán tử ‘<=’.

__gọi

Việc thêm hành vi của cuộc gọi phương thức được thực hiện bằng cách sử dụng câu lệnh __call. Một ví dụ đơn giản trả về tổng các giá trị trong bảng chính với bảng đã truyền.Bản thử trực tiếp

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))

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau.

70 

__tostring

Để thay đổi hành vi của câu lệnh print, chúng ta có thể sử dụng metamethod __tostring. Một ví dụ đơn giản được hiển thị bên dưới.Bản thử trực tiếp

mytable = setmetatable({ 10, 20, 30 }, {    __tostring = function(mytable)    sum = 0 	       for k, v in pairs(mytable) do          sum = sum + v       end 		       return "The sum of values in the table is " .. sum    end }) print(mytable)

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau.

The sum of values in the table is 60 

Nếu bạn biết đầy đủ các khả năng của bảng meta, bạn thực sự có thể thực hiện nhiều thao tác sẽ rất phức tạp mà không cần sử dụng đến nó. Vì vậy, hãy cố gắng làm việc nhiều hơn với việc sử dụng các bảng đo lường với các tùy chọn khác nhau có sẵn trong bảng meta như được giải thích trong các mẫu và cũng tạo mẫu của riêng bạn.


Lượt xem : 209

Integrations
Users

Share Profile

Anyone at KeenThemes can view
Anyone with link can edit

Give Award

Anyone at KeenThemes can view
Anyone with link can edit

Report User

Let us know why you’re reporing this person
Don't worry, your report is completely anonymous; the person you're
reporting will not be informed that you've submitted it