简介

null可能是大家在编写程序中最为头疼的一个东西,稍不留意的情况下就有可能使用到了这个空字符。所以dart在2.12引入了nll safety,默认情况下强制所有的类型都不为null,只有在你认为它可以为null的时候才可以设置为null。

虽然有了null safety,但是这里还有一些我们需要考虑的null的最佳实践。

不需要初始化对象为null

在dart2.12之后,所有的对象都强制为非空的,除非你显示指定其为可空的对象。

如果一个对象可以为空,那么我们可以这样指定:

String? name;

如果定义一个对象可以为空,那么对dart来说会隐式对其初始化为null。

所以下面的显示初始化为null是完全没有必要的:

String? name=null;

同样的,如果参数是一个可以为空的对象,那么dart也会将其初始化为null,我们也没有必要显示去设置其值:

void echoName(String? name){
print(name);
}

null的三元操作符

所谓三元就是有三个变量,我们常见的三元操作符就是?:,通常来说是这样用的:

name==null?true:false;

上面的逻辑实际上是把一个null转换成了一个bool类型。

为了实现这个功能,dart提供了一个更加简洁的操作符??, 可以这样使用:

name??false;

上面的代码表示如果name是空,则返回false。

注意,这里只是返回值改变了,但是name值本身并没有变化,也不会将name从一个可为空的类型,变成不为空的类型。所以如果我们在if语句里面对字符进行判断,则还是需要显示进行null的比较:

int measureMessage(String? message) {
if (message != null && message.isNotEmpty) {
// dart知道message不为空
return message.length;
} return 0;
}

如果这样编写,则会出现异常:

int measureMessage(String? message) {
if (message?.isNotEmpty ?? false) {
//dart并不知道message不为空
return message!.length;
} return 0;
}

如果在使用中需要判断类型是否为空,则不要使用late

late是做什么用的呢?late表示该类型目前不会初始化,但是会在未来的某个时间对其进行初始化。

所以,如果你用late表示某个类型,那么在后续使用的时候是不需要进行手动判断该类型是否为空的。

如果你仍然要手动判断,那么就没必要设置该类型为late。

本地变量的类型提升

dart有一个非常好的特性,就是当我们判断一个变量不为空之后,该变量就会被提升为非空变量。

当提升为非空变量之后,就可以自由访问该非空变量内部的属性和方法了。

但是可惜的是,dart中的类型提升只是针对与local变量或者参数而言的,对于类变量或者是top level的变量并不适用,所以我们需要将这些变量拷贝到本地变量,从而使用类型提升的特性。

我们看下面的例子:

class UploadException {
final Response? response; UploadException([this.response]); @override
String toString() {
var response = this.response;
if (response != null) {
return 'Could not complete upload to ${response.url} '
'(error code ${response.errorCode}): ${response.reason}.';
} return 'Could not upload (no response).';
}
}

其中UploadException中的response是一个顶级变量,虽然我们对其进行测试是否为空,但是在使用的过程中还是不能直接访问其内部的属性,因为response可能为空。

为了使用dart的类型提升的特性,我们可以将顶级的变量赋值给一个本地变量,从而在null测试之后,自动将其提升为非空的类型,从而直接访问其内部的属性。

总结

以上就是dart中null用法的最佳实践。

本文已收录于 http://www.flydean.com/29-dart-null-effective/

最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!

欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!

dart系列之:和null说再见,null使用最佳实践的更多相关文章

  1. dart系列之:安全看我,dart中的安全特性null safety

    目录 简介 Non-nullable类型 Nullable List Of Strings 和 List Of Nullable Strings !操作符 late关键字 总结 简介 在Dart 2. ...

  2. Mysql高手系列 - 第13篇:细说NULL导致的神坑,让人防不胜防

    这是Mysql系列第13篇. 环境:mysql5.7.25,cmd命令中进行演示. 当数据的值为NULL的时候,可能出现各种意想不到的效果,让人防不胜防,我们来看看NULL导致的各种神坑,如何避免? ...

  3. dart系列之:dart语言中的变量

    目录 简介 dart中的变量 定义变量 变量的默认值 Late变量 常量 总结 简介 flutter是google在2015年dart开发者峰会上推出的一种开源的移动UI构建框架,使用flutter可 ...

  4. dart系列之:dart语言中的内置类型

    目录 简介 Null 数字 字符串 布尔值 列表 set和map 简介 和所有的编程语言一样,dart有他内置的语言类型,这些内置类型都继承自Object,当然这些内置类型是dart语言的基础,只有掌 ...

  5. IOS开发遇到(null)与<null>轻松处理

    在ios开发中不可避免的我们会遇到服务器返回的值有空值,但是如果是nil也就算了还可能得到(null)以及<null>的返回值,该如何处理呢?(当然有的字典转模型中已处理,可以通过遍历等) ...

  6. com.opensymphony.xwork2.ognl.OgnlValueStack] - target is null for setProperty(null, "emailTypeNo", [Ljava.lang.String;@6f205e]

    情况1,查询结果未转换为与前台交互的实体类DTO 实体类:EmailTypeDto package com.manage.email.dto; public class EmailTypeDto { ...

  7. ognl.OgnlException: target is null for setProperty(null, "emailTypeNo", [Ljava.lang.String;@1513fd0)

    [com.opensymphony.xwork2.ognl.OgnlValueStack] - Error setting expression 'emaiTypeDto.emailTypeNo' w ...

  8. SQL语句中=null和is null

    平时经常会遇到这两种写法:IS NOT NULL与!=NULL.也经常会遇到数据库有符合条件!=NULL的数据,但是返回为空集合.实际上,是由于对二者使用区别理解不透彻. 默认情况下,推荐使用 IS ...

  9. mysql探究之null与not null

    相信很多用了mysql很久的人,对这两个字段属性的概念还不是很清楚,一般会有以下疑问: 1.我字段类型是not null,为什么我可以插入空值 2.为毛not null的效率比null高 3.判断字段 ...

随机推荐

  1. Windows 任务计划部署 .Net 控制台程序

    Windows 搜索:任务计划程序 创建任务 添加任务名称 设置触发器:这里设置每10分钟执行一次 保存之后显示 此任务会从每天的 0:10:00 执行第一次后一直循环下去. 在操作选项卡下,选择启动 ...

  2. CF1557B Moamen and k-subarrays 题解

    Content 给定一个大小为 \(n\) 的数组.你可以将其分为 \(k\) 个子数组,并按照每个子数组的字典序重新排列这些子数组,再顺次拼接,得到一个新的数组.问是否存在一种划分子数组的方案,使得 ...

  3. LuoguP7398 [COCI2020-2021#5] Šifra 题解

    Content 给定一个长度 \(n\) 的只包含小写字母和 \(0\sim9\) 的字符串(字符串中的字母可视为分隔符).求字符串中包含多少个不同的数字. 数据范围:\(1\leqslant n\l ...

  4. libevent实现多线程

    libevent并不是线程安全的,但这不代表libevent不支持多线程模式.前几天在微博上看到ruanyf发了条微博说到apache和nginx的并发模型,看到评论很多人都说不对于是自己又查了下,总 ...

  5. WinFrm中多线程操作窗体属性

    首先声明一个委托. delegate void SetTextCallback(string text); 然后再写一个事件. private void SetInfo(string text) { ...

  6. react 创建项目 sass router redux

    ​ 创建项目第一步 基本搭建 在创建之前,需要有一个git 仓库,我们要把项目搭建到git 中 目录介绍 cd 到某个盘 mkdir workspace 创建workspace文件夹 cd works ...

  7. 前端实现list排序

    需求 针对list中某个字段,实现list的升序和降序 效果图 代码 我是用在angular1.X中项目的,根据list中的sort字段进行排序. # sort.html <style> ...

  8. flink使用命令开始、停止任务

    命令操作 进行flink的安装目录 动态上传jar包启动job ./bin/flink run -c com.test.CountMain -P 3 Test-1. 0-SNAPSHOT.jar -- ...

  9. Log4j未平,Logback 又起!再爆漏洞?

    前段时间 Log4j接连爆漏洞的事儿相比把大家都折腾的不轻,很多开发都被连夜叫起来修复漏洞.这几天终于平复一些了. 可是,昨晚,忽然看到技术群和朋友圈,有人开始聊Logback 又爆漏洞了. 这是什么 ...

  10. 2021 年终总结:内推40人、全网15万粉、Code Runner 3000万下载、发扬WLB、进军视频领域

    时光飞逝,岁月如梭,蓦然回首,已是年底. 感觉写 2020 年终总结还是在不久之前.转眼间,2021 已经接近尾声了.是时候来写写 2021 年的年终总结了. 内推 40 人 2019 年,内推了 2 ...