Dart4Flutter - 拾遺01 - flutter-dart環境搭建
Flutter 例項 - 從本地到Flutter通訊 - Event Channels
關於不變形一直是熱定話題,尤其是在前段。像Immutable.js這樣的庫和單向資料流等其他概念都認為,當資料不可變時,更容易管理資料。
在物件導向和函式是程式設計中,一個不可變的物件是指,一旦物件建立之後狀態是不能修改的。想對應的是可變物件,建立之後,物件狀態是可以修改的。
好了,那Dart是怎樣做的呢?我們有幾個概念很適合內建的不變性和不可變物件,從const修飾符和const建構函式開始。 不要與ES6中的const混淆,後者只是一個不可變的繫結。
// 定義USER為常量,初始化。
const USER = { name: 'Joe'; }
// 這樣將丟擲異常.
USER = {};
// 但是這樣不會;以為是繫結的不可變,可以修改物件
USER.name = 'Jill';
複製程式碼
在Dart中,const是一個不可變繫結,也是不可變物件。
main() {
const user = const {'name': 'Joe'};
// 丟擲 Static error: "Constant variables cannot be assigned a value".
user = {};
// 丟擲 Runtime error: "Unsupported operation: Cannot modify unmodifiable Map".
user['name'] = 'Jill';
}
複製程式碼
所有型別,例如(Null, String, int, double, num, bool, Map, List, Symbol),都可以是不可變的,而且可以給自定型別新增const建構函式。
class User {
final String name;
const User(this.name);
}
main() {
const user = const User('Joe');
}
複製程式碼
讓我們回顧一下 - const例項既是不可變的繫結,又在語言層面強制執行,既是根本不可變的 - 也是在編譯時就確定的 - 也就是說,任何兩個例項都被認為是等價的,並且在執行時只能由單個例項表示。 例如,以下內容相當簡單,它只在執行時分配一個例項:
class User {
final String name;
final List<String> cars;
User(this.name, {this.cars});
}
main() {
// 雖然迴圈100次,但是隻有一個物件
for (var i = 0; i < 100; i++) {
const users = const {
'Matan': const User(
'Matan Lurey',
cars: const [
'Truck',
'Jeep',
'GoKart',
],
),
};
}
}
複製程式碼
更多關於const和final請參考Dart官方文件
通過package:meta靜態分析檢查
當然,const是有限制的 - 必須在編譯時建立類物件。所以不能完成如下,在執行時,從資料庫讀出資料,建立物件。我們現在介紹package:meta的immutable
註解。
import 'pacakge:meta/meta.dart';
// 因為當前類使用@immutable註解,所以變數必須是final的
@immutable
class User {
final String name;
User(this.name)
}
複製程式碼
你可以使用這個註解幫助開發者,強制類是不可變的。但是不像const那麼規範,但是他依然對開發者有用。