Dart doesn’t support varargs. So we can’t call a function or create a class that accepts variable numbers of arguments. And it is not handy in some cases.
Suppose we want to create a log function that will accept variable numbers of arguments. We can’t do that in Dart. We need to call the log function multiple times just to dump logs into the console for multiple items.
Again, we can’t also use variable numbers of named arguments in Dart.
For example, we can’t do this in Dart.
|
|
Dart initially supported varargs but removed them later for the sake of simplicity. There is also an issue in the dart-lang repo that has been open for a long time, since 2014!
So, it seems there’s no luck anytime soon for getting varargs back into the language!
But we can apply a neat trick to get this work in Dart for both positional and named variable numbers arguments!
We can override the noSuchMethod(Invocation invocation)
method in an Object
to simulate this. When a nonexistent
method is called on an instance of an Object
, it internally calls this method and we can get access to all positional
and named arguments from this method using invocation.positionalArguments
and invocation.namedArguments
. Great!
Let’s code this. First, we need to define the function that accepts a variable number of positional and named arguments.
|
|
Here for positional arguments, we use List<dynamic>
args and for named arguments we use Map<Symbol, dynamic>
kwargs .
Now let’s define the actual class that will be responsible for tricking Dart.
|
|
Here, when we call an instance of VariadicFunction
as a method, and as it is NOT a method, it will invoke
the noSuchMethod
, thus doing the trick!
Now it’s time to implement the logs()
function that we have mentioned earlier using VariadicFunction
.
|
|
Here, we first joined all positional arguments as a string. For named arguments, we need to get the named arguments’ symbol names. But the toString() gives us Symbol(“name”) . So we are removing this object name by using replaceAll and then joining them as a string.
Then we print them on the console by using the log() function defined in the dart:developer
module.
Last but not least, we need to erase the type of VariadicFunction by adding as dynamic . Otherwise, we can’t invoke it as a method as it is NOT a method and it will give us a compiler error.
Then when we invoke logs as a method, it will eventually invoke the noSuchMethod and we get a function with args and kwargs just as in Python!
Mission accomplished!
Now we can this function to logs and it will accept arbitrary numbers of positional and named arguments. Great!
Final Code: https://gist.github.com/SNNafi/ed9d4ee98ace0d5b8ec9184f6c468d39
Reference: https://stackoverflow.com/questions/13731631/creating-function-with-variable-number-of-arguments-or-parameters-in-dart