一、基本概念
在剛開始學習Dart
的時候,對於const, final, static
這幾個關鍵字很容易產生困惑,究竟該在那種場景下使用它們,這篇文章就從以下幾個方面總結一下這三個關鍵字:
- 基本概念
- 一些要注意的點
- 在何種場景下,使用哪種關鍵字
1.1 const
const
有以下幾種應用場景:
(1) const
用在=
左邊
當const
用在=
左邊時,其作用是 宣告變數,它要求 必須在宣告變數時賦值,一旦賦值就不允許修改,而宣告值一定要是編譯時常數。
const
在宣告變數時可以省略變數的型別,var, int
等。
這裡的關鍵點在於區分 什麼是編譯時常數,有以下幾種場景:
- 數值、字串、其它的
const
變數
void main() {
const a = 1;
const b = 'hello';
const c = a;
}
複製程式碼
- 表示式。表示式的所有值都是編譯時可知的。
void main() {
const a = 1;
const b = a > 1 ? 2 : 1;
}
複製程式碼
- 集合或物件。集合必須用
const
修飾,物件的建構函式必須用const
修飾。
void main() {
const a = const [1,2,3];
const b = ConstObject(2);
b.log();
}
class ConstObject {
final value;
const ConstObject(this.value);
log() {
print(value);
}
}
複製程式碼
(2) const
用在等號右邊
當const
用在=
右邊,其作用是 修飾值,它意味著物件的整個深度狀態可以在編譯時完全確定,並且物件將被凍結並且完全不可變。
一般用於修飾集合,它要求兩點:
- 集合的元素必須是遞迴的編譯時常數,也就是上面提到的三種情況。
void main() {
var c = 2;
//ERROR, 集合元素必須是編譯時常數。
var a = const [c,2,3];
}
複製程式碼
- 不允許對集合做任何改變。
void main() {
const a = const [1,2,3];
//ERROR, 不允許修改。
a[1] = 2;
}
複製程式碼
(3) const
修飾類的建構函式
當const
修飾類的建構函式時,它要求該類的所有成員都必須是final
的。
class ConstObject {
final value;
//ERROR, 必須是 final 變數。
int value2;
const ConstObject(this.value);
log() {
print(value);
}
}
複製程式碼
1.2 final
final
的要求就是 其宣告的變數在賦值之後就不再改變,它並不要求=
的右邊是編譯時常數。
final
有兩種場景:
- 檔案中的變數宣告:必須在宣告時賦值。
- 類的成員變數宣告:可以在宣告時賦值,也可以通過建構函式賦值語法糖
ClassV({this.a})
,或者初始化列表的方式賦值。
1.3 static
static
的概念相對來說就比較容易理解了,它的作用是 宣告類的成員變數,使得多個相同型別的類物件共享同一個成員變數的例項。
二、一些要點
2.1 const
- 宣告類成員變數時,
const
變數必須同時被宣告為static
的。 const
變數,變數命名方式應使用全大寫加下劃線。const
變數只能在定義的時候初始化。
2.2 final
final
變數可以在建構函式引數列表或者初始化列表中初始化。
2.3 static
- 在檔案中,變數不能宣告為
static
。
三、在何種場景下,使用哪種關鍵字
下面的表格總結了如何選取關鍵字,判斷的順序依次往下。
3.1 類
判斷順序 | 關鍵詞 |
---|---|
值是編譯時常數 | static const |
值不是編譯時常數,但所有類都共享同一個例項 | static final :在宣告的時候就能確定值,並且不再改變;static :不能確定。 |
各個類物件持有不同的例項,但只能被賦值一次 | final |
其它 | 普通定義 |
3.2 檔案
判斷條件 | 關鍵詞 |
---|---|
常量 | const |
非常量,但在宣告時就能確定值,並且不希望被改變 | final |
其它 | 普通定義 |