关于Flutter空安全升级方案整理

前言

Flutter 从 2.0 版本开始支持空安全(Null Safety)。dart 版本为:

 environment:sdk: ">=2.12.0 < 3.0.0"

升级到空安全后,由于语法的变动,基本上整个工程,代码都爆红,这对项目来说简直是灾难性的打击,不升级的话只是缓兵之计,因为随着时间的推移,flutter将不再维护非空安全的版本,同时一些三方库也将无法使用,因此空安全升级变成了一个不得不做的事情,项目越复杂需要的时间也就越持久,考虑到对项目的稳定性,和开发周期。选择一个合适自己项目的迁移方案非常重要。下面自己会讲下自己对空安全迁移的理解和实施方案,目前成功迁移几个项目,还是比较有经验的。

语法变动

空安全升级后dart语法是存在很大的变化的,但是理念很简单即:万物皆可为空,和以往不同,现在任意创建一个对象都需要判断对象是否为空,这样在使用的时候,便明确知道这个对象是否可能为空,可以避免很多空指针的情况。
Dart 空安全的关键语法
1.不可空类型
在启用空安全的 Dart 中,默认情况下所有类型都是不可空的。这意味着一个变量声明后,不能为 null。例如:

int x = 42; // x 不能为 null

如果尝试将 null 赋值给不可空类型,编译器将会报错。

2.可空类型
如果一个变量可以是 null,则必须在类型后加上 ?。例如:

int? y = null; // y 可以是整数或 null

这种语法清晰地表明 y 是可空的,开发者在使用时必须考虑它可能为 null 的情况。

3.非空断言操作符 !
当你确定一个可空变量不为 null 时,可以使用 ! 操作符进行非空断言。例如:

int? a = 5;
int b = a!; // 断言 a 不为 null,安全地将其赋值给 b

使用 ! 操作符时要小心,因为如果断言错误(即变量实际上为 null),程序会抛出异常。因此对于不确定的变量尽量不要强制!

4.空合并操作符 ??
空合并操作符提供了一种为可空变量指定默认值的便捷方式。例如:

String? name;
String displayName = name ?? 'Guest'; // 如果 name 为 null,则使用 'Guest'

这种操作符在开发中是非常常用的,我们经常会通过??来给一些可为空的对象创建兜底值

5.late 变量
有时候我们明确知道这个对象一定是不会为null的但是再创建的时候拿不到值,便可以通过late 来延迟初始化这个对象

late String description;void initialize() {description = 'Dart is fun!';
}

使用 late 声明的变量在首次使用前必须被初始化,否则将导致运行时错误。

空安全迁移

Flutter 官方提供了空安全迁移方案:使用dart migrate工具可以借助该工具
在开始迁移之前,请确保做好以下准备工作:
升级 Dart SDK:确保你使用的 Dart SDK 版本是 2.12 或更高版本。可以通过 dart --version 检查当前的 Dart 版本。
更新依赖:确保项目中的所有依赖包都支持空安全。可以使用以下命令查看哪些包需要更新:

dart pub outdated --mode=null-safety

在这里插入图片描述

可以根据输出的日志将不支持空安全的版本升级或者替换
以上都完成后,便可以使用 dart migrate 来进行代码的替换了

dart migrate工具会为你构建迁移后的代码建议,并启动一个交互式的迁移网页界面。

View the migration suggestions by visiting:http://127.0.0.1:60278/Users/you/project/mypkg.console-simple?authToken=Xfz0jvpyeMI%3D

在这里插入图片描述
以上便可以通过dart migrate进行简单的迁移
手动迁移
真实的开发场景哪有这么理想,因此使用dart migrate对很多大型项目并不是很使用,并且使用dart migrate会大量的添加** !** 导致项目一堆异常,无法真正的运行起来。
另外也没有那么多时间,让项目进度停下来做空安全迁移。
因为我们做的方案是:创建一个支持空安全语法的module

//需要安卓和iOS模块
flutter create --template=plugin --org com.xxxx.xxx --platforms android --platforms ios --project-name aaa bbb
flutter create --template=plugin --org com.xxxx.xxxxx  --project-name aaaa bbbb

将创建好的工程以module的形式,依赖到主项目中,此方法不会打破项目的连续性,可以边迁移,边做需求开发。需要注意的是:
需要将主项目(非空安全)和子module(空安全)以相对路径的方式进行依赖因此需要修改pubspec.yaml 中的依赖方式

UT和覆盖率需要以下面的方式进行run

flutter test --no-sound-null-safety

在整体空安全都迁移完成后,再将项目移会去,这样边可以,一部分同时进行正常的需求开发,一部分同时进行空安全整改,最大化的提高工作效率。

当然在迁移过程中会涉及到import的问题,这里自己写了脚本,用于批量修改导包

#!/bin/shecho "修改工程导包"# 修改对应的一级文件夹
CHANGEFILE="xxxx"# 修改以package开头的导包
package_name="package:xxxxx\/$CHANGEFILE\/"
new_string=""
old_string="\.\.\/"
search_string="\.\.\/$CHANGEFILE"
old_import="$CHANGEFILE\/"
# 从主项目迁移到空安全路径修改导包路径名称
new_import="package:mobile_cn_null_safety\/$CHANGEFILE\/"find . -name "*.dart"|while read fname; doecho "The string is found on line(s): $fname"
#package 开头导包if grep -q "$package_name" "$fname"; then# 使用grep查找字符串所在行package_line_number=$(grep -n "${package_name}" "$fname" | cut -d: -f1)# 遍历行号for each1 in $package_line_numberdoif [ -n "$each1" ];thensed -i  '' "${each1}s/${package_name}/${new_import}/g" "$fname"fidonefi# 相对路径导包if grep -q "$search_string" "$fname"; then# 使用grep查找字符串所在行line_number=$(grep -n "${search_string}" "$fname" | cut -d: -f1)for each in $line_numberdoif [ -n "$each" ];thensed -i  '' "${each}s/${old_string}//g" "$fname"sed -i  '' "${each}s/${old_import}/${new_import}/g" "$fname"fidonefi
done

以上差不多便是全部内容。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/58637.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

干货 | 2024年数据要素白皮书(免费下载)

导读&#xff1a;白皮书在对比分析国际数据领域发展现状的基础上&#xff0c;围绕数据要素市场化配置改革这一主线&#xff0c;从数据高质量供给、数据创新应用、体制机制建设、产业探索方向四大方面展现了数据要素发展过程中&#xff0c;各类主体的新作为、新成效&#xff0c;…

RTT 内核基础学习

RT-Thread 内核介绍 内核是操作系统的核心&#xff0c;负责管理系统的线程、线程间通信、系统时钟、中断以及内存等。 内核位于硬件层之上&#xff0c;内核部分包括内核库、实时内核实现。 内核库是为了保证内核能够独立运行的一套小型的类似C库的函数实现子集。 这部分根据编…

六通道CAN集线器(协议型)

一、功能概述 SG_CanHub_600 是一款具有六路通道的工业级智能 CAN 数字隔离中继集线器。 SG_CanHub_600 能够实现信号再生、延长通信距离、提高总线负载能力、匹配不同速 率 CAN 网络&#xff0c;同时强大的 ID过滤功能可以极大降低 CAN 总线负荷&#xff0c;并具有故障指…

Web应用性能测试工具 - httpstat

在数字化时代&#xff0c;网站的性能直接影响用户体验和业务成功。你是否曾经在浏览网页时&#xff0c;遇到加载缓慢的困扰&#xff1f;在这个快速变化的互联网环境中&#xff0c;如何快速诊断和优化Web应用的性能呢&#xff1f;今天&#xff0c;我们将探讨一个强大的工具——h…

【Linux】从零开始使用多路转接IO --- 理解EPOLL的 LT水平触发模式 与 ET边缘触发模式

当你偶尔发现语言变得无力时&#xff0c; 不妨安静下来&#xff0c; 让沉默替你发声。 --- 里则林 --- 从零开始认识多路转接 1 EPOLL优缺点2 EPOLL工作模式 1 EPOLL优缺点 poll 的优点(和 select 的缺点对应) 接口使用方便&#xff1a;虽然拆分成了三个函数&#xff0c;…

kafka+zookeeper的搭建

kafka从2.8版本开始&#xff0c;就可以不用配置zookeeper了&#xff0c;但是也可以继续配置。我目前使用的kafka版本是kafka_2.12-3.0.0.tgz&#xff0c;其中前面的2.12表示是使用该版本的scala语言进行编写的&#xff0c;而后面的3.00才是kafka当前的版本。 通过百度网盘分享…

基础数据结构——队列(链表实现)

队列的性质 先进先出&#xff08;FIFO - First In First Out&#xff09;&#xff1a;最先加入队列的元素最先被移出后进后出&#xff08;后来的元素排在队尾&#xff09;只允许在队尾插入元素&#xff0c;在队首删除元素具有先来先服务的特点 链表实现队列 和之前创建链表相…

git原理与上传

言&#xff1a; git是一个软件&#xff0c;gitee/github是一个网站&#xff0c;这里有什么联系吗&#xff1f;我们身为一个程序员不可能不知道github&#xff0c;但是毕竟这是外国的网站&#xff0c;我们不翻墙的情况下&#xff0c;是无法访问的(或者就是太慢了&#xff0c;或…

亚信安全新一代WAF:抵御勒索攻击的坚固防线

近年来&#xff0c;勒索攻击已成为黑客的主要攻击手段。新型勒索攻击事件层出不穷&#xff0c;勒索攻击形势愈发严峻&#xff0c;已经对全球制造、金融、能源、医疗、政府组织等关键领域造成严重危害。如今&#xff0c;勒索攻击手段日趋成熟、攻击目标愈发明确&#xff0c;模式…

Selenium 高频面试题及答案

在求职面试中&#xff0c;Selenium的相关知识已经成为自动化测试工程师们无法避开的热门考点。想要脱颖而出&#xff0c;提前了解Selenium的高频面试题及其答案显得尤为重要。这篇文章将带你快速掌握Selenium的核心考点和解答&#xff0c;帮助你在面试中应对自如&#xff01; …

7.qsqlquerymodel 与 qtableview使用

目录 qtableview 委托QStyledItemDelegateQAbstractItemDelegateCheckBoxItemDelegate使用qtableview控制列宽&#xff0c;行高&#xff0c;隐藏拖拽行列 qtableview 委托 //设置单元格委托 void setItemDelegate(QAbstractItemDelegate *delegate); QAbstractItemDelegate *it…

微服务实战系列之玩转Docker(十八)

导览 前言Q&#xff1a;如何保障容器云环境下etcd集群的数据安全一、安全机制身份认证必学必看1. 启动参数2. 授权命令3. 开启认证 二、应用实践1. 访问容器2. 查看认证是否开启3. 查看是否已创建用户4. 创建用户5. 开启认证6. 验证是否开启7. 验证数据 结语系列回顾 前言 etc…

如何基于pdf2image实现pdf批量转换为图片

最近为了将pdf报告解析成为文本和图片&#xff0c;需要将大量多页的pdf文件拆分下单独的一页一页的图像&#xff0c;以便后续进行OCR和图像处理&#xff0c;因此就需要实现将pdf2image&#xff0c;本文主要结合开源的pdf2image和poppler&#xff0c;实现了pdf转换为png格式图片…

Python小游戏23——捕鱼达人

首先&#xff0c;你需要安装Pygame库。如果你还没有安装&#xff0c;可以使用以下命令进行安装&#xff1a; 【bash】 pip install pygame 运行效果展示 接下来是示例代码&#xff1a; 【python】 import pygame import random # 初始化Pygame pygame.init() # 屏幕尺寸 SCREEN…

如何调整pdf的页面尺寸

用福昕阅读器打开pdf&#xff0c;进入打印页面&#xff0c;选择“属性”&#xff0c;在弹出的页面选择“高级” 选择你想调成的纸张尺寸&#xff0c;然后打印&#xff0c;打印出来的pdf就是调整尺寸后的pdf

《重学Java设计模式》之 原型模式

原型模式主要解决的问题就是创建重复对象&#xff0c;而这部分对象内容本身比较复杂&#xff0c;生成过程可能从库或者RPC接口中获取数据的耗时较长&#xff0c;因此采用克隆的方式节省时间。 案例&#xff1a;上机考试抽题&#xff0c;要求打乱题目、答案数据 工厂结构 选择题…

八,附录 A:其他发现流程示例

八&#xff0c;附录 A&#xff1a;其他发现流程示例 八&#xff0c;附录 A&#xff1a;其他发现流程示例8.1 修改后的发现流程8.2 优化后的发现流程8.3 高级发现流程 八&#xff0c;附录 A&#xff1a;其他发现流程示例 以下部分提供了关于修改后的、优化后的和高级的发现流程…

实战:看懂并分析执行计划——Clustered Index Scan

这是 Clustered Index Scan 的执行计划详情,以下是对每一行的含义及其对查询性能的可能影响的解释。 Clustered Index Scan (Clustered) 解释 Physical Operation: Clustered Index Scan (Clustered) 物理操作,表明数据库引擎在整个聚集索引上进行扫描。Clustered Index Sc…

Jenkins声明式Pipeline流水线语法示例

系列文章目录 docker搭建Jenkins2.346.3版本及常用工具集成配置(ldap、maven、ansible、npm等) docker安装低版本的jenkins-2.346.3,在线安装对应版本插件失败的解决方法 文章目录 系列文章目录jenkins流水线基础1、pipeline1.1、什么是pipeline&#xff1f;1.2、为什么使用pi…

OceanBase中,如何解读 obdiag 收集的火焰图 【DBA早下班系列】

1. 前言 在之前的文章 遇到性能问题&#xff0c;如何给OceanBase“拍CT“&#xff08;火焰图与扁鹊图&#xff09;中&#xff0c;分享了obdiag 快速收集火焰图的方法&#xff0c;那么&#xff0c;紧接着的问题便是&#xff1a;收集到火焰图和扁鹊图之后&#xff0c;该如何解读…