Dart 中的 "const" 和 "final" 关键字有什么区别?
What is the difference between the "const" and "final" keywords in Dart?
Dart 中的 const
和 final
关键字有什么区别?
There is a post on dart's website and it explains it pretty well.
决赛:
"final" means single-assignment: a final variable or field must have an initializer. Once assigned a value, a final variable's value cannot be changed. final modifies variables.
常量:
"const" has a meaning that's a bit more complex and subtle in Dart. const modifies values. You can use it when creating collections, like const [1, 2, 3], and when constructing objects (instead of new) like const Point(2, 3). Here, const means that the object's entire deep state can be determined entirely at compile time and that the object will be frozen and completely immutable.
Const objects have a couple of interesting properties and restrictions:
They must be created from data that can be calculated at compile time. A const object does not have access to anything you would need to calculate at runtime. 1 + 2 is a valid const expression, but new DateTime.now() is not.
They are deeply, transitively immutable. If you have a final field containing a collection, that collection can still be mutable. If you have a const collection, everything in it must also be const, recursively.
They are canonicalized. This is sort of like string interning: for any given const value, a single const object will be created and re-used no matter how many times the const expression(s) are evaluated.
那么,这是什么意思?
常量:
如果您拥有的值是在运行时计算的(例如 new DateTime.now()
),您可以 而不是 为它使用常量。但是,如果该值在编译时已知 (const a = 1;
),那么您应该使用 const
而不是 final
。 const
和 final
之间还有 2 个较大的差异。首先,如果您在 class 中使用 const
,则必须将其声明为 static const
而不仅仅是 const
。其次,如果您有一个 const
集合,其中的所有内容都在 const
中。如果您有一个 final
集合,其中的所有内容都是 而不是 final
.
决赛:
如果您在编译时不知道该值,则应使用 final
而不是 const
,而在运行时它将是 calculated/grabbed。如果你想要一个无法更改的 HTTP 响应,如果你想从数据库中获取一些东西,或者如果你想从本地文件中读取,请使用 final
。任何在编译时未知的东西都应该 final
而不是 const
。
综上所述,const
和 final
都不能重新分配,但是 final
对象中的字段,只要它们不是 const
或 final
本身,可以重新分配(与 const
不同)。
扩展@Meyi 的答案
- final变量只能设置一次,当
访问。(例如,从下面的代码部分,如果您使用
biggestNumberOndice
的值,那么该值将被初始化并分配内存)。
const 本质上是内部最终的,但主要区别在于
它的编译时间常量在编译期间初始化
即使您不使用它的值,它也会被初始化并占用
space在内存中。
来自 classes 的变量可以是最终的但不是常量,如果你想要一个
常量在 class 级别使其成为静态常量。
代码:
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;
}
如果您来自 C++
,那么 Dart
中的 const
是 C++
中的 constexpr
和 [=12= 中的 final
] 是 const
在 C++
.
以上仅适用于基本类型。
但是,在 Dart
中,标记为 final
的对象在其成员方面是可变的。
合并@Meyi 和@faisal-naseer 的答案并与小程序进行比较。
常数:
const 关键字用于使变量存储编译时间常数值。编译时间常数值是一个在编译时将保持不变的值:-)
例如5
是一个编译时间常量。而 DateTime.now()
不是编译时常量。因为此方法将 return 在运行时 行被执行的时间 。所以我们不能将 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 级别常量变量 应该像下面这样初始化。
Class A {
static const a = 5;
}
实例级常量变量不可能。
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
的另一个主要用途是使对象不可变。要使 class 对象不可变,我们需要 将 const 关键字与构造函数 结合使用,并使 所有字段都成为 final ,如下所述。
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;
// Can't use var along with final keyword. Uncommenting below line cause compilation issue.
// 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级最终变量必须在同一行初始化
Class A {
static final a = 5;
static final b = DateTime.now();
}
实例级final变量必须在同一行或构造函数初始化中初始化。该值将在创建对象时放入内存。
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()];
常数
值必须在 编译时已知,const birthday = "2008/12/25"
之后无法更改已初始化。
决赛
值必须在 运行-时间, final birthday = getBirthDateFromDB()
可以知道'初始化后不能更改
final
和 const
都防止变量被重新分配(类似于 final
在 Java 中的工作方式或 const
在 [= 中的工作方式42=]脚本).
区别与内存的分配方式有关。在运行时为 final
变量分配内存,在编译时为 const
变量分配内存。 final
修饰符应该是更常用的,因为许多程序变量不需要任何内存,因为程序逻辑不会调用它们进行初始化。使用 const
变量,您基本上是在告诉计算机,"Hey, I need memory for this variable up front because I know I'm going to need it."
以这种方式思考它们可以更容易地理解它们在语法用法上的差异。主要是 final
变量可能是实例变量,但 const
必须是 class 上的 static
变量。这是因为实例变量是在运行时创建的,而 const
变量——根据定义——不是。因此,class 上的 const
变量必须是 static
,这意味着该变量的单个副本存在于 class 上,而不管 class 被实例化。
这个视频相当简单地分解了它:
https://www.youtube.com/watch?v=9ZZL3iyf4Vk
这篇文章更深入地解释了两者之间一个非常重要的语义差异,即 final
修改变量而 const
修改值,这本质上归结为只能初始化 const
可在编译时导出的值。
https://news.dartlang.org/2012/06/const-static-final-oh-my.html
您不能使用 final
初始化 const
。例如:
final myConst = 1;
const myFinal = 2;
final a = myConst; // possible
final b = myFinal; // possible
const c = myConst; // this is not possible
const d = myFinal; // possible
dart 中的 final
和 const
混淆到我们认为它们相同的程度。
让我们看看它们的区别:
P.S. I included image instead of text as I couldn't tabulate the info
in Whosebug .md format easily.
什么时候使用哪个关键字?
两者的一个简单示例:
使用 final:如果你不知道它在编译时的值是什么。例如,当您可能需要从 API 获取数据时,这会在您的代码 运行 时发生。
使用常量:如果您确定在 运行 您的代码时不会更改值。例如,当您声明一个始终保持不变的句子时。
https://itnext.io/difference-between-const-and-final-in-dart-78c129d0c573
我的理解
const
表示它的初始值必须是固定的,不能是动态值;
final
表示它的初始值必须是固定的,但可以是动态值,等于var
固定值。
代码演示
const
void main() {
const sum = 1 + 2;
// ✅ const can not change its value
print("sum = ${sum}");
// ⚠️ Const variables must be initialized with a constant value.
const time = new DateTime.now();
// ❌ Error: New expression is not a constant expression.
print("time = ${time}");
}
final
// new DateTime.now();
// dynamic timestamp
void main() {
final sum = 1 + 2;
// ✅ final can not change its value
print("sum = ${sum}");
final time = new DateTime.now();
// ✅ final === var with fixed value
print("time = ${time}");
}
截图
参考资料
https://dart.dev/guides/language/language-tour#final-and-const
const
是编译时常量。
final
是一个 运行 时间常数。
需要 TLDR 的 TLDR 吗? :)
任何在编译时未知的东西都应该 final
超过 const
。
如果您从不打算更改变量,请使用 final
或 const
,代替 var 或与类型一起使用。 final 变量只能设置一次; const 变量是编译时常量。 (Const 变量是隐式最终的。)最终顶级或 class 变量在第一次使用时被初始化。
下面是创建和设置 final
变量的示例:
final name = 'Bob'; // Without a type annotation
final String nickname = 'Bobby';
您不能更改 final
变量的值:
name = 'Alice'; // Error: a final variable can only be set once.
对要成为编译时常量的变量使用const
。如果const
变量是class级别,就把它标记为static
const。在声明变量的位置,将值设置为编译时常量,例如数字或字符串文字、const 变量或对常量进行算术运算的结果:
const bar = 1000000; // Unit of pressure (dynes/cm2)
const double atm = 1.01325 * bar; // Standard atmosphere
const
关键字不仅仅用于声明常量变量。您还可以使用它来创建常量值,以及声明创建常量值的构造函数。任何变量都可以有一个常量值。
var foo = const [];
final bar = const [];
const baz = []; // Equivalent to `const []`
您可以从 const
声明的初始化表达式中省略 const
,就像上面的 baz
一样。有关详细信息,请参阅 DON’T use const redundantly。
您可以更改非 final、非常量变量的值,即使它曾经有一个 const
值:
foo = [1, 2, 3]; // Was const []
您不能更改 const
变量的值:
baz = [42]; // Error: Constant variables can't be assigned a value.
您可以定义使用 type checks and casts (is
and as
), collection if, and spread operators(...和...?
)的常量:
const Object i = 3; // Where i is a const Object with an int value...
const list = [i as int]; // Use a typecast.
const map = {if (i is int) i: "int"}; // Use is and collection if.
const set = {if (list is List<int>) ...list}; // ...and a spread.
带有final
关键字的变量将在运行时初始化,并且只能被赋值一次。
带有 const
关键字的变量在编译时初始化,并在运行时已赋值。
使用final
:如果你不知道它在编译时的值是多少。例如,当您可能需要从 API 获取数据时,这会在您的代码 运行 时发生。
使用 const
:如果您确定在 运行 您的代码时不会更改值。例如,当您声明一个始终保持不变的句子时。
所有这些答案我都可以用简洁的方式描述。
const list = [1, 2, 3];
- variable/identifier 和值都是常量。喜欢 -
const list = const [1, 2, 3]
- 这就是不允许重新分配它们的原因。
- 适合全局变量。
- 可以将其用作 class 变量,但必须设置为静态。喜欢 -
static const list = [1, 2, 3]
.
对比:
final list = [1, 2, 3];
- Variable/Identifier 是常量,但值不是。喜欢 -
const list = [1, 2, 3]
- 这就是为什么我们可以表现得像 -
list.add(4)
Dart 中的 const
和 final
关键字有什么区别?
There is a post on dart's website and it explains it pretty well.
决赛:
"final" means single-assignment: a final variable or field must have an initializer. Once assigned a value, a final variable's value cannot be changed. final modifies variables.
常量:
"const" has a meaning that's a bit more complex and subtle in Dart. const modifies values. You can use it when creating collections, like const [1, 2, 3], and when constructing objects (instead of new) like const Point(2, 3). Here, const means that the object's entire deep state can be determined entirely at compile time and that the object will be frozen and completely immutable.
Const objects have a couple of interesting properties and restrictions:
They must be created from data that can be calculated at compile time. A const object does not have access to anything you would need to calculate at runtime. 1 + 2 is a valid const expression, but new DateTime.now() is not.
They are deeply, transitively immutable. If you have a final field containing a collection, that collection can still be mutable. If you have a const collection, everything in it must also be const, recursively.
They are canonicalized. This is sort of like string interning: for any given const value, a single const object will be created and re-used no matter how many times the const expression(s) are evaluated.
那么,这是什么意思?
常量:
如果您拥有的值是在运行时计算的(例如 new DateTime.now()
),您可以 而不是 为它使用常量。但是,如果该值在编译时已知 (const a = 1;
),那么您应该使用 const
而不是 final
。 const
和 final
之间还有 2 个较大的差异。首先,如果您在 class 中使用 const
,则必须将其声明为 static const
而不仅仅是 const
。其次,如果您有一个 const
集合,其中的所有内容都在 const
中。如果您有一个 final
集合,其中的所有内容都是 而不是 final
.
决赛:
如果您在编译时不知道该值,则应使用 final
而不是 const
,而在运行时它将是 calculated/grabbed。如果你想要一个无法更改的 HTTP 响应,如果你想从数据库中获取一些东西,或者如果你想从本地文件中读取,请使用 final
。任何在编译时未知的东西都应该 final
而不是 const
。
综上所述,const
和 final
都不能重新分配,但是 final
对象中的字段,只要它们不是 const
或 final
本身,可以重新分配(与 const
不同)。
扩展@Meyi 的答案
- final变量只能设置一次,当
访问。(例如,从下面的代码部分,如果您使用
biggestNumberOndice
的值,那么该值将被初始化并分配内存)。 const 本质上是内部最终的,但主要区别在于 它的编译时间常量在编译期间初始化 即使您不使用它的值,它也会被初始化并占用 space在内存中。
来自 classes 的变量可以是最终的但不是常量,如果你想要一个 常量在 class 级别使其成为静态常量。
代码:
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;
}
如果您来自 C++
,那么 Dart
中的 const
是 C++
中的 constexpr
和 [=12= 中的 final
] 是 const
在 C++
.
以上仅适用于基本类型。
但是,在 Dart
中,标记为 final
的对象在其成员方面是可变的。
合并@Meyi 和@faisal-naseer 的答案并与小程序进行比较。
常数:
const 关键字用于使变量存储编译时间常数值。编译时间常数值是一个在编译时将保持不变的值:-)
例如5
是一个编译时间常量。而 DateTime.now()
不是编译时常量。因为此方法将 return 在运行时 行被执行的时间 。所以我们不能将 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 级别常量变量 应该像下面这样初始化。
Class A {
static const a = 5;
}
实例级常量变量不可能。
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
的另一个主要用途是使对象不可变。要使 class 对象不可变,我们需要 将 const 关键字与构造函数 结合使用,并使 所有字段都成为 final ,如下所述。
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;
// Can't use var along with final keyword. Uncommenting below line cause compilation issue.
// 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级最终变量必须在同一行初始化
Class A {
static final a = 5;
static final b = DateTime.now();
}
实例级final变量必须在同一行或构造函数初始化中初始化。该值将在创建对象时放入内存。
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()];
常数
值必须在 编译时已知,const birthday = "2008/12/25"
之后无法更改已初始化。
决赛
值必须在 运行-时间, final birthday = getBirthDateFromDB()
可以知道'初始化后不能更改
final
和 const
都防止变量被重新分配(类似于 final
在 Java 中的工作方式或 const
在 [= 中的工作方式42=]脚本).
区别与内存的分配方式有关。在运行时为 final
变量分配内存,在编译时为 const
变量分配内存。 final
修饰符应该是更常用的,因为许多程序变量不需要任何内存,因为程序逻辑不会调用它们进行初始化。使用 const
变量,您基本上是在告诉计算机,"Hey, I need memory for this variable up front because I know I'm going to need it."
以这种方式思考它们可以更容易地理解它们在语法用法上的差异。主要是 final
变量可能是实例变量,但 const
必须是 class 上的 static
变量。这是因为实例变量是在运行时创建的,而 const
变量——根据定义——不是。因此,class 上的 const
变量必须是 static
,这意味着该变量的单个副本存在于 class 上,而不管 class 被实例化。
这个视频相当简单地分解了它: https://www.youtube.com/watch?v=9ZZL3iyf4Vk
这篇文章更深入地解释了两者之间一个非常重要的语义差异,即 final
修改变量而 const
修改值,这本质上归结为只能初始化 const
可在编译时导出的值。
https://news.dartlang.org/2012/06/const-static-final-oh-my.html
您不能使用 final
初始化 const
。例如:
final myConst = 1;
const myFinal = 2;
final a = myConst; // possible
final b = myFinal; // possible
const c = myConst; // this is not possible
const d = myFinal; // possible
final
和 const
混淆到我们认为它们相同的程度。
让我们看看它们的区别:
P.S. I included image instead of text as I couldn't tabulate the info in Whosebug .md format easily.
什么时候使用哪个关键字?
两者的一个简单示例: 使用 final:如果你不知道它在编译时的值是什么。例如,当您可能需要从 API 获取数据时,这会在您的代码 运行 时发生。
使用常量:如果您确定在 运行 您的代码时不会更改值。例如,当您声明一个始终保持不变的句子时。
https://itnext.io/difference-between-const-and-final-in-dart-78c129d0c573
我的理解
const
表示它的初始值必须是固定的,不能是动态值;
final
表示它的初始值必须是固定的,但可以是动态值,等于var
固定值。
代码演示
const
void main() {
const sum = 1 + 2;
// ✅ const can not change its value
print("sum = ${sum}");
// ⚠️ Const variables must be initialized with a constant value.
const time = new DateTime.now();
// ❌ Error: New expression is not a constant expression.
print("time = ${time}");
}
final
// new DateTime.now();
// dynamic timestamp
void main() {
final sum = 1 + 2;
// ✅ final can not change its value
print("sum = ${sum}");
final time = new DateTime.now();
// ✅ final === var with fixed value
print("time = ${time}");
}
截图
参考资料
https://dart.dev/guides/language/language-tour#final-and-const
const
是编译时常量。
final
是一个 运行 时间常数。
需要 TLDR 的 TLDR 吗? :)
任何在编译时未知的东西都应该 final
超过 const
。
如果您从不打算更改变量,请使用 final
或 const
,代替 var 或与类型一起使用。 final 变量只能设置一次; const 变量是编译时常量。 (Const 变量是隐式最终的。)最终顶级或 class 变量在第一次使用时被初始化。
下面是创建和设置 final
变量的示例:
final name = 'Bob'; // Without a type annotation
final String nickname = 'Bobby';
您不能更改 final
变量的值:
name = 'Alice'; // Error: a final variable can only be set once.
对要成为编译时常量的变量使用const
。如果const
变量是class级别,就把它标记为static
const。在声明变量的位置,将值设置为编译时常量,例如数字或字符串文字、const 变量或对常量进行算术运算的结果:
const bar = 1000000; // Unit of pressure (dynes/cm2)
const double atm = 1.01325 * bar; // Standard atmosphere
const
关键字不仅仅用于声明常量变量。您还可以使用它来创建常量值,以及声明创建常量值的构造函数。任何变量都可以有一个常量值。
var foo = const [];
final bar = const [];
const baz = []; // Equivalent to `const []`
您可以从 const
声明的初始化表达式中省略 const
,就像上面的 baz
一样。有关详细信息,请参阅 DON’T use const redundantly。
您可以更改非 final、非常量变量的值,即使它曾经有一个 const
值:
foo = [1, 2, 3]; // Was const []
您不能更改 const
变量的值:
baz = [42]; // Error: Constant variables can't be assigned a value.
您可以定义使用 type checks and casts (is
and as
), collection if, and spread operators(...和...?
)的常量:
const Object i = 3; // Where i is a const Object with an int value...
const list = [i as int]; // Use a typecast.
const map = {if (i is int) i: "int"}; // Use is and collection if.
const set = {if (list is List<int>) ...list}; // ...and a spread.
带有final
关键字的变量将在运行时初始化,并且只能被赋值一次。
带有 const
关键字的变量在编译时初始化,并在运行时已赋值。
使用final
:如果你不知道它在编译时的值是多少。例如,当您可能需要从 API 获取数据时,这会在您的代码 运行 时发生。
使用 const
:如果您确定在 运行 您的代码时不会更改值。例如,当您声明一个始终保持不变的句子时。
所有这些答案我都可以用简洁的方式描述。
const list = [1, 2, 3];
- variable/identifier 和值都是常量。喜欢 -
const list = const [1, 2, 3]
- 这就是不允许重新分配它们的原因。
- 适合全局变量。
- 可以将其用作 class 变量,但必须设置为静态。喜欢 -
static const list = [1, 2, 3]
.
对比:
final list = [1, 2, 3];
- Variable/Identifier 是常量,但值不是。喜欢 -
const list = [1, 2, 3]
- 这就是为什么我们可以表现得像 -
list.add(4)