2015-08-18 21 views
4

Я получаю ужасно путаницу с помощью двоеточия, используемого при определении/вызове функций Lua.Lua: обозначение двоеточия, определение «я» и функции по сравнению с вызовом

Я думал, что я получил мою голову вокруг него, пока я не увидел этот кусок кода:

function string.PatternSafe(str) 
    return (str:gsub(".", pattern_escape_replacements)); 
end 

function string.Trim(s, char) 
    if char then char = char:PatternSafe() else char = "%s" end 
    return string.match(s, "^" .. char .. "*(.-)" .. char .. "*$") or s 
end 

Что толку меня здесь является то, что string.PatternSafe() не ссылается на «себя» в любом месте, но код, похоже, работает.

Я также видел несколько сценариев, которые используют обозначения двоеточие при определении функции, например:

function foo:bar(param1) ... end 

После нескольких часов прибегая к помощи я до сих пор не удалось выяснить, что именно происходит в этих два контекста. Мои текущие предположения заключаются в следующем:

  1. Если функция определяется с помощью обозначения толстой кишки, он получает невидимый параметр «я», вставленный в качестве первого параметра
  2. Если функция вызывается с использованием обозначений толстой кишки, объект, предшествующий ' : 'вставляется в аргументы (поэтому становится первым параметром функции)
  3. Если функция вызывается с использованием точечной нотации, то даже если она была определена с использованием двоеточия, она не получит объект, вставленный в качестве первого аргумента/параметр

Если мое предположение Правильно, что вызывает дополнительный вопрос: что является лучшим способом обеспечить правильную работу функции?

+0

Возможный дубликат [Разница между. и: в Lua] (https://stackoverflow.com/questions/4911186/difference-between-and-in-lua) –

ответ

5

Ваши предположения верны.

Успенская 1 из the manual:

Синтаксис двоеточие используется для определения методов, то есть функции , которые имеют неявный дополнительный параметр самостоятельно. Таким образом, утверждение

function t.a.b.c:f (params) body end 

является синтаксически

t.a.b.c.f = function (self, params) body end 

Успенской 2 из the manual:

Вызова v: имя (арг) является синтаксическим сахаром для v.name (v, args), за исключением того, что v оценивается только один раз.

Успения 3 не имеет прямого раздела руководства, так как это обычный нормальный синтаксис вызова функции.

Вот и все. self - это просто имя магии, указанное в синтаксическом сахаре, используемом как часть назначения двоеточия. Это не необходимо имя. Первый аргумент - это первый аргумент независимо от имени.

Таким образом, в вашем примере:

function string.PatternSafe(str) 
    return (str:gsub(".", pattern_escape_replacements)); 
end 

первый аргумент str так, когда функция называется char:PatternSafe() является ДЭ-сахаров (по предположению 2) char.PatternSafe(char) который просто проходя char функции как первый аргумент (который, как я уже сказал, равен str).

+0

Каков наилучший способ определить изнутри вызываемой функции, был ли он вызван с помощью точки или двоеточия нотация? Редактирование: В частности, если вы случайно вызвали точечную нотацию, «я» проглотит следующий параметр (поэтому в примере foo: bar self param проглотит param1, если я позвоню foo.bar («test») и param1 будет равен нулю). – Aubergine18

+1

Вы * не можете * сообщить в функции, как вы были вызваны. Они не разные. Это весь сахар. Вы * можете * рассказать, сколько аргументов у вас есть, и какие «типы» они есть. –

+0

@ Etan Ну, одно из возможных решений - проверить, сколько аргументов было передано. 1 дополнительный? Синтаксис Colon. – warspyking