2017-01-08 8 views
4

Продолжая изучать Lua.Lua table.insert не принимает параметр строки

Я написал функцию, которая удаляет первое предложение из каждой строки и возвращает результат в виде таблицы модифицированных строк, где первое предложение было удалено. Странно, table.insert ведет себя странно в такой функции.

function mypackage.remove_first(table_of_lines) 
    local lns = table_of_lines 
    local new_lns = {} 
    for i=1,#lns do 
    table.insert(new_lns,string.gsub(lns[i],"^[^.]+. ","",1)) 
    end 
    return new_lns 
end 

Неожиданно это дало мне следующую ошибку.

[string "function mypackage.remove_first(table_of_lines)..."]:5: bad argument #2 to 'insert' (number expected, got string) 

Почему «ожидается число»?

table.insert От документы

Вставки значение элемента в положении поз в списке, сдвигая вверх по списку элементов [поз], [список поз + 1], ···, список [#list]. Значение по умолчанию для pos - это # ​​list + 1, так что таблица вызова.интет (t, x) вставляет x в конец списка t.

Ничего не сказано о требованиях к типу для table.insert. Хорошо, я решил изменить пример.

function mypackage.remove_first(table_of_lines) 
    local lns = table_of_lines 
    local new_lns = {} 
    for i=1,#lns do 
    local nofirst = string.gsub(lns[i],"^[^.]+. ","",1) 
    table.insert(new_lns,nofirst) 
    end 
    return new_lns 
end 

И теперь все работает. Можете ли вы объяснить, что здесь происходит?

+1

'string.gsub' возвращает два значения вместо одного, а другой (перегруженной) версии' table.insert' вызывается –

+0

Hm, и одно из значений как-то невидимо для 'print'? – minerals

+1

@minerals: Это не невидимо. Когда у вас есть выражение, которое приводит к нескольким значениям, и вы назначаете его на меньшее количество значений, дополнительные из них отбрасываются. Поэтому 'local nofirst = string.gsub (...)' будет отбрасывать второе значение. –

ответ

2

Проблема немного сложная. Это столкновение трех факторов:

  1. string.gsub возвращает два параметра; вторым параметром является количество совпадений.

  2. table.insert может принимать 3 параметра. Когда ему даются 3 параметра, ожидается, что второй параметр будет целочисленным смещением, определяющим, куда вставлять объект.

  3. Когда вы сделаете это: func1(func2()), все из возвращаемых значений func2 передается func1, до тех пор, пока вы не передавать аргументы после func2 в func1 «s списка аргументов. Таким образом, func1(func2(), something_else) получит только 2 аргумента.

Поэтому, когда вы делаете table.insert(ins, string.gsub(...)), это будет вызывать версию 3-аргумент, который ожидает, что второй аргумент является индексом для вставки объекта в. Отсюда и проблема.

Если вы хотите, чтобы обеспечить отбрасывание, то вы можете обернуть выражение в скобках:

table.insert(new_lns, (string.gsub(lns[i], "^[^.]+. ", "", 1)))