在Dart中,是否可以有闭包的const映射?

时间:2016-02-21 14:31:37

标签: dart

我创建了一个闭包的文字地图,例如:

Map<String, Function> mapOfFuncs = {
  'foo': (a, b, c) => ... ,
  'bar': (a, b, c) => ... ,
   ...
}

到目前为止一切顺利。然后我想制作这张地图const,因为它在我的程序中是全局的,不应该被修改。

const Map<String, Function> MAP_OF_FUNCS = const {
  'foo': (a, b, c) => ... ,
  'bar': (a, b, c) => ... ,
   ...
}

由于地图中的文字闭包不是const,因此飞镖窒息。

在Dartpad上:https://dartpad.dartlang.org/817d2cfd141b0a56fc7d

我原以为文字闭包是const。有没有办法让它们如此?

2 个答案:

答案 0 :(得分:5)

我怀疑这可能无法实现,请看一下这段代码:

for (var i=0; i<cats.length; i++) {
    (function (i) {
        var currCat = cats[i];

        var newDiv = document.createElement("div"); // div for this cat

        var catTitle = document.createElement("h3"); // cat name 
        catTitle.appendChild(document.createTextNode(currCat.name));
        newDiv.appendChild(catTitle);

        var catPhoto = document.createElement("img"); // cat photo
        catPhoto.setAttribute("id", currCat.name + "-photo");
        catPhoto.setAttribute("src", currCat.photo);
        newDiv.appendChild(catPhoto);

        var catPara = document.createElement("p"); // cat click count
        var catSpan = document.createElement("span");
        catSpan.setAttribute("id", currCat.name + "-count");
        catSpan.appendChild(document.createTextNode("0"));
        catPara.appendChild(document.createTextNode(currCat.name + " has been clicked "));
        catPara.appendChild(catSpan);
        catPara.appendChild(document.createTextNode(" times."));
        newDiv.appendChild(catPara);

        catDiv.appendChild(newDiv);

        catPhoto.addEventListener('click', function(){increaseCount(currCat, catSpan);}, false);
    }(i));
}

只有引用静态方法引用int test1(int a, int b, int c) { return a; } int test2(final int a, final int b, final int c) { return a; } const Function f1 = test1; const Function f2 = (final a,b,c) => a; const Map<String, Function> MAP_OF_FUNCS = const { 'foo': test1, 'fam': test2, 'bam': f1, 'bar': f2 }; test1的前两个版本才能在此星座中工作。即使test2产生编译错误, UPDATE ,但是使用dartJS作为@irn从指出的注释中编译。然后不清楚为什么f1的版本无效。

因此,可能是赋值运算符无法为给定的常量lambda表达式生成静态编译的引用,或者为其RHS(右侧)参数生成静态方法引用。

The documentation指出我测试f2组合,但这通常只适用于非顶级元素,如类成员。因此,添加一个新类可以测试它。

static const

但是,这些函数定义有效,但将其分配给映射会失败。有关built in types部分下的地图的文档显示了如何使用class A { static const Function a1 = test1; static const Function a2 = (final a, final b, final c) => a; } const Map<String, Function> MAP_OF_FUNCS = const { 'foo': A.a1, 'bar': A.a2 }; 关键字创建编译时常量映射。

final

不幸的是,这种方法也有同样的缺点。它可能与符号的缩小限制有关:

  

Symbol对象表示Dart程序中声明的运算符或标识符。您可能永远不需要使用符号,但它们对于按名称引用标识符的API非常有用,因为缩小会更改标识符名称而不会更改标识符符号。   ...   符号文字是编译时常量。

     

有关符号的更多信息,请参阅dart:mirrors - reflection

也许其他人有更好的主意,但对我而言,目前这似乎是不可能的。

答案 1 :(得分:3)

const表达式不支持闭包。有一个未解决的问题https://github.com/dart-lang/sdk/issues/4596https://github.com/Pajn/dep-const-function-literals/issues/1

如果您改为创建静态函数,则可以在const映射文字中引用它们,但是您当前无法将它们内联定义。