如何通过变量向Dart带命名参数的函数传递实参
解决Dart中通过变量向带命名参数的函数传递实参的问题
你这个思路完全可行!问题就出在Function.apply要求的命名参数Map必须是Map<Symbol, dynamic>类型,而不是你现在用的Map<String, String>。我来给你详细拆解一下:
为什么会报错?
Dart的命名参数在底层是通过**Symbol(符号)**来标识的,它是一种用来表示标识符的特殊对象,每个命名参数的名称都会对应一个唯一的Symbol。Function.apply的第三个参数需要的就是这种以Symbol为键的Map,普通字符串键的Map无法直接匹配。
至于你第一次尝试的print(fn(args))报错,是因为fn定义的是仅包含命名参数的函数,没有位置参数,你直接传一个Map进去会被当成位置参数,自然会提示“0个位置参数预期,但传入了1个”。
正确的实现方式
只需要把普通的字符串键Map转换成Symbol键的Map即可,有两种简单的转换方式:
方式1:手动转换Map键
// null safety下建议给参数加可空标记 fn({String? a, String? b, String? c}) { return '$a $b $c'; } var args = {'a': 'foo', 'b': 'bar', 'c': 'baz'}; // 将字符串键转换为Symbol键 var namedArgs = args.map((key, value) => MapEntry(Symbol(key), value)); // 调用Function.apply print(Function.apply(fn, null, namedArgs)); // 输出: foo bar baz
方式2:直接创建Symbol键的Map
如果一开始就知道参数名,也可以直接构建Symbol键的Map:
var namedArgs = { #a: 'foo', #b: 'bar', #c: 'baz' }; print(Function.apply(fn, null, namedArgs));
这里的#a是Dart中创建Symbol的字面量语法,和Symbol('a')是等价的。
补充说明
目前Dart还不支持直接展开普通Map作为命名参数(比如fn(**args)这种语法暂时没有),所以Function.apply是这种动态传递命名参数场景下的最佳方案。
内容的提问来源于stack exchange,提问作者darksoulsong
相关产品推荐
相关产品推荐

