• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

dart 如何优雅的避空

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

前言

对于每一个程序员来说,空指针异常应该是基本都会遇到过的异常,而且这个异常出现的概率还比较大。

但是,空指针异常又是最容易解决的异常,因为只要加个非空判断就可以避免了。

本篇通过对比一般非空判断和 dart 特有的语法糖告诉你如何使用 dart 进行优雅的避空。

目录

1. dart 在线编辑器

一般一些简单的 dart 测试我们可以直接用在线编辑器来做测试和验证。

下面给大家介绍的两个都是官网的。

**dart 在线运行器主页版:**????
https://www.dartlang.org/guides/get-started

**dart 在线运行器全屏版:**????
https://dartpad.dartlang.org/null

其中全屏版就是在主页版里面点击全屏按钮就打开了。

所以可以认为是一样的。

但是笔者使用起来的不同如下,大家可以根据自己的感受选择。

主页版:
优点:运行输出结果较全屏版快。
缺点:输出结果区域较小,超出需要滑动查看。

全屏版:
优点:输出结果区域大。可以直观看到结果。
缺点:运行输出结果较主页版慢。

2. dart ?.

dart 语法糖 ?.

它的意思是左边如果为空返回 null,否则返回右边的值。

A?.B
如果 A 等于 null,那么 A?.B 为 null
如果 A 不等于 null,那么 A?.B 等价于 A.B

Sample:

void main() {
  Animal animal = new Animal('cat');
  Animal empty = null;
  
  //animal 非空,返回 animal.name 的值 cat
  print(animal?.name);
  //empty 为空,返回 null
  print(empty?.name);
  
  //animal 非空,可以直接访问 animal.name 的值 cat
  print(animal.name);
  //empty 为空,抛出异常
  print(empty.name);
}

class Animal {
  final String name;
  Animal(this.name);
}

大家拷贝代码然后替换在线编辑器的内容,运行后会看到如下输出:

cat
null
cat
Uncaught exception:
Cannot read property 'get$name' of null

可以看到假设左边不为空,不管是使用**?.还是直接用我们熟悉的.访问变量都是没问题的。
但是如果左边为空,使用
?.会返回null**。但是直接使用**.**会直接抛出异常。

3. dart ??

dart 语法糖 ??

它的意思是左边如果为空返回右边的值,否则不处理。

A??B
如果 A 等于 null,那么 A??B 为 B
如果 A 不等于 null,那么 A??B 为 A

以上面为例子,假设我们上面要求当 empty 为空时,默认值输出 unknown。

那么可以修改如下:

//empty 为空,返回 null
print(empty?.name);

改为

//empty 为空,本来要返回 null,由于有 ??,返回 unknown
print(empty?.name??'unknown');

这样就不会返回 null 而是返回 unknown。

同样的大家可以试下返回 cat 的语句如果加上这个会怎样,可以预见是不会改变的。

4. dart ?. ?? 优雅所在

这边举例说明下使用 ?. ?? 语法糖和不使用的对比。

void main() {
  C c = new C('Case 1');
  B b = new B(c);
  A a = new A(b);
  
//   C c = new C(null);
//   B b = new B(c);
//   A a = new A(b);
  
//   C c = new C('Case 2');
//   B b = null;
//   A a = new A(b);
  
  //直接使用.来最终获取 c 的变量 value
  if (a != null && a.bMember != null && a.bMember.cMember != null) {
    print(a.bMember.cMember.value);
  } else {
    print(null);
  }
  
  //直接使用.来最终获取 c 的变量 value,为空时返回 unknown
  if (a != null && a.bMember != null && a.bMember.cMember != null) {
    String value = a.bMember.cMember.value;
    if (value == null) {
      value = 'unknown';
    }
    print(value);
  } else {
    print('unknown');
  }
  
  //dart 使用?.来最终获取 c 的变量 value
  print(a?.bMember?.cMember?.value);
  //dart 使用?.来最终获取 c 的变量 value,为空时使用 ?? 返回 unknown
  print(a?.bMember?.cMember?.value??'unknown');
}

class A {
  final B bMember;
  A(this.bMember);
}

class B {
  final C cMember;
  B(this.cMember);
}

class C {
  final String value;
  C(this.value);
}

这里面有三个 case,另外两个 case 暂时注释掉。

这三个 case 的结果分别为:

Case 1
Case 1
Case 1
Case 1
null
unknown
null
unknown
null
unknown
null
unknown

可以看到 dart 的语法糖很优雅,一行全搞定。

5. print 方法遇到 null

下面这个例子:

void main() {
    String a = null;
    print('exception='+a);
}

你觉得结果是 exception=null 吗?

结果是

Uncaught exception:
Invalid argument: null

原因是因为 print 里面连接的必须是字符串。

因为这里 a 确实是字符串,所以编辑器没有报错。

假设这里 a 为一个对象 A 的变量,会报如下提示:

The argument type 'A' can't be assigned to the parameter type 'String'.

那我们怎么处理?

有两种方法。

方法一:

void main() {
    String a = null;
    print('exception='+'$a');
}

方法二:

void main() {
    String a = null??'null';
    print('exception='+a);
}

注意下面的写法是不行的,原因是 ?? 优先级没有 + 高。需要加小括号。

void main() {
    String a = null;
    print('exception='+a??'null');
}

6. 牛刀小试

知识学以致用才能够巩固。

因此这边出了小题目给大家测试是否完全掌握本篇内容。

答案组成了支付宝口令红包哦~

微信公众号回复「牛刀小试」获取题目。

或者直接点击菜单栏目录->牛刀小试获取。

温馨提示:
如果你输入 3 次还是提示错误(错误过多口令红包会暂时不可用哦),有两种情况。

第一种就是答案错了。

第二种就是领取完了。

答案会在红包领取完之后或一天之后将题目替换为题目+答案。

因为是异步的,所以不一定实时更新哦~

更多阅读:
Flutter 即学即用系列博客——01 环境搭建
Flutter 即学即用系列博客——02 一个纯 Flutter Demo 说明
Flutter 即学即用系列博客——03 在旧有项目引入 Flutter
Flutter 即学即用系列博客——04 Flutter UI 初窥
Flutter 即学即用系列博客——05 StatelessWidget vs StatefulWidget


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
dart类详细讲解发布时间:2022-07-13
下一篇:
关于Dart2那些事儿-变量发布时间:2022-07-13
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap