https://www.bilibili.com/vide...git
https://github.com/ducafecat/...github
String title = 'ducafecat';
type?
操做符String? title = null;
value!
操做符String? title = 'ducafecat'; String newTitle = title!;
value?
操做符String? title = 'ducafecat'; bool isEmpty = title?.isEmpty();
value??
操做符String? title = 'ducafecat'; String newTitle = title ?? 'cat';
late
會在運行時檢查。因此請您僅在肯定它被使用前必定會被初始化的狀況下使用late String? title; title = 'ducafecat';
類型 | 集合是否可空 | 數據項是否可空 |
---|---|---|
List<String> | no | no |
List<String>? | yes | no |
List<String?> | no | yes |
List<String?>? | yes | yes |
類型 | 集合是否可空 | 數據項是否可空 |
---|---|---|
Map<String, int> | no | no* |
Map<String, int>? | yes | no* |
Map<String, int?> | no | yes |
Map<String, int?>? | yes | yes |
*
可能返回空
// 有可能返回 null int value = <String, int>{'one': 1}['one']; // ERROR // 須要加上 type? int? value = <String, int>{'one': 1}['one']; // OK // 或者 value! int value = <String, int>{'one': 1}['one']!; // OK
environment: sdk: ">=2.12.0 <3.0.0"
咱們強烈建議您按順序遷移代碼,先遷移依賴關係中的處於最末端的依賴。例如,若是 C 依賴了 B,B 依賴了 A,那麼應該按照 A -> B -> C 的順序進行遷移。編程
# Dart 版本是否爲 2.12 或更高 > dart --version # 依賴包的遷移狀態 > dart pub outdated --mode=null-safety
# 該命令會更改您的 pubspec.yaml 文件 > dart pub upgrade --null-safety # 升級包 > dart pub upgrade
> dart migrate
> dart analyze
> dart --no-sound-null-safety run > flutter run --no-sound-null-safety
{ // 使用 IntelliSense 瞭解相關屬性。 // 懸停以查看現有屬性的描述。 // 欲瞭解更多信息,請訪問: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { "name": "getx_quick_start", "request": "launch", "type": "dart", "program": "lib/main.dart", "args": ["--no-sound-null-safety"] } ] }
https://dart.cn/null-safety/u...json
makeCoffee(String coffee, [String? dairy]) { if (dairy != null) { print('$coffee with $dairy'); } else { print('Black $coffee'); } }
int topLevel = 0; class SomeClass { static int staticField = 0; }
class SomeClass { int atDeclaration = 0; int initializingFormal; int initializationList; SomeClass(this.initializingFormal) : initializationList = 0; }
int tracingFibonacci(int n) { int result; if (n < 2) { result = n; } else { result = tracingFibonacci(n - 2) + tracingFibonacci(n - 1); } print(result); return result; }
object
的類型從它聲明的 Object
提高到了 List
。在空安全引入之前,下面的程序沒法運行。// With (or without) null safety: bool isEmptyList(Object object) { if (object is List) { return object.isEmpty; // <-- OK! } else { return false; } } -> // Without null safety: bool isEmptyList(Object object) { if (object is! List) return false; return object.isEmpty; }
int tracingFibonacci(int n) { final int result; if (n < 2) { result = n; } else { result = tracingFibonacci(n - 2) + tracingFibonacci(n - 1); } print(result); return result; }
String checkList(List list) { if (list?.isEmpty) { return 'Got nothing'; } return 'Got something'; }
late
修飾符是「在運行時而非編譯時對變量進行約束」。這就讓 late
這個詞語約等於 什麼時候 執行對變量的強制約束。// Using null safety: class Coffee { String? _temperature; void heat() { _temperature = 'hot'; } void chill() { _temperature = 'iced'; } String serve() => _temperature! + ' coffee'; } -> // Using null safety: class Coffee { late String _temperature; void heat() { _temperature = 'hot'; } void chill() { _temperature = 'iced'; } String serve() => _temperature + ' coffee'; }
late
與 final
結合使用,與普通的 final
字段不一樣,您不須要在聲明或構造時就將其初始化。您能夠稍後在運行中的某個地方加載它。可是您只能對其進行 一次 賦值,而且它在運行時會進行校驗。// Using null safety: class Coffee { late final String _temperature; void heat() { _temperature = 'hot'; } void chill() { _temperature = 'iced'; } String serve() => _temperature + ' coffee'; }
a
和 c
是可選的,能夠省略。參數 b
和 d
是必需的,調用時必須傳遞。在這裏請注意,是否必需和是否可空無關。// Using null safety: function({int? a, required int? b, int? c, required int? d}) {}
abstract class Cup { Beverage get contents; set contents(Beverage); } -> abstract class Cup { abstract Beverage contents; }
// Initalized without values ListQueue _context; Float32List _buffer; dynamic _readObject; Vec2D(Map<String, dynamic> object) { _buffer = Float32List.fromList([0.0, 0.0]); _readObject = object['container']; _context = ListQueue<dynamic>(); } -> // Initalized with values final ListQueue _context = ListQueue<dynamic>(); final Float32List _buffer = Float32List.fromList([0.0, 0.0]); final dynamic _readObject; Vec2D(Map<String, dynamic> object) : _readObject = object['container'];
null
的工廠方法factory StreamReader(dynamic data) { StreamReader reader; if (data is ByteData) { reader = BlockReader(data); } else if (data is Map) { reader = JSONBlockReader(data); } return reader; } -> factory StreamReader(dynamic data) { if (data is ByteData) { // Move the readIndex forward for the binary reader. return BlockReader(data); } else if (data is Map) { return JSONBlockReader(data); } else { throw ArgumentError('Unexpected type for data'); } }
© 貓哥api
https://ducafecat.tech/2021/0...安全
https://github.com/ducafecat/...微信
https://github.com/ducafecat/...編程語言