Відповіді:
На сайті дартса є публікація, і це досить добре пояснює.
Фінал:
"final" означає однозначне призначення: остаточна змінна або поле має мати ініціалізатор. Після призначення значення значення остаточної змінної не можна змінити. остаточний змінює змінні .
Const:
"const" має значення, яке є дещо складнішим і тонкішим у Dart. const змінює значення . Ви можете використовувати його під час створення колекцій, як const [1, 2, 3], і при побудові об'єктів (замість нових), таких як Const Point (2, 3). Тут const означає, що весь глибокий стан об'єкта може бути визначений повністю під час компіляції і що об'єкт буде застигнутим і повністю незмінним.
Об'єкти Const мають кілька цікавих властивостей та обмежень:
Вони повинні бути створені з даних, які можна обчислити під час компіляції. Об'єкт const не має доступу до всього, що вам потрібно було б обчислити під час виконання. 1 + 2 - допустимий вираз const, але новий DateTime.now () - ні.
Вони глибоко, транзитивно незмінні. Якщо у вас є остаточне поле, що містить колекцію, ця збірка все ще може бути зміненою. Якщо у вас є колекція const, все в ній також повинно бути const, рекурсивно.
Вони канонізовані . Це щось на зразок інтернування інтерфейсу: для будь-якого заданого значення const один об'єкт const буде створений та повторно використаний незалежно від того, скільки разів виражаються вирази const.
Const:
Якщо значення, яке ви маєте, обчислюється під час виконання ( new DateTime.now()наприклад), ви не можете використовувати const для нього. Однак, якщо значення відомо під час компіляції ( const a = 1;), тоді вам слід скористатися constнад final. Є ще 2 великі відмінності між constта final. По-перше, якщо ви використовуєте const, ви повинні оголосити це як static constпросто, а не просто const. По-друге, якщо у вас є constколекція, все, що знаходиться всередині цього є const. Якщо у вас є finalколекція, все всередині цього немає final .
Остаточний: його
final слід використовувати, constякщо ви не знаєте значення під час компіляції, і воно буде обчислено / схоплено під час виконання. Якщо ви хочете відповідь HTTP, яку неможливо змінити, якщо ви хочете отримати щось із бази даних, або якщо ви хочете прочитати з локального файлу, використовуйте final. Все, що не відомо на час компіляції, має finalзакінчитися const.
Незважаючи на все сказане, обидва constі finalне можуть бути перепризначені, але поля в finalоб'єкті, доки їх немає constабо finalможуть бути перепризначені (на відміну від const).
constі коли final? Чи знаєте ви якийсь варіант використання цього модифікатора?
Значення повинно бути відоме під час компіляції , його
const birthday = "2008/12/26"
неможливо змінити після ініціалізації.
Значення має бути відомо , в перспективі часу ,
final birthday = getBirthDateFromDB()
не може бути змінено після ініціалізації.
Зведені відповіді @Meyi і @ faisal-naseer та порівняння з невеликим програмуванням.
Ключове слово const використовується для створення змінної для зберігання постійного значення часу компіляції . Постійна величина часу компіляції - це значення, яке буде постійним при компілюванні :-)
Наприклад 5, константа часу компіляції. Хоча DateTime.now()це не константа часу компіляції. Тому що цей метод поверне час, коли рядок виконується під час виконання. Таким чином , ми не можемо привласнити DateTime.now()до constзмінної.
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();
Потрібно ініціалізувати в одному рядку .
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;
Усі заяви, зазначені нижче, є прийнятними.
// Without type or var
const a = 5;
// With a type
const int b = 5;
// With var
const var c = 6;
Змінна const рівня класу повинна бути ініціалізована як нижче.
Class A {
static const a = 5;
}
Змінна const рівня екземпляра неможлива .
Class A {
// Uncommenting below statement will give compilation error.
// Because const is not possible to be used with instance level
// variable.
// const a = 5;
}
Інше основне використання constвикористовується для того, щоб зробити об'єкт непорушним . Щоб зробити об’єкт класу незмінним, нам потрібно використовувати ключове слово const з конструктором і зробити всі поля такими, як зазначено нижче.
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);
}
ми можемо використовувати ключове слово const до списку .
const a = const [] - змінна, a ініціалізована як така, constщо містить перелік constоб'єктів (тобто список повинен містити лише константи часу компіляції та незмінні об'єкти). Тому ми не можемо призначити aінший список .
var a = const [] - a Ініціалізованаvarconst змінна , яка містить об'єкти списку . Таким чином ми можемо призначити інший список зміннійa .
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)];
}
Остаточне ключове слово також використовується для того, щоб змінна містила постійне значення . Після ініціалізації ми не зможемо змінити значення.
final a = 5;
// Uncommenting below statement will give compilation error.
// Because a is declared as final.
// a = 6;
Усі заяви, зазначені нижче, є прийнятними.
// Without type or var
final a = 5;
// With a type
final int b = 5;
// With var
final var c = 6;
Може призначити значення часу виконання .
// 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;
Кінцева змінна рівня класу повинна бути ініціалізована в одному рядку.
Class A {
static final a = 5;
static final b = DateTime.now();
}
Кінцеву змінну рівня екземпляра необхідно ініціалізувати в тому ж рядку або в ініціалізації конструктора. Значення буде збережено в пам'яті, коли об’єкт створений.
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);
}
Призначення списку .
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()];
Подовження відповіді від @Meyi
biggestNumberOndiceлише тоді, значення буде ініціалізовано і буде призначено пам'ять).const є внутрішньо остаточним за своєю суттю, але головна відмінність полягає в тому, що його константа часу компіляції, яка ініціалізується під час компіляції, навіть якщо ви не використовуєте її значення, вона буде ініціалізована і займе місце в пам'яті.
Змінна від класів може бути остаточною, але не постійною, і якщо ви хочете константа на рівні класу, зробіть це статичним const.
Код:
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;
}
І те, finalі constінше запобігає переназначенню змінної (подібно до того, як finalпрацює в Java або як constпрацює в JavaScript).
Різниця пов'язана з тим, як розподіляється пам'ять. Пам'ять виділяється для finalзмінної під час виконання, а для constзмінної - під час компіляції. finalМодифікатор повинен бути більш широко використовується, тому що багато програмні змінні не потрібна пам'ять , так як логіка програми не буде вимагати їх ініціалізації. Зі constзмінною ви в основному говорите комп'ютеру: "Ей, мені потрібна пам'ять для цієї змінної вперед, тому що я знаю, що мені це потрібно".
Мислення про них таким чином полегшує розуміння відмінностей у їх синтаксичному використанні. Головним чином, що finalзмінна може бути змінною екземпляра, але constповинна бути staticзмінною у класі. Це відбувається тому, що змінні екземплярів створюються під час виконання, а constзмінні - за визначенням - ні. Таким чином, constзмінні класу повинні бути static, а це означає, що одна копія цієї змінної існує в класі, незалежно від того, чи є цей клас примірником.
Це відео розбиває його досить просто: https://www.youtube.com/watch?v=9ZZL3iyf4Vk
Ця стаття заглиблюється і пояснює дуже важливу семантичну різницю між цими двома, тобто finalзмінює змінні та constмодифікує значення, що по суті зводиться до лише можливості ініціалізації constзначень, які можна отримати в момент компіляції.
https://news.dartlang.org/2012/06/const-static-final-oh-my.html
Якщо ви їдете з , C++то constв Dartце constexprв C++і finalв Dartце constв C++.
Сказане стосується лише примітивних типів. Однак у Dartпозначених об'єктах finalє змінними з точки зору його членів.
constв C ++ майже завжди використовується для вказівки, що об'єкт не може бути змінений через певну посилання або покажчик. finalу Dart не перешкоджає мутації об'єкта через цю змінну.
Коли використовувати яке ключове слово?
Простий приклад для обох: Використовуйте final: Якщо ви не знаєте, яке значення буде в час компіляції. Наприклад, коли вам потрібно буде отримати дані з API, це відбувається під час запуску вашого коду.
Використовуйте const: Якщо ви впевнені, що значення не буде змінено під час запуску коду. Наприклад, коли ви оголошуєте речення, яке завжди залишається однаковим.
https://itnext.io/difference-between-const-and-final-in-dart-78c129d0c573
const: stackoverflow.com/questions/51576209 / ... і простому explonation доfinalпостійний (не може перепризначення або правонаступник після створення з остаточним ключовим словом) , і ви повинні ініціалізувати її один раз.