Ответы:
На сайте дартс есть пост, который довольно хорошо объясняет.
Финал:
«final» означает одиночное присваивание: конечная переменная или поле должны иметь инициализатор. После присвоения значения значение окончательной переменной не может быть изменено. Конечные модифицирует переменные .
Const:
«const» имеет значение, которое немного сложнее и тоньше в Dart. const изменяет значения . Вы можете использовать его при создании коллекций, таких как const [1, 2, 3], и при создании объектов (вместо новых), таких как const Point (2, 3). Здесь const означает, что все глубокое состояние объекта может быть полностью определено во время компиляции и что объект будет заморожен и полностью неизменен.
У объектов Const есть пара интересных свойств и ограничений:
Они должны быть созданы из данных, которые могут быть рассчитаны во время компиляции. Константный объект не имеет доступа ни к чему, что вам нужно будет вычислить во время выполнения. 1 + 2 является допустимым выражением const, но новый DateTime.now () - нет.
Они глубоко, транзитивно неизменны. Если у вас есть последнее поле, содержащее коллекцию, эта коллекция все еще может быть изменяемой. Если у вас есть коллекция const, все в ней также должно быть const, рекурсивно.
Они канонизированы . Это похоже на интернирование строк: для любого заданного значения const будет создан и повторно использован один объект const независимо от того, сколько раз вычислено выражение (выражения) const.
Const:
Если у вас есть значение, вычисленное во время выполнения ( new DateTime.now()например), вы не можете использовать const для него. Однако, если значение известно во время компиляции ( const a = 1;), вам следует использовать constover final. Есть 2 других больших различия между constи final. Во-первых, если вы используете const, вы должны объявить это, static constа не просто const. Во-вторых, если у вас есть constколлекция, все внутри нее находится внутри const. Если у вас есть finalколлекция, все внутри этого нет 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;
Константная переменная уровня класса должна быть инициализирована, как показано ниже.
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 инициализированная как varсодержащая список constобъектов . Таким образом, мы можем назначить другой список переменной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 также используется для того, чтобы переменная содержала постоянное значение . После инициализации мы не можем изменить значение.
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
biggestNumberOndiceonly, значение будет инициализировано и будет выделена память).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/… и простое объяснение кfinalявляется постоянным (не может переназначаться или назначаться после создания с ключевым словом final), и вам придется инициализировать его один раз.