2016-02-21 26 views
5

Ho creato una mappa letterale di chiusure, qualcosa come:In Dart, è possibile avere una mappa const di chiusure?

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

Tutto bene finora. Quindi volevo creare questa mappa const, poiché è globale all'interno del mio programma e non dovrebbe mai essere modificata.

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

Dart soffoca su questo, come le chiusure letterali nella mappa non sono const.

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

avrei pensato che le chiusure sono letterali const. C'è un modo per renderli così?

risposta

2

Le chiusure non sono supportate nelle espressioni const.C'è un problema aperto https://github.com/dart-lang/sdk/issues/4596 e https://github.com/Pajn/dep-const-function-literals/issues/1

Se si creano invece funzioni statiche, è possibile fare riferimento a tali valori in letterali const-map, ma attualmente non è possibile definirli in linea.

+0

Grande scoperta, ho inserito i commenti di callback nei problemi in modo che le risposte corrette potrebbero essere spinte in futuro dagli autori. Altrimenti continua a tirare le informazioni;) –

5

Ho il sospetto che questo potrebbe non essere possibile, dare un'occhiata a questo codice:

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

Solo le prime due versioni che fanno riferimento al metodo statico fa riferimento test1 e test2 lavoro in questa costellazione. Anche f1 produce un errore di compilazione, UPDATE ma compila usando dartJS come @irn dai commenti evidenziati. Quindi non è chiaro il motivo per cui la versione con f2 non funziona.

Probabilmente è l'operatore di assegnazione che non è in grado di produrre un riferimento compilato staticamente per una determinata espressione lambda costante o un riferimento al metodo statico per l'argomento RHS (lato destro).

The documentation mi ha indicato per testare la combinazione static const, ma generalmente funziona solo su elementi di livello non superiore come i membri della classe. Quindi aggiungere una nuova classe rende possibile testarlo.

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

Tuttavia, queste definizioni di funzione sono validi, ma l'assegnazione alla mappa fallisce come prima. La documentazione sulle mappe nella sezione built in types mostra come creare una mappa di costante di tempo di compilazione utilizzando la parola chiave final.

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

Sfortunatamente, questo approccio ha lo stesso inconveniente. Potrebbe coraziarsi con i limiti di limitazione dei simboli:

Un oggetto simbolo rappresenta un operatore o un identificatore dichiarato in un programma Dart. Potrebbe non essere necessario utilizzare simboli, ma sono inestimabili per le API che fanno riferimento agli identificatori per nome, poiché la minificazione modifica i nomi degli identificatori ma non i simboli identificativi. ... I valori letterali dei simboli sono costanti in fase di compilazione.

Per ulteriori informazioni sui simboli, vedere dart:mirrors - reflection.

Forse qualcun altro ha un'idea migliore, ma per me questo non sembra possibile per il momento.

+1

La costante 'f1' dovrebbe essere costante e dart2js non ha problemi a compilarlo, quindi sembra un errore analizzatore per ottenere un avviso. – lrn

+0

@lrn Aggiornamento della risposta. –

+0

La ragione per cui 'f2' non funziona è che un'espressione di funzione non è un'espressione di costante in fase di compilazione. La specifica elenca le possibili espressioni costanti in fase di compilazione, e le espressioni di funzione non sono tra queste e l'espressione di inizializzazione di una variabile const deve essere un'espressione di costante in fase di compilazione. – lrn

Problemi correlati