简体   繁体   中英

Regarding colon operator in Lua

Why does this piece of code fail (attempt to call method 'sort' (a nil value))

th> xyz = {1,2,3}                                                                      
th> xyz:sort()

while this works

th> table.sort(xyz)

Because the table table, which contains the generic functions for manipulating tables provided by the standard library, isn't in the metatable for a table by default. In fact, a table doesn't have a metatable unless specified explicitly.

You could do this manually though:

local xyz = {1,2,3}
local mt = { __index = table}
setmetatable(xyz, mt)
xyz:insert(2)
xyz:sort()

@YuHao gives a direct answer. This is more background.

The colon operator is an indexing operator; It indexes the value of the expression on the left with the identifier (as a string-typed key) on the right.

expression:identifier(arg0, arg1, ...)

is conceptually the same as

local lhs = expression
lhs.identifer(lhs, arg0, arg1, ...)

is conceptually the same as

local lhs = expression
lhs["identifer"](lhs, arg0, arg1, ...)

So, your question isn't so much about the colon operator as it is about indexing.

In Lua, indexing a table-typed value first checks the table's fields for the key. If found, it returns the value.

If not, it checks the table for its one optional currently associated metatable and if that table has a value with the key "__index". If not found, the result of indexing is nil . If the value of the __index field is a table, the process repeats on that table. If the value is a function, then the result of indexing is the return value of calling that function.

In your case, as @YuHao explains , your table doesn't have a "sort" field nor a metatable so the indexing result is nil , resulting in the error of attempting to call a nil value. (The message nicely indicates that you used the colon syntax by saying it is a "method call".)

It's because xyz doesn't have a key/value pair where the key is "sort" and the value is a function. table has said key/value pair. Try this to make things clearer:

local xyz = {}
print(xyz.sort)    -- prints nil
print(table.sort)  -- prints function: 0xabcd1234

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM