2017-01-08 1 views
4

Continuer à apprendre Lua.Lua table.insert n'accepte pas un paramètre de chaîne

J'ai écrit une fonction qui supprime la première phrase de chaque ligne et renvoie le résultat sous la forme d'une table de lignes modifiées, où la première phrase a été supprimée. Étrangement, table.insert se comporte bizarre dans une telle fonction.

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 

De façon inattendue, cela m'a donné l'erreur suivante.

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

Pourquoi "nombre attendu" en premier lieu?

De table.insert documents

valeur de l'élément Inserts à la position pos dans la liste, le déplacement de la liste éléments [pos], liste [pos + 1], ···, liste [#list]. La valeur par défaut pour pos est # list + 1, de sorte qu'un appel table.insert (t, x) insère x à fin de la liste t.

Rien n'est dit à propos des exigences de type pour table.insert. Ok, j'ai décidé de modifier l'exemple.

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 

Et maintenant tout fonctionne. Pouvez-vous expliquer ce qui se passe ici?

+1

'string.gsub' retourne deux valeurs au lieu d'une, et une autre version (surcharge) de' table.insert' est invoqué –

+0

Hm, et l'une des valeurs est invisible à 'print'? – minerals

+1

@minerals: Ce n'est pas invisible. Lorsque vous avez une expression qui génère plusieurs valeurs et que vous l'attribuez à moins de valeurs, les valeurs supplémentaires sont supprimées. Donc 'local nofirst = string.gsub (...)' supprimera la seconde valeur. –

Répondre

2

Le problème est un peu compliqué. Il est une collision de trois facteurs:

  1. string.gsub retours deux paramètres; le deuxième paramètre est le nombre de correspondances.

  2. table.insert peut prendre 3 paramètres. Quand on lui donne 3 paramètres, on s'attend à ce que le deuxième paramètre soit un offset d'entier définissant où insérer l'objet.

  3. Lorsque vous faites ceci: func1(func2()), tous des valeurs de retour de func2 sont passés à func1, tant que vous ne passez pas d'arguments après func2 dans la liste des arguments de func1. Donc func1(func2(), something_else) obtiendra seulement 2 arguments.

Par conséquent, lorsque vous faites table.insert(ins, string.gsub(...)), cela invoquera la version 3-argument, qui attend le second argument est l'indice d'insérer l'objet dans. D'où le problème.

Si vous voulez vous assurer défausse, vous pouvez envelopper l'expression entre parenthèses:

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