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()); }); }