2012-12-05 19 views
22

Sto cercando un modo per creare una funzione con un numero variabile di argomenti o parametri in Dart. So che potrei creare un parametro array, ma preferirei non farlo perché sto lavorando su una libreria in cui la sintassi sintattica è importante.Creazione di una funzione con numero variabile di argomenti o parametri in Dart

Per esempio, in pianura JavaScript, potremmo fare qualcosa di simile (preso in prestito da here):

function superHeroes() { 
    for (var i = 0; i < arguments.length; i++) { 
    console.log("There's no stopping " + arguments[i]); 
    } 
} 

superHeroes('UberMan', 'Exceptional Woman', 'The Hunk'); 

Tuttavia, in dardo, che il codice non verrà eseguito. C'è un modo per fare la stessa cosa nel dardo? In caso contrario, questo è qualcosa che è sulla tabella di marcia?

risposta

16

Non puoi farlo per ora.

Non so davvero se varargs tornerà - erano lì alcune volte fa ma have been removed.

Tuttavia è possibile emulare varargs con Emulating functions. Vedi lo snippet di codice seguente.

typedef dynamic OnCall(List); 

class VarargsFunction extends Function { 
    OnCall _onCall; 

    VarargsFunction(this._onCall); 

    call() => _onCall([]); 

    noSuchMethod(Invocation invocation) { 
    final arguments = invocation.positionalArguments; 
    return _onCall(arguments); 
    } 
} 

main() { 
    final superHeroes = new VarargsFunction((arguments) { 
    for (final superHero in arguments) { 
     print("There's no stopping ${superHero}"); 
    } 
    }); 
    superHeroes('UberMan', 'Exceptional Woman', 'The Hunk'); 
} 
+0

Wow è una soluzione davvero accurata. Mi piace il modo in cui la dart gestisce gli argomenti, ma questo sarebbe di grande aiuto per gli sviluppatori che amano il contrario. –

+0

Molto bello! Non avevo guardato molto nella parte di InvocationMirror del linguaggio, quindi grazie per un grande esempio.Ho modificato leggermente la tua risposta per creare una versione che funzioni sulla versione corrente di Dart. – plowman

2

Per l'esempio che hai scritto, penso che tu stia meglio usando un elenco. Mi dispiace per quello!

Sto guardando dartbug.com, ma non vedo una richiesta di funzionalità per questo. Sei sicuramente il benvenuto per crearne uno!

5

Ho suonato in giro un po 'con la risposta di Alexandre Ardhuin e ha scoperto che siamo in grado di modificare un paio di cose per fare questo lavoro nella versione corrente di Dart:

class VarArgsClass { 
    noSuchMethod(InvocationMirror invocation) { 
    if (invocation.memberName == 'superheroes') { 
     this.superheroes(invocation.positionalArguments); 
    } 
    } 

    void superheroes(List<String> heroNames) { 
    for (final superHero in heroNames) { 
     print("There's no stopping ${superHero}!"); 
    } 
    } 
} 

main() { 
    new VarArgsClass().superheroes('UberMan', 'Exceptional Woman', 'The Hunk'); 
} 

Questo ha un sacco di problemi, tra cui:

  • Un avviso viene generato ovunque venga chiamato superheroes() perché la firma non corrisponde ai parametri.
  • È necessario eseguire ulteriori controlli manuali per assicurarsi che l'elenco degli argomenti passati ai supereroi sia veramente uno List<String>.
  • La necessità di controllare il nome membro in noSuchMethod() rende più probabile che ti dimenticherai di cambiare la stringa "supereroi" se cambi il nome del metodo.
  • Reflection rende il percorso del codice più difficile da tracciare.

MA se stai bene con tutti questi problemi, allora questo ha il compito.

+1

C'è un altro problema che credo debba essere menzionato: funzionerà solo se passi più di un argomento. Se passi solo una stringa, chiamerai il metodo originale dei supereroi e il macchinario noSuchMethod verrà ignorato. – Ladicek

3

Se si è veramente in sintassi sintassi, basta dichiarare una funzione/metodo con dire 10 parametri posizionali opzionali e fare. È improbabile che qualcuno lo chiamerà con più di 10 argomenti.

Se suona come un hack, è perché è è un hack. Ma ho visto la squadra di Dart fare lo stesso :-)

+0

Ho già aggiunto i metadati @kludge –

+0

E quindi il metodo deve eseguire controlli speciali per ciascuno dei dieci argomenti (se arg1! = Null ..., se arg2! = Null ...)? Schifoso! –

+0

Ho già detto che è un trucco e ha un prezzo che il progettista API potrebbe essere disposto a pagare. – Ladicek

Problemi correlati