Creating function with variable number of arguments or parameters in Dart

You can't do that for now.

I don't really know if varargs will come back - they were there some times ago but have been removed.

However it is possible to emulate varargs with Emulating functions. See the below code snippet.

typedef OnCall = dynamic Function(List arguments);

class VarargsFunction {
  VarargsFunction(this._onCall);
  
  final OnCall _onCall;

  noSuchMethod(Invocation invocation) {
    if (!invocation.isMethod || invocation.namedArguments.isNotEmpty)
      super.noSuchMethod(invocation);
    final arguments = invocation.positionalArguments;
    return _onCall(arguments);
  }
}

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

I played around a little with Alexandre Ardhuin's answer and found that we can tweak a couple of things to make this work in the current version of 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');
}

This has lots of problems, including:

  • A warning is generated wherever you call superheroes() because the signature doesn't match your parameters.
  • More manual checking would need to be done to make sure the list of arguments passed to superheroes is really a List<String>.
  • Needing to check the member name in noSuchMethod() makes it more likely you'll forget to change the 'superheroes' string if you change the method name.
  • Reflection makes the code path harder to trace.

BUT if you are fine with all of those issues, then this gets the job done.


Dart does indirectly support var-args as long as you aren't too much into syntactic brevity.

void testFunction([List<dynamic> args=[]])
{
  for(dynamic arg:args)
  {
    // Handle each arg...
  }
}

testFunction([0, 1, 2, 3, 4, 5, 6]);
testFunction();
testFunction([0, 1, 2]);

Note: You can do the same thing with named parameters, but you'll have to handle things internally, just in case if the user (of that function; which could be you) decides to not pass any value to that named parameter.


I would like to thank @Ladicek for indirectly letting me know that a word like brevity exists in English.

Tags:

Dart