Ответы:
На сайте дартс есть пост, который довольно хорошо объясняет.
Финал:
«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;
), вам следует использовать const
over 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
biggestNumberOndice
only, значение будет инициализировано и будет выделена память).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), и вам придется инициализировать его один раз.