Risposte:
C'è un post sul sito Web di Dart e lo spiega abbastanza bene.
Finale:
"final" significa assegnazione singola: una variabile o un campo finale deve avere un inizializzatore. Una volta assegnato un valore, il valore di una variabile finale non può essere modificato. finale modifica le variabili .
const:
"const" ha un significato un po 'più complesso e sottile in Dart. const modifica i valori . Puoi usarlo quando crei raccolte, come const [1, 2, 3] e quando costruisci oggetti (invece di nuovi) come const Point (2, 3). Qui const significa che l'intero stato profondo dell'oggetto può essere determinato interamente al momento della compilazione e che l'oggetto sarà congelato e completamente immutabile.
Gli oggetti Const hanno un paio di proprietà e restrizioni interessanti:
Devono essere creati da dati che possono essere calcolati in fase di compilazione. Un oggetto const non ha accesso a tutto ciò che dovresti calcolare in fase di esecuzione. 1 + 2 è un'espressione const valida, ma il nuovo DateTime.now () non lo è.
Sono profondamente, transitivamente immutabili. Se si dispone di un campo finale contenente una raccolta, tale raccolta può essere comunque modificabile. Se hai una collezione const, anche tutto ciò che deve essere const deve essere ricorsivo.
Sono canonicalizzati . Questo è un po 'come lo string interning: per ogni dato valore const, verrà creato e riutilizzato un singolo oggetto const indipendentemente da quante volte vengono valutate le espressioni const.
Const:
Se il valore si dispone è calcolato in fase di esecuzione ( new DateTime.now()
per esempio), è possibile non utilizzare un const per esso. Tuttavia, se il valore è noto al momento della compilazione ( const a = 1;
), è necessario utilizzare const
over final
. Ci sono altre 2 grandi differenze tra const
e final
. In primo luogo, se lo stai utilizzando const
, devi dichiararlo come static const
non solo const
. In secondo luogo, se hai una const
collezione, tutto ciò che è dentro è dentro const
. Se hai una final
collezione, tutto ciò che non lo è final
.
Finale:
final
deve essere utilizzato const
se non si conosce il valore in fase di compilazione e verrà calcolato / acquisito in fase di esecuzione. Se si desidera una risposta HTTP che non può essere modificata, se si desidera ottenere qualcosa da un database o se si desidera leggere da un file locale, utilizzare final
. Tutto ciò che non è noto al momento della compilazione dovrebbe essere final
finito const
.
Detto questo, entrambi const
e final
non possono essere riassegnati, ma i campi in un final
oggetto, purché non lo siano const
o final
, possono essere riassegnati (a differenza const
).
const
e quando final
? Conosci una sorta di caso d'uso per questi modificatori?
Il valore deve essere noto al momento della compilazione ,
const birthday = "2008/12/26"
non può essere modificato dopo l'inizializzazione.
Il valore deve essere noto in fase di esecuzione ,
final birthday = getBirthDateFromDB()
non può essere modificato dopo l'inizializzazione.
Risposte @Meyi e @ faisal-naseer consolidate e confronto con poca programmazione.
parola chiave const utilizzata per creare una variabile per memorizzare un valore costante di tempo di compilazione . Il valore della costante del tempo di compilazione è un valore che sarà costante durante la compilazione :-)
Ad esempio 5
è una costante di tempo di compilazione. Mentre DateTime.now()
ciò non è costante di tempo di compilazione. Perché questo metodo restituirà il momento in cui la linea viene eseguita in fase di esecuzione. Quindi non possiamo assegnare DateTime.now()
a una const
variabile.
const a = 5;
// Uncommenting below statement will cause compile time error.
// Because we can't able to assign a runtime value to a const variable
// const b = DateTime.now();
Dovrebbe essere inizializzato sulla stessa riga .
const a = 5;
// Uncommenting below 2 statement will cause compilation error.
// Because const variable must be initialized at the same line.
// const b;
// b = 6;
Tutte le dichiarazioni menzionate di seguito sono accettabili.
// Without type or var
const a = 5;
// With a type
const int b = 5;
// With var
const var c = 6;
La variabile const a livello di classe deve essere inizializzata come di seguito.
Class A {
static const a = 5;
}
La variabile const a livello di istanza non è possibile .
Class A {
// Uncommenting below statement will give compilation error.
// Because const is not possible to be used with instance level
// variable.
// const a = 5;
}
L'altro uso principale di const
viene utilizzato per rendere immutabile l' oggetto . Per rendere immutabile un oggetto classe dobbiamo usare la parola chiave const con il costruttore e rendere tutti i campi come finali come indicato di seguito.
Class A {
final a, b;
const A(this.a, this.b);
}
void main () {
// There is no way to change a field of object once it's
// initialized.
const immutableObja = const A(5, 6);
// Uncommenting below statement will give compilation error.
// Because you are trying to reinitialize a const variable
// with other value
// immutableObja = const A(7, 9);
// But the below one is not the same. Because we are mentioning objA
// is a variable of a class A. Not const. So we can able to assign
// another object of class A to objA.
A objA = const A(8, 9);
// Below statement is acceptable.
objA = const A(10, 11);
}
possiamo usare la parola chiave const in un elenco .
const a = const [] - Una variabile a
inizializzata in quanto const
contiene un elenco di const
oggetti (ovvero, l'elenco deve contenere solo oggetti costanti di tempo di compilazione e immutabili). Quindi non siamo in grado di assegnare a
con un altro elenco .
var a = const [] - Una variabile a
inizializzata come var
contenente const
oggetti di un elenco . Quindi possiamo assegnare un altro elenco alla variabilea
.
Class A {
final a, b;
const A(this.a, this.b);
}
class B {
B(){ // Doing something }
}
void main() {
const constantListOfInt = const [5, 6, 7,
// Uncommenting below statement give compilation error.
// Because we are trying to add a runtime value
// to a constant list
// DateTime.now().millisecondsSinceEpoch
];
const constantListOfConstantObjA = const [
A(5, 6),
A(55, 88),
A(100, 9),
];
// Uncommenting below 2 statements will give compilation error.
// Because we are trying to reinitialize with a new list.
// constantListOfInt = [8, 9, 10];
// constantListOfConstantObjA = const[A(55, 77)];
// But the following lines are little different. Because we are just
// trying to assign a list of constant values to a variable. Which
// is acceptable
var variableWithConstantList = const [5, 6, 7];
variableWithConstantList = const [10, 11, 15];
var variableOfConstantListOfObjA = const [A(5, 8), A(7, 9), A(10, 4)];
variableWithConstantList = const [A(9, 10)];
}
parola chiave finale utilizzata anche per fare in modo che la variabile mantenga un valore costante . Una volta inizializzato, non è possibile modificare il valore.
final a = 5;
// Uncommenting below statement will give compilation error.
// Because a is declared as final.
// a = 6;
Tutte le dichiarazioni menzionate di seguito sono accettabili.
// Without type or var
final a = 5;
// With a type
final int b = 5;
// With var
final var c = 6;
È in grado di assegnare un valore di runtime .
// DateTime.now() will return the time when the line is getting
// executed. Which is a runtime value.
final a = DateTime.now();
var b = 5;
final c = b;
La variabile finale a livello di classe deve essere inizializzata nella stessa riga.
Class A {
static final a = 5;
static final b = DateTime.now();
}
La variabile finale a livello di istanza deve essere inizializzata nella stessa riga o nell'inizializzazione del costruttore. Il valore verrà messo in memoria quando viene creato l'oggetto.
Class A {
final a = 5;
}
// Constructor with a parameter.
Class B {
final b;
B(this.b);
}
// Constructor with multiple parameter.
Class C {
final c;
C(this.c, int d) {
// Do something with d
}
}
void main() {
A objA = new A();
B objB = new B(5);
C objC = new C(5, 6);
}
Assegnare un elenco .
final a = [5, 6, 7, 5.6, A()];
// Uncommenting Below statement will give compilation error.
// Because we are trying to reinitialize the object with another list.
// a = [9.9, 10, B()];
Estensione della risposta di @Meyi
biggestNumberOndice
solo allora il valore verrà inizializzato e la memoria verrà assegnata).const è internamente di natura finale, ma la differenza principale è che la sua costante di tempo di compilazione che viene inizializzata durante la compilazione anche se non si utilizza il suo valore verrà inizializzata e occuperà spazio in memoria.
La variabile dalle classi può essere finale ma non costante e se si desidera una costante a livello di classe, renderla statica const.
Codice:
void main() {
// final demonstration
final biggestNumberOndice = '6';
// biggestNumberOndice = '8'; // Throws an error for reinitialization
// const
const smallestNumberOnDice = 1;
}
class TestClass {
final biggestNumberOndice = '6';
//const smallestNumberOnDice = 1; //Throws an error
//Error . only static fields can be declared as constants.
static const smallestNumberOnDice = 1;
}
Entrambi final
e const
impediscono la riassegnazione di una variabile (simile a come final
funziona in Java o come const
funziona in JavaScript).
La differenza ha a che fare con l'allocazione della memoria. La memoria è allocata per afinal
variabile in fase di esecuzione e per una const
variabile in fase di compilazione. Il final
modificatore dovrebbe essere il più comunemente usato, perché molte variabili di programma non avranno bisogno di memoria poiché la logica del programma non richiederà l'inizializzazione di esse. Con una const
variabile stai praticamente dicendo al computer: "Ehi, ho bisogno di memoria per questa variabile in anticipo perché so che ne avrò bisogno."
Pensarli in questo modo semplifica la comprensione delle differenze nel loro utilizzo sintattico. Principalmente che una final
variabile può essere una variabile di istanza, ma a const
deve essere astatic
variabile in una classe. Questo perché le variabili di istanza vengono create in fase di esecuzione e le const
variabili, per definizione, non lo sono. Pertanto, le const
variabili su una classe devono essere static
, il che significa semplicemente che esiste una sola copia di quella variabile su una classe, indipendentemente dal fatto che quella classe sia istanziata.
Questo video lo scompone in modo abbastanza semplice: https://www.youtube.com/watch?v=9ZZL3iyf4Vk
Questo articolo approfondisce e spiega un'importantissima differenza semantica tra i due, ovvero final
modifica le variabili econst
modifica i valori, che si riduce essenzialmente alla possibilità di inizializzare solo const
valori che sono derivabili in fase di compilazione.
https://news.dartlang.org/2012/06/const-static-final-oh-my.html
Se vieni da C++
allora const
in Dart
è constexpr
in C++
e final
in Dart
è const
in C++
.
Quanto sopra si applica solo ai tipi primitivi. Tuttavia negli Dart
oggetti contrassegnatifinal
sono modificabili in termini di membri.
const
in C ++ viene quasi sempre usato per specificare che un oggetto non è mutabile attraverso un riferimento o un puntatore specifici. final
in Dart non impedisce che l'oggetto venga mutato attraverso quella variabile.
Quando utilizzare quale parola chiave?
Un semplice esempio per entrambi: Usa final: se non sai quale sarà il suo valore al momento della compilazione. Ad esempio, quando è necessario ottenere dati da un'API, ciò accade quando si esegue il codice.
Usa const: se sei sicuro che un valore non verrà modificato durante l'esecuzione del codice. Ad esempio, quando dichiari una frase che rimane sempre la stessa.
https://itnext.io/difference-between-const-and-final-in-dart-78c129d0c573
const
: stackoverflow.com/questions/51576209/... e il semplice explonation afinal
è costante (non può riassegnare o assegnare una volta creati con parola chiave final) e si deve inizializzare una volta.