Odpowiedzi:
Na stronie darta jest post, który całkiem dobrze to wyjaśnia.
Finał:
„końcowe” oznacza przypisanie pojedyncze: końcowa zmienna lub pole musi mieć inicjator. Po przypisaniu wartości nie można zmienić końcowej wartości zmiennej. final modyfikuje zmienne .
Stała:
„const” ma znaczenie, które w Dart jest nieco bardziej złożone i subtelne. const modyfikuje wartości . Możesz go używać podczas tworzenia kolekcji, takich jak const [1, 2, 3], i podczas konstruowania obiektów (zamiast nowych), takich jak const Point (2, 3). Tutaj const oznacza, że cały głęboki stan obiektu można określić całkowicie w czasie kompilacji i że obiekt zostanie zamrożony i całkowicie niezmienny.
Obiekty Const mają kilka interesujących właściwości i ograniczeń:
Muszą być tworzone na podstawie danych, które można obliczyć w czasie kompilacji. Obiekt const nie ma dostępu do niczego, co musiałbyś obliczyć w czasie wykonywania. 1 + 2 to prawidłowe wyrażenie const, ale new DateTime.now () już nie.
Są głęboko, przejściowo niezmienne. Jeśli masz ostatnie pole zawierające kolekcję, ta kolekcja nadal może być modyfikowalna. Jeśli masz kolekcję const, wszystko w niej musi być również const, rekurencyjnie.
Są kanonizowane . Jest to coś w rodzaju internowania ciągów: dla każdej podanej wartości stałej zostanie utworzony i ponownie użyty pojedynczy obiekt const, bez względu na to, ile razy wyrażenie (a) const jest oceniane.
Const:
Jeżeli wartość masz jest obliczana w czasie wykonywania ( new DateTime.now()
na przykład), można nie używać const dla niego. Jeśli jednak wartość jest znana w czasie kompilacji ( const a = 1;
), należy użyć const
over final
. Istnieją 2 inne duże różnice między const
i final
. Po pierwsze, jeśli używasz const
, musisz zadeklarować to jako, static const
a nie tylko const
. Po drugie, jeśli masz const
kolekcję, wszystko w niej znajduje się const
. Jeśli masz final
kolekcję, wszystko w niej nie jest final
.
Final:
final
powinno być użyte powyżej, const
jeśli nie znasz wartości w czasie kompilacji i zostanie obliczona / pobrana w czasie wykonywania. Jeśli potrzebujesz odpowiedzi HTTP, której nie można zmienić, jeśli chcesz uzyskać coś z bazy danych lub jeśli chcesz odczytać z pliku lokalnego, użyj final
. Wszystko, co nie jest znane w czasie kompilacji, powinno się final
skończyć const
.
Biorąc to wszystko pod uwagę, zarówno const
i final
nie można ich ponownie przypisać, ale pola w final
obiekcie, o ile nie są const
lub final
, można ponownie przypisać (w przeciwieństwie const
).
const
i kiedy final
? Czy znasz jakieś zastosowanie tego modyfikatora?
Wartość musi być znana w czasie kompilacji ,
const birthday = "2008/12/26"
nie można jej zmienić po zainicjowaniu.
Wartość musi być znana w czasie wykonywania ,
final birthday = getBirthDateFromDB()
nie można jej zmienić po zainicjowaniu.
Skonsolidowane odpowiedzi @Meyi i @ faisal-naseer oraz porównanie z niewielkim programowaniem.
słowo kluczowe const używane do utworzenia zmiennej do przechowywania wartości stałej czasu kompilacji . Wartość stałej czasowej kompilacji to wartość, która będzie stała podczas kompilacji :-)
Na przykład 5
jest stałą czasową kompilacji. Chociaż DateTime.now()
nie jest to stała czasowa kompilacji. Ponieważ ta metoda zwróci czas, w którym linia jest wykonywana w czasie wykonywania. Więc nie możemy przypisać DateTime.now()
do const
zmiennej.
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();
Powinien zostać zainicjowany w tym samym wierszu .
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;
Wszystkie poniższe stwierdzenia są dopuszczalne.
// Without type or var
const a = 5;
// With a type
const int b = 5;
// With var
const var c = 6;
Zmienna const poziomu klasy powinna być zainicjowana jak poniżej.
Class A {
static const a = 5;
}
Zmienna const na poziomie instancji nie jest możliwa .
Class A {
// Uncommenting below statement will give compilation error.
// Because const is not possible to be used with instance level
// variable.
// const a = 5;
}
Innym głównym zastosowaniem const
jest uczynienie obiektu niezmiennym . Aby obiekt klasy stał się niezmienny, musimy użyć słowa kluczowego const z konstruktorem i nadać wszystkim polom ostateczne wartości, jak wspomniano poniżej.
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);
}
możemy użyć słowa kluczowego const do listy .
const a = const [] - Zmienna a
zainicjowana jako const
zawierająca listę const
obiektów (tj. lista powinna zawierać tylko stałą czasu kompilacji i niezmienne obiekty). Nie możemya
więc przypisać innej listy .
var a = const [] - Zmienna a
zainicjowana jako var
zawierająca const
obiekty listy . Więc możemy przypisać inną listę do zmienneja
.
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)];
}
Słowo kluczowe final również służyło do ustawiania zmiennej jako stałej wartości . Po zainicjowaniu nie możemy zmienić wartości.
final a = 5;
// Uncommenting below statement will give compilation error.
// Because a is declared as final.
// a = 6;
Wszystkie poniższe stwierdzenia są dopuszczalne.
// Without type or var
final a = 5;
// With a type
final int b = 5;
// With var
final var c = 6;
Potrafi przypisać wartość wykonawczą .
// 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;
Zmienna końcowa na poziomie klasy musi zostać zainicjowana w tym samym wierszu.
Class A {
static final a = 5;
static final b = DateTime.now();
}
Zmienna końcowa na poziomie instancji musi zostać zainicjowana w tym samym wierszu lub w inicjalizacji konstruktora. Wartość zostanie zapisana w pamięci podczas tworzenia obiektu.
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);
}
Przypisywanie listy .
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()];
Rozszerzenie odpowiedzi o @Meyi
biggestNumberOndice
tylko wtedy wartość zostanie zainicjowana i zostanie przypisana pamięć).const ma wewnętrznie ostateczny charakter, ale główną różnicą jest to, że jego stała czasu kompilacji, która jest inicjowana podczas kompilacji, nawet jeśli nie używasz jej wartości, zostanie zainicjowana i zajmie miejsce w pamięci.
Zmienna z klas może być ostateczna, ale nie stała, a jeśli chcesz mieć stałą na poziomie klasy, uczyń ją stałą statyczną.
Kod:
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;
}
Oba final
i const
zapobiegają ponownemu przypisaniu zmiennej (podobnie jak final
działa w Javie lub jak const
działa w JavaScript).
Różnica dotyczy sposobu alokacji pamięci. Pamięć jest przydzielana dla final
zmiennej w czasie wykonywania i dla const
zmiennej w czasie kompilacji. final
Modyfikator powinny być powszechnie stosowane, ponieważ wiele zmiennych, program nie wymaga żadnego pamięć ponieważ logika programu nie będzie wymagać, żeby zostać zainicjowany. Za pomocą const
zmiennej w zasadzie mówisz komputerowi: „Hej, potrzebuję pamięci na tę zmienną z góry, ponieważ wiem, że będę jej potrzebować”.
Myślenie o nich w ten sposób ułatwia zrozumienie różnic w ich użyciu składniowym. Przede wszystkim final
zmienna może być zmienną instancji, ale const
musi być static
zmienną w klasie. Dzieje się tak, ponieważ zmienne instancji są tworzone w czasie wykonywania, a const
zmienne - z definicji - nie. Tak więc const
zmienne w klasie muszą być static
, co oznacza po prostu, że pojedyncza kopia tej zmiennej istnieje w klasie, niezależnie od tego, czy ta klasa jest tworzona.
Ten film wyjaśnia to dość prosto: https://www.youtube.com/watch?v=9ZZL3iyf4Vk
Ten artykuł jest bardziej szczegółowy i wyjaśnia bardzo ważną różnicę semantyczną między nimi, tj. final
Modyfikuje zmienne i const
modyfikuje wartości, co w istocie sprowadza się do możliwości inicjowania tylko const
wartości, które można wyprowadzić w czasie kompilacji.
https://news.dartlang.org/2012/06/const-static-final-oh-my.html
Jeżeli przyjeżdżasz z C++
czym const
się Dart
to constexpr
w C++
i final
w Dart
jest const
w C++
.
Powyższe dotyczy tylko typów pierwotnych. Jednak w Dart
obiektach zaznaczone final
są zmienne pod względem swoich członków.
const
w C ++ jest prawie zawsze używany do określenia, że obiekt nie jest zmienny przez określone odwołanie lub wskaźnik. final
w Dart nie zapobiega mutacji obiektu przez tę zmienną.
Kiedy używać którego słowa kluczowego?
Prosty przykład dla obu: Użyj final: Jeśli nie wiesz, jaka będzie jego wartość w czasie kompilacji. Na przykład, gdy trzeba pobrać dane z interfejsu API, dzieje się tak podczas uruchamiania kodu.
Użyj const: jeśli masz pewność, że wartość nie zostanie zmieniona podczas uruchamiania kodu. Na przykład, gdy deklarujesz zdanie, które zawsze pozostaje takie samo.
https://itnext.io/difference-between-const-and-final-in-dart-78c129d0c573
const
: stackoverflow.com/questions/51576209/ ... a prosta eksplonacjafinal
jest stała (nie można ponownie przypisać ani przypisać po utworzeniu za pomocą końcowego słowa kluczowego) i trzeba ją raz zainicjować.