Dart字符串判空

NullPointerExp是无数java程序员都想消除的问题,OC里,nil对象调方法返回的是nil(这种做法,仁者见仁,智者见智);kotlin和swift通过optional机制,通过编程过程中强化Nullable概念,来避免NPE。

dart中,null是一个普通的Null类型对象,首先这点就让人有点困扰了。所以dart不会出现np,但是null调用其他方法会出现noSuchMethod的问题。这个体验就不是很好了。然后引入了null-aware操作符,这个和optional机制有点像,不过做的不彻底,且if的设定有点奇怪。

Dart是一门假装很现代,但实际上有点过时的语言。

先不吐槽了,回归标题吧。

Null-aware operators

dart语法中支持Null-aware操作符,?? ??=?.

用法

Empty string judge

在判断一个字符串是否为空时,我们一般是这样写的:

// 判断不为空
if (str != null && !str.isEmpty()) {
    // str is not empty, do something
}
// 判断为空
if (str == null || str.isEmpty()) {
    // str is empty, do something
}

在了解到null-aware操作符后,我们是不是可以这么写:

if (!str?.isEmpty()) {
    // str is not empty, do something
}

if (str?.isEmpty()) {
    // str is empty, do something
}

其实不然,上面的代码是有问题的。具体问题有要从dart的if说起,dart的if判断来看。

Dart中规定,if中当且仅当参数为bool类型true时,为真,其他全部都为假。

知道这条规定,就可以发现上面的问题了:当str为空时str?.isEmpty()输出的结果为null,而这在if语句中,实际上相当于false,那么也就是说当str为空时,str?.isEmpty()进入了if的false分支。而相反的,在null前面加上!否定后,又变为了true,即当str为空时,!str?.isEmpty()反而是进入了true分支。

这明显是不符合我们期望的逻辑的,所以这种写法是绝对不可取的。

但是dart的string类型还有另一个方法isNotEmpty,此时这样写:

if (str?.isNotEmpty()) {
    // str is not empty, do something
}

if (!str.isNotEmpty()) {
    // str is empty, do something
}

str非空时,逻辑肯定没有问题,当str为空时,str?.isNotEmpty会返回false,而同样的!str?.isNotEmpty,就会返回true,这样恰好就符合我们期望的逻辑了。

Conclusion

不过IDE是不建议if中传null这样非bool类型的对象的,所以你这样写的话会给一个提示:

这里的逻辑确实容易让不了解的人很困惑,所以不建议用以上null-aware操作符来做字符串的空判断。

如果想做一个工具方法来简化字符串的判断,也不用自己重复造轮子,推荐使用官方的quiver.strings这个库,里面涵盖了字符串的一些常用工具方法。

Wrote by Kevin(a2V2aW56aGFuMDQxN0BvdXRsb29rLmNvbQ==)

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Python小屋

Python编程一定要注意的那些“坑”(九):0与False

问题描述:在编程时,经常需要单独编写一个函数用来判断某个事件是否成立,如果成立就返回正常结果,否则返回False。在主调函数中根据被调函数的返回值决定下一步的操...

13430
来自专栏彭湖湾的编程世界

【javascript】详解变量,值,类型和宿主对象

JS数据类型 JS类型分类 ? 讲到类型, 首先要说的当然是JS的类型分类, 对于这一点,《javascript高级语言程序设计》和《你不知道的javasvri...

22360
来自专栏编程之旅

数据结构——优先队列(C++和Java实现)

十几天没有更新自己的博客了,因为目前在算法和数据结构的学习中,碰到了一些问题,例如之前就在优先队列,堆这个数据结构面前,感觉到有点吃不透概念,而使用的那本书上写...

15930
来自专栏HTML5学堂

为什么不要在 JavaScript 中使用位操作符?

如果你的第一门编程语言不是 JavaScript,而是 C++ 或 Java,那么一开始你大概会看不惯 JavaScript 的数字类型。在 JavaScrip...

366100
来自专栏架构之路

索引优先队列-IndexedPrirotyQueue的原理及实现(源码)

1.索引优先队列的意义 索引优先队列是一个比较抽象的概念,它是一个优先队列,又带有索引,这个索引是用来干什么的呢? 在正常的队列中,我们只能访问队列头元素,整个...

46580
来自专栏nummy

python string模块学习

如果字符串模板中的变量没有提供值,会抛出异常,这时,可以使用safe_substitute().

8320
来自专栏linux驱动个人学习

Android系统的智能指针(轻量级指针、强指针和弱指针)的实现原理分析【转】

Android系统的运行时库层代码是用C++来编写的,用C++ 来写代码最容易出错的地方就是指针了,一旦使用不当,轻则造成内存泄漏,重则造成系统崩溃。不过系统为...

10820
来自专栏静默虚空的博客

[设计模式]原型模式

简介 原型模式 (Prototype)用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。 原型模式是一种对象创建型模式 (可参考 设计模式 创建型...

20180
来自专栏Android机动车

数据结构学习笔记——栈

我们允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom),不含任何数据元素的栈称为空栈。

10030
来自专栏刘望舒

带你领略Kotlin的精髓

从谨慎地在项目中引入kotlin到全部转为kotlin开发我们用了大概半年的时间。这中间经历了从在一个小功能中尝试使用到完全使用kotlin完成了大版本开发的过...

11920

扫码关注云+社区

领取腾讯云代金券