web-dev-qa-db-fra.com

Définir des valeurs par défaut pour les arguments de fonction

Dans le wiki Lua, j'ai trouvé un moyen de définir des valeurs par défaut pour les arguments manquants:

function myfunction(a,b,c)
    b = b or 7
    c = c or 5
    print (a,b,c)
end

Est-ce le seul moyen? Le PHP style myfunction (a,b=7,c=5) ne semble pas fonctionner. Ce n'est pas que la méthode Lua ne fonctionne pas, je me demande simplement si c'est la seule façon de le faire.

80
ripat

Si vous voulez des arguments nommés et des valeurs par défaut comme PHP ou Python, vous pouvez appeler votre fonction avec un constructeur de table:

myfunction{a,b=3,c=2}

(Cela se voit dans de nombreux endroits de Lua, tels que les formes avancées des modules de protocole de LuaSocket et les constructeurs dans IUPLua .)

La fonction elle-même pourrait avoir une signature comme celle-ci:

function myfunction(t)
    setmetatable(t,{__index={b=7, c=5}})
    local a, b, c =
      t[1] or t.a, 
      t[2] or t.b,
      t[3] or t.c
    -- function continues down here...
end

Toutes les valeurs manquantes dans le tableau des paramètres seront prises à partir du __index table dans sa métatable (voir la documentation sur les métatables ).

Bien sûr, des styles de paramètres plus avancés sont possibles en utilisant des constructeurs de table et des fonctions - vous pouvez écrire tout ce dont vous avez besoin. Par exemple, ici est une fonction qui construit une fonction qui prend des tables d'arguments nommées ou positionnelles à partir d'une table définissant les noms de paramètres et les valeurs par défaut et une fonction prenant une liste d'arguments régulière.

En tant que fonctionnalité non linguistique, ces appels peuvent être modifiés pour fournir de nouveaux comportements et sémantiques:

  • Des variables peuvent être définies pour accepter plusieurs noms
  • Les variables positionnelles et les variables de mots clés peuvent être intercalées - et la définition des deux peut donner la priorité à l'une ou l'autre (ou provoquer une erreur)
  • Il est possible de créer des variables sans position uniquement par mot-clé, ainsi que des variables sans position uniquement sans nom
  • La construction de table assez verbeuse pourrait être effectuée en analysant une chaîne
  • La liste d'arguments pourrait être utilisée textuellement si la fonction est appelée avec autre chose qu'une table

Certaines fonctions utiles pour écrire des traducteurs d'arguments sont unpack (déplacement vers table.unpack en 5.2), setfenv (obsolète en 5.2 avec le nouveau _ENV construction) et select (qui renvoie une seule valeur à partir d'une liste d'arguments donnée, ou la longueur de la liste avec '#').

80

À mon avis, il n'y a pas d'autre moyen. C'est juste la mentalité Lua: pas de fioritures, et à part du sucre syntaxique, pas de façons redondantes de faire des choses simples.

44
jpjacobs

Techniquement, il y a b = b == nil and 7 or b (qui doit être utilisé dans le cas où false est une valeur valide comme false or 7 est évalué à 7), mais ce n'est probablement pas ce que vous recherchez.

20

La seule façon que j'ai trouvée jusqu'à présent et qui ait un sens est de faire quelque chose comme ceci:

function new(params)
  params = params or {}
  options = {
    name = "Object name"
  }

  for k,v in pairs(params) do options[k] = v end

  some_var = options.name
end

new({ name = "test" })
new()
5
NineBlindEyes