Dart語言已經提供了不少語法糖來改善判斷空值的寫法,可是仍是有兩種狀況不容易判斷:javascript
function
是否爲空此時須要這樣每每須要這樣寫代碼:java
Function(String) filter; // 必定要寫一個if,其實很不優雅 if(filter != null){ filter('some string'); }
?.call()
調用Function(String) filter; // 一行判斷function是否爲空,並執行function filter?.call('some string');
例若有Map以下:git
Map map = { 'id': 3, 'tag': 'user', 'info': { 'name': 'Jerry', //'age': 5, } };
若是取值就很容易報錯:github
map['info']; // 取出map map['info']['name']; // 取出'Jerry' map['info2']['remark']; // 取不存在的key,再取值就回報錯 // 我在項目中的代碼,查詢Accu的天氣詳情,這樣會很是不穩定 source['Wind']['Speed']['Metric']['Value']
由於有時調用的Api並不徹底可靠,咱們固然不但願雲端的json結構變化就直接致使咱們整個程序報錯。若是堆疊不少個if判斷,會讓程序難以閱讀。json
Tips:javascript
中可使用map?.['info']
進行取值。
思路很簡單,重載[]
操做符便可
完整代碼:GitHub倉庫地址數組
class SafeMap { SafeMap(this.value); final dynamic value; SafeMap operator [](dynamic key) { if (value is Map) return SafeMap(value[key]); if (value is List) { List _list = value; int max = _list.length - 1; if (key is int && key < max) return SafeMap(value[key]); } return SafeMap(null); } dynamic get v => value; String get string => value is String ? value as String : null; num get number => value is num ? value as num : null; Map get map => value is Map ? value as Map : null; List get list => value is List ? value as List : null; bool get boolean => value is bool ? value as bool : false; bool isEmpty() { if (this.v == null) return true; if (this.string == '') return true; if (this.number == 0) return true; if (this.map?.keys?.length == 0) return true; if (this.list?.length == 0) return true; if (this.boolean == false) return true; return false; } @override String toString() => '<SafeMap:$value>'; }
使用:安全
void main() { test('get value from safemap', () { // source map Map map = { 'id': 3, 'tag': 'student', 'info': { 'name': 'Jerry', }, 'class': [ { "name": 'class 1', 'tag': '', }, {}, ], }; SafeMap safeMap = SafeMap(map); // 取值,錯誤的類型會返回SafeMap(null) assert(safeMap['id'].value == 3); assert(safeMap['id'].string == null); // 錯誤的下標也會返回SafeMap(null) assert(safeMap['tag'].value == 'student'); assert(safeMap['tag12345'].value == null); // 連續取值,能夠一直安全取值,只會返回SafeMap(null). assert(safeMap['info']['name'].value == 'Jerry'); assert(safeMap['a']['b']['b']['b']['b']['b'].value == null); // 取出數組,也能夠經過數組下標繼續取值 assert(safeMap['class'].list.length == 2); assert(safeMap['class'][0]['name'].value == 'class 1'); // {},[],0,'',null 都會被判斷爲空 assert(safeMap['class'][0]['tag'].isEmpty()); assert(safeMap['class'][1].isEmpty()); // 越界也會返回SafeMap(null),判斷isEmpty爲true assert(safeMap['class'][2].isEmpty()); }); }