Dart4Flutter - 不可變性

黃馬發表於2018-07-03

Dart4Flutter - 01 – 變數、型別和函式

Dart4Flutter – 02 –控制流 和異常

Dart4Flutter – 03 – 類和泛型

Dart4Flutter – 04 – 非同步和庫

Dart4Flutter - 拾遺01 - flutter-dart環境搭建

Dart4Flutter - 不可變性

Flutter入門 - 狀態管理

Flutter 入門例項1

Flutter 入門 - Container 屬性詳解

Flutter 入門-本地訪問-MethodChannel

Flutter 例項 - 載入更多的ListView

Flutter 例項 - 從本地到Flutter通訊 - Event Channels

Dart4Flutter - 不可變性

關於不變形一直是熱定話題,尤其是在前段。像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那麼規範,但是他依然對開發者有用。

參考

相關文章