2010-05-03 38 views

Trả lời

5

Như những người khác đã nói, self (bảng Account) được sử dụng như một metatable giao cho các đối tượng tạo bằng new. Đơn giản hóa một chút (thêm thông tin có sẵn tại các liên kết được cung cấp) khi một trường không được tìm thấy trong 'o', nó sẽ chuyển đến bảng 'Tài khoản' vì có thể so sánh được với tài khoản (đây là những gì __index làm).

Nó không, tuy nhiên, cần phải được thực hiện mỗi khi một đối tượng được tạo ra. Bạn có thể dễ dàng dính vào nơi này:

Account.__index = Account 

và nó cũng hoạt động.

Câu chuyện dài hơn một chút là nếu một đối tượng o có metatable, và metatable có tập __index lĩnh vực, sau đó một không tra cứu lĩnh vực trên o sẽ sử dụng __index để tìm lĩnh vực này (__index có thể là một bảng hoặc chức năng). Nếu o có trường được đặt, bạn không truy cập chức năng __index có thể so sánh của nó để nhận thông tin. Một lần nữa, mặc dù, tôi khuyến khích bạn đọc thêm tại các liên kết được cung cấp ở trên.

0

Chúng được sử dụng để chỉ đạo lại các truy cập bảng (cục bộ y = bảng [khóa]) cũng được sử dụng trong các cuộc gọi phương thức. Trong dòng trên, đối tượng o sẽ có bất kỳ nỗ lực nào để truy cập các khóa được chuyển hướng đến chính đối tượng hiện tại, dễ dàng kế thừa tất cả các hàm thành viên. Và có thể cả các biến dữ liệu, tùy thuộc vào chính xác __index là gì và nó hoạt động như thế nào.

3

Lua không phải là ngôn ngữ hướng đối tượng, nhưng nó có tất cả các phương tiện để viết mã hướng đối tượng. Tuy nhiên, nó được thực hiện theo kiểu prototyping a la JavaScript. Thay vì tạo lớp một cách rõ ràng, một đối tượng nguyên mẫu được tạo ra và sau đó nhân bản vô tính để tạo ra các cá thể mới.

Các metamethod __index được gọi để thực hiện tra cứu chính trên truy cập đọc vào bảng khi khóa chưa có trong bảng. Vì vậy, self.__index = self về cơ bản cho phép kế thừa tất cả các phương thức và trường của lớp "Account" theo "phiên bản" mới được tạo trong các dòng o = o or {}setmetatable(o, self).

Xem thêm:

+0

Tôi tìm thấy "hướng dẫn" này trên Lua [kế thừa] (http: // lua-users.org/wiki/InheritanceTutorial) đặc biệt khai sáng cùng với câu trả lời này. – Indolering

+0

@Indolering Thanks. Tôi đặt liên kết của bạn trong câu trả lời. –

4

Tài liệu Lua có phần mơ hồ về chi tiết này và nhiều câu trả lời ở đây hoặc là phản hồi tài liệu Lua hoặc không giải thích kỹ lưỡng về miếng ngon khó hiểu này.

Dòng self._index = self hiện diện hoàn toàn vì lợi ích của đối tượng mới được tạo, o; nó không có tác động có ý nghĩa hoặc chức năng trên Account.

Trường _index chỉ có ý nghĩa đặc biệt trong ngữ cảnh của các siêu dữ liệu; do đó self._index chỉ là một trường thông thường cũ cho Account. Tuy nhiên, khi Account được sử dụng như một metatable cho o, trường _index "trở thành" một metamethod cho o. (Vì vậy, một lĩnh vực cho Account là những gì là một metamethod cho o.)

Khi bạn lấy hai câu lệnh kết hợp ...

 
(1) setmetatable(o, self) 
(2) self._index = self 

... bạn đang sử dụng Account như metatable cho o trên dòng (1) và đặt số _index metamethod cho o thành Account trên dòng (2). (Trên dòng (2), bạn cũng đang đặt "trường cũ đơn giản" __index trong Account thành Account.) Vì vậy, khía cạnh hữu ích của self._index = self không phải là cài đặt của trường _index cho Account, mà là cài đặt của _index metamethod cho o.

Sau đây là chức năng tương đương:

 
    setmetatable(o, self) 
    getmetatable(o)._index = self 
+0

Hãy nhớ rằng trong khi __index là một metamethod trong tên, lua cung cấp một phím tắt tiện dụng, nơi __index có thể được gán một bảng thay vì một hàm. Trong những trường hợp này khi __index được gọi là tra cứu được thực hiện. Vì vậy, khi bạn nói __index = tự những gì bạn đang thực sự nói là, nếu bạn không thể tìm thấy một lĩnh vực nhất định trong trường hợp của tài khoản, nhìn (aka "chỉ số") tại lớp tài khoản/nguyên mẫu chính nó. – Aaron

0

đối tượng Tạo (mà chỉ đơn giản là Bàn) là hoàn toàn khác với Lua. Ý tưởng cơ bản là tạo một bảng thông thường chứa các thuộc tính (hàm và giá trị) phổ biến cho tất cả các cá thể. Bảng này, tôi sẽ gọi CAT cho Bảng thuộc tính chung.

Nếu bạn tham chiếu thuộc tính trong bảng và Lua không thể tìm thấy thuộc tính này, có một cách để báo cho Lua biết nơi khác để tìm thuộc tính. Chúng tôi muốn Lua nhìn vào CAT cho các thuộc tính chung. Metatables trả lời nhu cầu đó. Thêm về cách hoạt động sau này.

Chúng tôi cũng cần các phương thức trong CAT để có thể sử dụng các giá trị mẫu. Tự câu trả lời cần. Khi bạn gọi hàm bảng (phương thức) theo cách này: tableName:methodName(), Lua tự động đặt tham chiếu đến đối tượng bảng làm thông số đầu tiên. Tên của tham số này là tự. Mặc dù phương thức nằm trong CAT, bản thân nó sẽ tham chiếu tới bảng cá thể đối tượng cụ thể.

Giả sử chúng tôi có CAT được gọi là Ô tô.

metaCar = { __index = Car } 
-- this table will be used as the metatable for all instances of Car 
-- Lua will look in Car for attributes it can't find in the instance 

Ví dụ:

-- instance table is called mustang  
-- setmetatable(mustang, metaCar) 

Đây là một chức năng mục đích chung là tạo các đối tượng dụ mới và đặt metatable cho nó. Nếu CAT có hàm khởi tạo (init), hàm này cũng được thực thi.

function newObj(metatable) 
..obj = {}  -- create new empty instance object 
..setmetatable(obj, metatable) –- connect the metatable to it 
..if obj.init then -- if the CAT has an init method, execute it 
....obj:init() 
..end 
..return obj 
end 
Các vấn đề liên quan