vendredi 10 février 2012

Liste d'arguments variable en objective-C et Java


Pour changer aujourd'hui un post non pas axé sur un language mais sur une façon de coder. Je vais vous expliquer comment créer une fonction varargs ou en français variadique, c'est à dire une fonction qui prend un nombre arbitraire d'opérandes.

Il vous est sûrement déjà arrivé de créer des fonctions que prennent des tableaux d'objets en paramètre. C'est très bien quand on ne sait pas quels éléments vont constituer le tableau, mais lorsque savez que vous coderez toujours en dur les paramètres de la fonction, je ne pense pas qu'il soit judicieux de créer et allouer un tableau. Voici comment je procède en Objective-C sur iPhone en Java sur Android.

Sur iPhone, tout d'abord, dans le .h, je déclare par exemple ceci:

- (void) maFonctionAvecUnParametre:(id)param1
        etUneListeVariable:(id)param2,...
        NS_REQUIRES_NIL_TERMINATION;

Vous remarquerez que le paramètre "etUneListeVariable" et constitué d'un paramètre, ici de type id car je n'ai pas voulu me limiter à un seul type, trois points et une macro système. Voici comment les interpréter:

  • le paramètre va définir tout simplement le type des arguments qui vont suivre
  • les trois petits points suivant une virgule annoncent que le nombre de paramètres est variable
  • le NS_REQUIRES_NIL_TERMINATION n'est pas indispensable, c'est une macro qui déclare au compilateur que la liste des paramètres doit se terminer par un "objet nul", soit nil en objective-C.
l'utilisation dans le .m se fait de cette façon:

-(void) maFonctionAvecUnParametre:(id)param1 etUneListeVariable:(id)param2,...
{
    va_list args;
    va_start(args, param2);

    id valeur = param2;

    //si le premier argument des varargs n'est pas nul
    if(valeur)
    {
        //on boucle sur les éléments la liste des paramètres variable en commençant par le premier, ici param2 
        do {
         //ici mes traitement sur l'objet valeur
        } while ((valeur = va_arg( args, id )));
    }
}
Exemple d'utilisation:

[monObjet maFonctionAvecUnParametre:toto etUneListeVariable:titi, tata, tutu, nil];

[monObjet2 maFonctionAvecUnParametre:toto etUneListeVariable:titi, tata, tutu, tyty, nil];


Voilà pour l'objective-C.
En ce qui concerne le Java et entre autres Android, rien de plus simple, trois petits points suffisent, le langage assimile la liste lui-même à un tableau:


private static void traiterMaListe(Object... params)
{
     for (Object param : params)
     {
          //traitement sur mon param
     }
}

Exemple:

monObjet.traiterMaListe(toto, tata, titi);
monObjet2.traiterMaListe(toto, tata, titi, tutu, tyty);

Pratique n'est-ce pas :)

Voilà pour mon domaine de compétence. Il faut savoir que la syntaxe d'objective-C est directement issue du C, et que d'autres langages comme le PHP par exemple implémentent les fonctions variadiques. Si vous voulez les implémenter dans un de ces langages, cherchez tout simplement varargs + votre langage sur Google, ou regardez sur Wikipedia :)

Twitter