2016-02-21 4 views
5

habe ich eine wörtliche Karte von Schließungen, so etwas wie:In Dart, ist es möglich, eine konstante Karte von Schließungen zu haben?

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

Alle bisher gut. Dann wollte ich diese Map const machen, da sie in meinem Programm global ist und niemals geändert werden sollte.

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

Dart auf diese als die wörtlichen Schließungen in der Karte Drosseln sind nicht const.

Auf Dartpad: https://dartpad.dartlang.org/817d2cfd141b0a56fc7d

Ich hätte gedacht, dass wörtliche Verschlüsse sind const. Gibt es eine Möglichkeit, sie so zu machen?

Antwort

2

Verschlüsse werden in const-Ausdrücken nicht unterstützt.Es ist ein offenes Problem https://github.com/dart-lang/sdk/issues/4596 und https://github.com/Pajn/dep-const-function-literals/issues/1

Wenn Sie stattdessen statische Funktionen erstellen, können Sie sie in konstanten Kartenliteralen referenzieren, aber Sie können sie derzeit nicht inline definieren.

+0

Tolles Ergebnis, ich habe Callback-Kommentare in die Ausgaben platziert, damit die richtigen Antworten in Zukunft von den Autoren gepusht werden. Ansonsten zieh weiter die Information;) –

5

Ich vermute, dies nicht möglich sein könnte, werfen Sie einen Blick auf diesen Code:

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 
}; 

Nur die ersten beiden Versionen die statische Methode Referenzierung referenziert test1 und test2 Arbeit in dieser Konstellation. Sogar f1 erzeugt einen Kompilierungsfehler, UPDATE kompiliert aber mit dartJS als @irn aus den angegebenen Kommentaren. Dann ist unklar, warum die Version mit f2 nicht funktioniert.

Wahrscheinlich ist also der Zuweisungsoperator nicht in der Lage, eine statisch kompilierte Referenz für einen gegebenen konstanten Lambda-Ausdruck oder eine statische Methodenreferenz für sein RHS-Argument (rechte Seite) zu erzeugen.

The documentation wies mich beim Testen der static const Kombination, aber das funktioniert im Allgemeinen nur auf nicht oberste Ebene Elemente wie Klassenmitglieder. Das Hinzufügen einer neuen Klasse ermöglicht es, dies zu testen.

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 
}; 

Diese Funktionsdefinitionen sind jedoch gültig, aber ihre Zuordnung zur Karte schlägt fehl wie zuvor. Die Dokumentation zu Karten im Abschnitt zeigt, wie Sie mithilfe des Schlüsselworts final eine Karte für die Kompilierzeitkonstante erstellen.

final constantMap = const { 
    2: 'helium', 
    10: 'neon', 
    18: 'argon', 
}; 

Leider hat dieser Ansatz den gleichen Nachteil. Es könnte mit den Minimierungsbeschränkungen von Symbolen korellieren:

Ein Symbol-Objekt stellt einen Operator oder eine Kennung dar, die in einem Dart-Programm deklariert wird. Sie müssen möglicherweise nie Symbole verwenden, aber sie sind von unschätzbarem Wert für APIs, die sich namentlich auf Bezeichner beziehen, da die Verminde- rung Bezeichner ändert, aber keine Bezeichner. ... Symbolliterale sind Kompilierzeitkonstanten. Weitere Informationen zu Symbolen finden Sie unter dart:mirrors - reflection.

Vielleicht hat jemand anderes eine bessere Idee, aber für mich scheint das im Moment nicht möglich.

+1

Die 'f1'-Konstante sollte konstant sein, und dart2js hat kein Problem, es zu kompilieren, also scheint es wie ein Analysefehler zu sein, um eine Warnung dafür zu bekommen. – lrn

+0

@lrn Aktualisierte die Antwort. –

+0

Der Grund dafür, dass 'f2' nicht funktioniert, ist, dass ein Funktionsausdruck kein kompilierbarer Konstantenausdruck ist. Die Spezifikation listet die möglichen Konstantenausdrücke zur Kompilierungszeit auf, und Funktionsausdrücke gehören nicht dazu, und der Initialisierungsausdruck einer Konstantenvariablen muss ein kompilierbarer Konstantenausdruck sein. – lrn

Verwandte Themen