Dart 3 正式发布,100% 健全的空安全
Dart 3 现已发布,这是迄今为止最大的 Dart 版本,包含了三个主要改进:完成了 100% 健全的空安全;添加了记录、模式和类修饰符的新语言特性;以及对未来进行了预览,即,通过 Wasm 编译扩大了对网络原生代码的平台支持。
100% 健全的空安全
Dart 3 已经成为了一种 100% 健全的空安全语言。100% 的空安全性为 Dart 带来了健全的类型系统。你可以相信,如果一个类型说一个值不是null
,那么它永远不可能是null
。这避免了某些类别的编码错误,例如空指针异常。它还允许编译器和运行时以没有空安全性无法实现的方式优化代码。虽然这种设计会使得迁移变得有点困难,但开发团队认为,他们为 Dart 做出了正确的选择。
预计绝大多数已迁移到 null safety 的包和应用程序都可以与 Dart 3 一起使用。在少数情况下,Dart 3 中的少量相关清理可能会影响某些代码。一些旧的核心库 API 已被删除(#34233、#49529)并且一些工具已被调整(#50707)。如果用户在迁移到使用 Dart 3 SDK 时遇到任何问题,可查阅 Dart 3 迁移指南。
主要语言特性 —— 记录、模式和类修饰符
Dart 3 不仅仅是基于现有基础作出改变,它还涉及添加重要的新特性和功能。
使用记录构建结构化数据
借助记录,你可以使用简洁明了的语法构建结构化数据。
( String , int ) userInfo( Map < String , dynamic > json) { return (json[ 'name' ] as String , json[ 'height' ] as int ); }
记录是值类型,没有标识。这使得编译器能够在某些情况下完全擦除记录对象。记录还带有自动定义的==
运算符和hashCode
函数。更多详细信息可查看文档。
用模式和模式匹配来处理结构化数据
记录简化了构建结构化数据的方式。这不会取代使用类来构建更正式的类型层次结构。它只是提供了另一种选择。在任何一种情况下,你都可能希望将该结构化数据分解为单独的元素以使用它们。这就是模式匹配发挥作用的地方。
考虑模式的基本形式。以下记录模式将记录解构为两个新变量name
和height
。然后可以像任何其他变量一样使用这些变量,例如调用print
时:
var (String name, int height) = userInfo({'name': 'Michael', 'height': 180}); print('User $name is $height cm tall.');
类似的模式也存在于 lists 和 maps 中。对于所有这些,你可以使用下划线模式跳过单个元素:
var (String name, _) = userInfo(…);
Dart 3 中还扩展了switch
语句的功能和表现力。现在已经消除了在每个案例末尾添加break
的需要,还支持逻辑运算符来组合案例。示例:
switch (charCode) { case slash when nextCharCode == slash: skipComment(); case slash || star || plus || minus: operator(charCode); case >= digit0 && <= digit9: number(); default: invalid(); }
模式的一个强大功能是能够检查“exhaustiveness”,此功能可确保 switch 可以处理所有可能的情况。
sealed class Animal { … } class Cow extends Animal { … } class Sheep extends Animal { … } class Pig extends Animal { … } String whatDoesItSay(Animal a) => switch (a) { Cow c => '$c says moo', Sheep s => '$s says baa' };
这将返回以下错误,提醒错过了最后一个可能的子类型 Pig 的处理:
line 6 • The type 'Animal' is not exhaustively matched by the switch cases since it doesn't match 'Pig()'.
if
语句也可以使用模式:
final json = {'name': 'Michael', 'height': 180}; // Find Michael's height. if (json case {'name': 'Michael', 'height': int h}) { print('Michael is $h cm tall.'); } else { print('Error: json contains no height info for Michael!'); }
更多详情可查看 patterns documentation 和 patterns codelab。
具有类修饰符的类的细粒度访问控制
Dart 3 的第三个语言特性是类修饰符。与期望每个 Dart 开发人员都使用的记录和模式不同,这更像是一个高级用户功能。它满足了 Dart 开发人员制作大型 API 表面或构建企业级应用程序的需求。
类修饰符使 API 作者能够仅支持一组特定的功能。默认值保持不变。开发团队希望 Dart 保持简单易用。因此,像以前一样,可以构造、扩展和实现常规类,如以下示例所示:
class Vehicle { String make; String model; void moveForward(int meters) { … } } // Construct. var myCar = Vehicle(make: 'Ford', model: 'T',); // Extend. class Car extends Vehicle { int passengers; } // Implement. class MockVehicle implements Vehicle { @override void moveForward … }
类修饰符支持在此基础上添加限制。考虑一些示例用例:
- 使用
interface class
,你可以定义一个契约供其他人实施。不能扩展接口类。 - 使用
base class
,你可以确保类的所有子类型都继承自它,而不是实现它的接口。这确保私有方法在所有实例上都可用。 - 使用
final class
,你可以关闭类型层次结构以防止你自己的库之外的任何子类。作为一个 sample 好处,这允许 API 所有者添加新成员,而不会冒破坏 API 使用者更改的风险。
更多详情可查看文档。
展望未来
- 查看 Dart 3 之后的次要版本是否需要对记录、模式和类修饰符进行更新。
- 研究一些更小、更增量的功能,这些功能完全不具破坏性,并且专注于提高开发者的生产力,而没有迁移成本。正在探索的两个示例是用于使用零成本“wrappers”以包装现有类型的内联类,和 primary constructors,它引入了一种更简洁的语法来定义具有几个字段和一个 primary constructor 的类。
- 关注宏(也称为元编程),以便更好地反序列化 JSON(和类似的),并启用数据类。
- 目前已经支持用 dart:fi 编译成 C 库的代码的互操作。正在努力将其扩展到支持 Android 上的 Java 和 Kotlin 互操作,以及iOS/MacOS上的Objective C和Swift互操作。
-
编译为 WebAssembly —— 使用 native code 定位 web
更多详情可查看官方公告。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Red Hat Enterprise Linux 9.2 已发布
Red Hat Enterprise Linux 9.1 已发布。 Red Hat Enterprise Linux 9.2 引入了对 Arm 架构的 64k 页面大小的支持,可以在更多硬件上部署操作系统并最大限度地提高大型数据集工作负载的性能。还扩展了系统角色的功能,可以自动执行更多的管理任务; 此外还增强了 Podman,这是 Red Hat 用于在 Linux 平台上开发、管理和运行容器的工具。Podman 的新 Red Hat Enterprise Linux 系统角色使管理员能够根据特定需求和环境自动配置,而无需采用命令行。 9.2 还更新了其他几个系统组件,实现了 SQL Server/Active Directory 身份验证的自动化、对 SQL Server 2022 的支持以及 Always-On 可用性组支持。 其他内容详见更新公告。
- 下一篇
Julia 1.9.0 发布,科学计算领域高性能语言
Julia 编程语言 1.9 版本已发布,这是一种通用的高性能语言,在科学计算和数值分析中较为流行。Julia 1.9 是 1.x 系列版本中的第九个次要版本,添加了一些新特性和功能,主要更改如下: 本机代码的缓存 本机代码缓存现已可用,从而显着改善了 TTFX (首次执行时间)延迟,包作者现在可以利用带有PrecompileTools 的precompile语句或工作负载来提前缓存重要的例程。 用户还可以创建自定义本地“启动”包,以加载依赖项并预编译适合其日常工作的工作负载。此功能带来一些额外的负载,例如预编译时间增加 10%-50%,但这是一次性成本。由于存储更多数据和使用不同的序列化格式,缓存文件也变得更大。 下图说明了从 Julia 1.7 开始加载时间 (TTL)、TTFX 和缓存文件大小的变化: 包扩展 Julia 1.9 引入了“包扩展”,从广义上讲,这是一种在加载一组包时自动加载模块的功能。该模块包含在ext父包目录中的一个文件中,加载“弱依赖”和扩展方法。 包扩展提供的功能类似于Requires.jl已经提供的功能,但具有关键优势,例如允许预编译条件代码,和添加弱依赖...
相关文章
文章评论
共有0条评论来说两句吧...