我正在寻找一种在Dart中使用可变数量的参数或参数创建函数的方法。我知道我可以创建一个数组参数,但我宁愿不这样做,因为我正在开发一个语法简洁很重要的库。
例如,在纯JavaScript中,我们可以做这样的事情(借鉴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');
然而,在dart中,该代码将无法运行。有没有办法在飞镖中做同样的事情?如果没有,这是路线图上的内容吗?
答案 0 :(得分:19)
你现在不能这样做。
我真的不知道 varargs 是否会回来 - 他们曾在那里见过have been removed。
但是可以使用Emulating functions模拟 varargs 。请参阅以下代码段。
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');
}
答案 1 :(得分:5)
我在Alexandre Ardhuin的回答中玩了一下,发现我们可以调整一些东西,使其在当前版本的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');
}
这有很多问题,包括:
superheroes()
,就会生成警告,因为签名与您的参数不符。List<String>
。noSuchMethod()
中的成员名称,如果更改方法名称,则更有可能忘记更改“超级英雄”字符串。但如果你对所有这些问题都很好,那么这就完成了工作。
答案 2 :(得分:3)
如果你真的想要语法简洁,只需声明一个函数/方法,并说明10个可选的位置参数即可。不太可能有人会用超过10个参数来调用它。
如果它听起来像是黑客,那是因为 是黑客攻击。但是我看到Dart团队做了同样的事情: - )
答案 3 :(得分:3)
只要您不太习惯语法简洁,Dart就会间接支持var-args。
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]);
注意:您可以使用命名参数执行相同的操作,但必须在内部进行处理,以防万一(该功能的用户;可能是您)决定不会将任何值传递给该命名参数。
我要感谢@Ladicek间接让我知道英语中存在诸如简洁之类的词。
答案 4 :(得分:2)
对于您编写的示例,我认为您最好使用列表。对不起!
我正在看dartbug.com,但我没有看到这方面的功能请求。你绝对欢迎创建一个!
答案 5 :(得分:0)
此版本:
typedef T VarArgsCallback<T>(List<dynamic> args, Map<String, dynamic> kwargs);
class VarArgsFunction<T> {
final VarArgsCallback<T> callback;
static var _offset = 'Symbol("'.length;
VarArgsFunction(this.callback);
T call() => callback([], {});
@override
dynamic noSuchMethod(Invocation inv) {
return callback(
inv.positionalArguments,
inv.namedArguments.map(
(_k, v) {
var k = _k.toString();
return MapEntry(k.substring(_offset, k.length - 2), v);
},
),
);
}
}
main() {
dynamic myFunc = VarArgsFunction((args, kwargs) {
print('Got args: $args, kwargs: $kwargs');
});
myFunc(1, 2, x: true, y: false); // Got args: [1, 2], kwargs: {x: true, y: false}
}
谢谢亚历山大(Alexandre)的answer!