[TOC]
下面的最佳實踐描述了如何在Dart中最好地使用變量。
## 不要顯式地將變量初始化為空。
在Dart中,未顯式初始化的變量或字段自動被初始化為null。這是由語言可靠地指定的。在Dart中沒有“未初始化內存”的概念。添加= null是多余的和不需要的。
~~~
int _nextId;
class LazyId {
int _id;
int get id {
if (_nextId == null) _nextId = 0;
if (_id == null) _id = _nextId++;
return _id;
}
}
~~~
以下是不推薦的寫法:
~~~
int _nextId = null;
class LazyId {
int _id = null;
int get id {
if (_nextId == null) _nextId = 0;
if (_id == null) _id = _nextId++;
return _id;
}
}
~~~
## 避免儲存你能計算的東西。
在設計類時,您通常希望將多個視圖公開到相同的底層狀態。通常你會看到在構造函數中計算所有視圖的代碼,然后存儲它們:
應該避免的寫法:
~~~
class Circle {
num radius;
num area;
num circumference;
Circle(num radius)
: radius = radius,
area = pi * radius * radius,
circumference = pi * 2.0 * radius;
}
~~~
這個代碼有兩個問題。首先,它可能會浪費內存。嚴格地說,這個區域和周長是緩存。它們是存儲的計算,我們可以從已有的其他數據中重新計算。他們用增加的內存換取減少的CPU使用。我們知道我們有一個性能問題值得權衡嗎?
更糟糕的是,代碼是錯誤的。緩存的問題是無效——您如何知道何時緩存過期需要重新計算?在這里,我們永遠不會這樣做,即使半徑是可變的。您可以指定一個不同的值,而面積和周長將保留它們以前的、現在不正確的值。
為了正確處理緩存失效,我們需要這樣做:
應該避免的寫法:
~~~
class Circle {
num _radius;
num get radius => _radius;
set radius(num value) {
_radius = value;
_recalculate();
}
num _area;
num get area => _area;
num _circumference;
num get circumference => _circumference;
Circle(this._radius) {
_recalculate();
}
void _recalculate() {
_area = pi * _radius * _radius;
_circumference = pi * 2.0 * _radius;
}
}
~~~
這需要編寫、維護、調試和讀取大量代碼。相反,您的第一個實現應該是:
~~~
class Circle {
num radius;
Circle(this.radius);
num get area => pi * radius * radius;
num get circumference => pi * 2.0 * radius;
}
~~~
這段代碼更短,占用的內存更少,也更不容易出錯。它存儲表示圓所需的最小數據量。沒有字段可以不同步,因為只有一個真實的源。
在某些情況下,您可能需要緩存慢速計算的結果,但只有在知道存在性能問題之后,才能這樣做,請仔細執行,并留下解釋優化的注釋。