[译] Dart 3 发布了

news2024/12/24 8:55:17

[译] Dart 3 发布了

alt

原文 https://medium.com/dartlang/announcing-dart-3-53f065a10635

https://ducafecat.com/blog/dart-3

来自 Google I/O 2023 的问候。今天,我们在 Mountain View 现场宣布 Dart 3——迄今为止最大的 Dart 发布!Dart 3 包含三个主要进展。首先,我们完成了通往 100% 无空安全的旅程。其次,我们为记录、模式和类修饰符添加了重大的新语言特性。第三,我们预览了未来,通过 Wasm 编译,我们将扩大我们的平台支持,为 web 提供本地代码支持。现在,让我们进入细节。

100% 无空安全

在过去的四年里,我们将 Dart 发展成了一种快速、便携、现代化的语言。现在,通过 Dart 3,它是一种 100% 无空安全的语言!正如我们之前所讨论的,我们认为没有其他编程语言曾经为现有语言添加过无空安全。所以,这是一个相当漫长的旅程。

alt

在 Dart 中实现了 100% 的 null 安全之后,我们拥有了 sound 类型系统。您可以信任,如果一个类型说一个值不是 null,那么它永远不会是 null。这避免了某些类别的编程错误,如空指针异常。它还允许我们的编译器和运行时以不可能没有空安全的方式优化代码。这个设计选择涉及到一个折衷。虽然迁移变得有点困难,但我们认为我们为 Dart 做出了正确的选择。

迁移到 Dart 3

实现 sound null safety 的一个关键部分是 Dart 社区的不懈支持:pub.dev 的前 1000 个包中有 99% 支持 null safety!

鉴于此,我们预计已经迁移到 null safety 的绝大多数包和应用程序将与 Dart 3 兼容。只有在少数情况下,Dart 3 中的一些相关清理可能会影响一些代码。一些旧的核心库 API 已经被删除(#34233, #49529),一些工具已经进行了调整(#50707)。如果您在使用 Dart 3 SDK 迁移时遇到任何问题,请参阅 Dart 3 迁移指南。除此之外,我们希望您会喜欢新的理性化核心库和工具。

主要语言特性——记录、模式和类修饰符

Dart 3 不仅是改变现有语言的问题。它还添加了重要的新功能和能力!这些包括记录、模式和类修饰符。

使用记录构建结构化数据

传统上,Dart 函数只能返回单个值。因此需要返回多个值的函数必须将它们打包到其他数据类型中,例如映射或列表,或定义可以保存值的新类。使用未打印的数据结构会削弱类型安全性。必须定义新类以仅仅携带数据会在编码过程中增加摩擦。您已经非常清楚地告诉了我们:多返回值的语言请求是我们的 第四高评级问题。

使用记录,您可以使用漂亮而简洁的语法构建结构化数据。考虑这个函数。它读取 JSON 块的名称和年龄,并将它们都以记录形式返回:

(String, int) userInfo(Map<String, dynamic> json) {
  return (json['name'] as String, json['height'] as int);
}

这应该很熟悉所有的 Dart 开发人员。记录看起来像列表文字,例如 [‘Michael’, ‘Product Manager’],但使用括号而不是方括号。在 Dart 中,记录是一个通用特性。它们可以用于超过函数返回值的用途。您还可以将它们存储在变量中,将它们放入列表中,在映射中使用它们作为键,或创建包含其他记录的记录。您可以添加未命名字段,就像我们在先前的示例中所做的那样,也可以添加命名字段,如 (42, description: ‘Meaning of life’)

记录是值类型,没有身份。这使得编译器在某些情况下可以完全擦除记录对象。记录还带有自动定义的 == 运算符和 hashCode 函数。记录文档中有更多细节。

使用模式和模式匹配处理结构化数据

记录简化了构建结构化数据的方式。这并不取代使用类构建更正式的类型层次结构。它只是提供了另一种选择。在任何情况下,您可能需要将该结构化数据分解为其各个元素以处理它们。这就是模式匹配发挥作用的地方。

考虑模式的基本形式。以下记录模式将记录分解为两个新变量 nameheight。然后,这些变量可以像任何其他变量一样使用,例如在调用 print 中:

var (String name, int height) = userInfo({'name''Michael''height': 180});
print('User $name is $height cm tall.');

类似的模式存在于列表和映射中。对于所有这些,您可以使用下划线模式跳过单个元素:

var (String name, _) = userInfo(…);

当在 switch 语句中使用时,模式会发挥作用。Dart 从一开始就具有有限的 switch 支持。在 Dart 3 中,我们扩展了 switch 语句的功能和表达力。我们现在支持在这些情况下进行模式匹配。我们已经删除了在每个 case 结尾添加 break 的需要。我们还支持逻辑运算符来组合 case。以下示例显示了一个漂亮而简洁的 switch 语句,该语句解析字符代码:

switch (charCode) {
  case slash when nextCharCode == slash:
    skipComment();

  case slash || star || plus || minus:
    operator(charCode);

  case >= digit0 && <= digit9:
    number();

  default:
    invalid();
}

当需要每个 case 中有一个或多个语句时,switch 语句提供了很好的帮助。在某些情况下,您只需要计算一个值。对于这种用例,我们提供了一个非常简洁的 switch expression。这类似于 switch statement,但使用不同的语法,这些语法被调整为表达式。以下示例函数返回 switch 表达式的值,以计算今天的工作日描述:

String describeDate(DateTime dt) =>
  switch (dt.weekday) {
      1 => 'Feeling the Monday blues?',
      6 || 7 => 'Enjoy the weekend!',
      _ => 'Hang in there.'
  };

模式的一个强大功能是检查“穷尽性”,该功能确保 switch 处理所有可能的情况。在上一个示例中,我们处理了 weekday 的所有可能值,它是一个 int。通过为特定值 167 的匹配语句组合,然后使用默认情况 _ 处理剩余的情况,我们穷尽了所有可能的值。为了对用户定义的数据层次结构(例如,类层次结构)启用此检查,请在类层次结构的顶部使用新的 sealed 修饰符,如以下示例:

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 语句也可以使用模式。在下一个示例中,我们使用 if-case 匹配来匹配一个 map-pattern 来解构 JSON 映射。在其中,我们针对常量值(如 'name''Michael')和类型测试模式 int h 进行匹配以读取 JSON 值。如果模式匹配失败,Dart 将执行 else 语句。

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!');
}

这只涉及到您可以使用模式的所有内容。我们相信它们将在所有 Dart 代码中变得普遍。要了解更多,请查看 模式文档 和 模式 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,您可以关闭类型层次结构,防止在您自己的库之外创建任何子类。作为示例的好处是,这允许 API 拥有者添加新成员而不会冒着破坏 API 消费者的风险。

有关详细信息,请参见新的class modifiers documentation。

展望未来

Dart 3 不仅是一个新功能的重要进步,我们还为您提供了未来的预览。

Dart 语言

记录、模式和类修饰符是非常重要的新功能,因此它们的设计可能仍有改进之处。我们将继续监控您的反馈意见,如果需要,在 Dart 3 后的小版本中进行更新。

我们还在研究一些更小、更增量的功能,这些功能完全不会破坏任何代码,并且专注于提高开发者的生产力。我们正在探索的两个例子是内联类,用于使用零成本“包装器”封装现有类型,以及主构造函数; 这是一项功能,它引入了一个更简洁的语法,用于定义具有少量字段和主构造函数的类。

我们之前讨论过宏(也称为元编程)。我们特别关注此功能,以实现更好的 JSON 反序列化(及类似操作),以及实现数据类。鉴于元编程的规模和固有风险,我们采取了非常彻底的方法,因此没有具体时间表可分享,甚至无法最终确定设计决策。

原生互操作

移动设备和桌面应用程序通常依赖于由本地平台提供的许多 API,无论是通知、支付还是获取手机位置。传统上,在 Flutter 中通过构建插件来访问这些 API,这需要编写 Dart 代码和一堆特定于平台的代码来提供实现。

我们已经支持使用[dart:ffi](<https://dart.dev/guides/libraries/c-interop>)编译为 C 库的代码进行互操作。我们目前正在扩展此功能,以支持在 Android 上的Java 和 Kotlin 互操作,以及在 iOS/macOS 上的Objective C 和 Swift 互操作。要了解 Android 互操作的介绍,请查看 Google I/O 23 的新Android 互操作视频。

编译为 WebAssembly —— 使用本机代码定向 Web

WebAssembly(缩写为 Wasm)作为跨现代浏览器的平台中立二进制指令格式而不断成熟。Flutter 框架已经使用 Wasm 一段时间了。这是我们通过一个 Wasm 编译模块将用 C++ 编写的 SKIA 图形渲染引擎传递到浏览器中的方式。我们长期以来一直有兴趣将 Wasm 用于部署 Dart 代码,但我们一直受阻。像许多其他面向对象语言一样,Dart 使用垃圾回收。在过去的一年里,我们与 Wasm 生态系统中的几个团队合作,为 WebAssembly 标准添加了一个新的 WasmGC 功能。这在 Chromium 和 Firefox 浏览器中已经接近稳定。

我们将 Dart 编译为 Wasm 模块的工作对于 Web 应用程序有两个高层次的目标:

  • 加载时间:我们希望可以通过 Wasm 提供部署负载,使浏览器能够更快地加载,从而提高用户与 Web 应用程序交互所需的时间。
  • 性能:由 JavaScript 驱动的 Web 应用程序需要即时编译才能实现良好的性能。Wasm 模块更接近底层和机器代码,因此我们认为它们可以提供更高的性能,减少卡顿并提供更一致的帧速率。
  • 语义一致性:Dart 自豪地表示在我们支持的平台之间高度一致。然而,在 Web 上,这还存在一些例外情况。例如,Dart Web 当前在 数字的表示方式上有所不同。使用 Wasm 模块,我们将能够将 Web 视为类似其他本机目标的平台,其语义类似。

我们很高兴地宣布 Dart 到 Wasm 编译的第一个预览版!我们最初的重点是 Flutter Web 支持。现在还处于早期阶段,我们还有很多工作要完成,但我们邀请您进行实验,看看这是否和我们一样令人兴奋。

结束语

感谢您阅读到最后。我们希望这篇文章让您对 Dart 3 感到兴奋,它今天在独立的Dart SDK和Flutter 3.10 SDK中都可以使用。

我们通过声音的空值安全、核心库和工具清理完成了 Dart 语言的重大改造。有重大的新语言功能,使 Dart 更具表现力和清晰度,拥有记录和模式。对于大型 API 表面,类修饰符可以实现详细的控制。我们还包括了未来的预览,即我们即将支持 WebAssembly。

凭借所有这些功能,我们认为 Dart 3 展示了我们的长期愿景:建立最具生产力的编程语言,用于在任何平台上构建快速应用程序。我们希望您也这样认为!


© 猫哥 ducafecat.com

end

本文由 mdnice 多平台发布

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

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

相关文章

Springboot +Flowable,各种历史信息如何查询(一)

一.简介 正在执行的流程信息是保存在以 ACT_RU_ 为前缀的表中&#xff0c;执行完毕的流程信息则保存在以 ACT_HI_ 为前缀的表中&#xff0c;也就是流程历史信息表。 假设有一个流程&#xff0c;流程图如下&#xff1a; 当这个流程执行完毕后&#xff0c;以 ACT_RU_ 为前缀的…

小黑子—多媒体技术与运用基础知识三:数字图形图像处理技术

多媒体技术与运用3.0 多媒体系列第三章1. 颜色科学1.1 颜色的性质1.1.1 颜色的物理性质1.1.2颜色三特性1.1.3三原色与三补色 1.2 颜色空间1.2.1 与设备无关的颜色空间1.2.1 与设备相关的颜色空间 1.3 常见的多媒体系统颜色空间1.3.1 RGB颜色空间1.3.2 CMYK颜色模型1.3.3 HSB颜色…

什么是模型鲁棒性和泛化能力

目录 1、鲁棒性 2、泛化能力 1、鲁棒性 定义&#xff1a;在统计学领域和机器学习领域&#xff0c;对异常值也能保持稳定、可靠的性质&#xff0c;称为鲁棒性。比如说&#xff0c;计算机软件在输入错误、磁盘故障、网络过载或有意攻击情况下&#xff0c;能否不死机、不崩溃&a…

17 KVM虚拟机配置-XML配置文件示例

文章目录 17 KVM虚拟机配置-XML配置文件示例17.1 概述17.2 示例一17.3 示例二 17 KVM虚拟机配置-XML配置文件示例 17.1 概述 本节给出一个基本的AArch64虚拟机和一个x86_64虚拟机的XML配置文件示例&#xff0c;供参考。 17.2 示例一 一个包含基本元素的AArch64架构虚拟机的…

Psychophysiology:降维独立成分分析(rdICA)对ERP测量的影响

导读 独立成分分析(ICA)是一种有效且普遍使用的EEG信号处理工具。为了减少计算时间&#xff0c;许多分析管道在ICA之前降低了EEG维数。Artoni及其同事(2018)的研究中就详细地描述了这种降维ICA(rdICA)对独立成分的偶极性和可靠性的有害影响。虽然ICA对于那些直接分析独立成分感…

【网络安全】记一次网站站点渗透

前言 遇到一个站&#xff0c;后端是 Node.js 写的&#xff0c;对于这种类型的站点&#xff0c;一般比较难 getshell&#xff0c;但也实现了最终的目标&#xff0c;拿到后台权限 信息搜集 先进行常规的信息搜集&#xff0c;子域名扫描、端口扫描、目录扫描等 这个站后端脚本语…

如何实现文件共享,文件共享的设置方法-镭速

文件共享是指在计算机网络中&#xff0c;多个用户可以通过共享相同的文件或目录来实现数据交换和协作工作。这种方式可以使多个用户在不同地点的计算机上访问并编辑同一个文件&#xff0c;从而实现更加高效和便捷的合作。 实现文件共享是计算机网络中常见的需求&#xff0c;可以…

关于在 MySQL 排序中使用索引这件事!

文章目录 1. 排序的两种方式2. 索引排序2.1 案例一2.2 案例二2.3 案例三2.4 案例四2.5 案例五2.6 案例六2.7 案例七2.8 案例八 3. 其他情况3.1 多表联查3.2 order by null 4. 小结 前面跟小伙伴们分享的索引相关的内容&#xff0c;基本上都是在 where 子句中使用索引&#xff0…

java环境变量 的配置与详解

笔者这学期开始学习java课程&#xff0c;学习java开发首先需要配置java运行环境变量。虽然上课老师也讲了如何配置java环境变量&#xff0c;可是笔者的同学还是有好多都不会配置&#xff0c;所以笔者最近配置了特别多次java环境变量。如下笔者详细解释从JDK安装到环境变量的装配…

rsync本地或远程备份

这里写自定义目录标题 rsync作用rsync用法scp /cp/rsync区别ssh无密码登陆原理远程备份案例远程备份脚本脚本1&#xff1a;脚本2 本地备份常用参数 rsync作用 实现本地或远程 全量备份 增量备份 rsync用法 rsync -avz 本机文件夹 远程主机用户名IP:远程主机文件夹 scp /cp/…

发电厂能源管理远程监控解决方案

发电厂能源管理远程监控解决方案 项目背景 在我国经济快速发展的同时&#xff0c;对用电的要求也越来越高。为了节约能源和降低成本&#xff0c;国家正在积极推动发电厂的技术改造。发电厂作为发电企业的核心&#xff0c;其耗能状况关系到整个国家的经济发展。为进一步加强对电…

如何成为一名职业黑客?

我需要什么技能才能成为一名优秀的专业黑客&#xff1f;” 由于黑客是最熟练的信息技术学科之一&#xff0c;它需要广泛的 IT 技术和技巧知识。要真正成为一名真正的黑客&#xff0c;必须掌握许多技能。这是我总结所需技能的概述列表。我将这些技能分为三类&#xff0c;以帮助你…

家用洗地机有什么推荐的吗?好用的家用洗地机

洗地机采用高效能滚刷设计&#xff0c;可轻松处理多种不同材质地面的卫生问题&#xff0c;例如&#xff1a;地毯、硬地板、瓷砖等等&#xff0c;都能轻松完成深度清洁。而且洗地机还具有智能化设计&#xff0c;例如自动充电、一键启动和一键停止等设计&#xff0c;使它操作起来…

【Hello Algorithm】基础数据结构

作者&#xff1a;小萌新 专栏&#xff1a;算法 作者简介&#xff1a;大二学生 希望能和大家一起进步 本篇博客简介&#xff1a;介绍几种基础数据结构 基础数据结构 单链表结构翻转单链表删除节点 双链表栈和队列用栈实现队列用队列实现栈 哈希表 单链表结构 在阅读这篇文章之前…

GLM-130B-一个开放的双语通用预训练模型-论文精读

本文为作为类ChatGPT的模型ChatGLM的前期基础论文2《AN OPEN BILINGUAL PRE-TRAINED MODEL》的精读笔记&#xff0c;基础论文1的精读笔记请见《GLM论文精读-自回归填空的通用语言模型》。希望对大家有帮助&#xff0c;欢迎讨论交流。GLM-130B&#xff0c;主要思想概述&#xff…

Android 签名文件

签名文件相关 一、为什么需要签名&#xff1f;二、创建签名文件2.1、使用AS新建签名文件2.2、使用 keytool 新建签名文件 三、签名串改参考地址 一、为什么需要签名&#xff1f; Android系统要求每一个Android应用程序必须要经过数字签名才能够安装到系统中&#xff0c;也就是…

YooAsset | Unity资源管理方案

跳转官方仓库地址 一、说明 可空包、可首包DLC、可满足限制包体的需求、可玩家自己制作MOD上传到服务器、可分工程构建&#xff1b;支持内置渲染管线、可编程渲染管线&#xff1b;支持完整路径、可寻址资源定位&#xff1b;基于标签打包&#xff0c;自动分析冗余&#xff0c;基…

MongoDB 查询文档中使用$expr、$where选择器

之前我们介绍过使用比较选择器、逻辑选择器、元素选择器、数组选择器查询文档&#xff0c;如果您需要进一步了解&#xff0c;可以参考&#xff1a; MongoDB 查询文档中使用比较选择器、逻辑选择器https://blog.csdn.net/m1729339749/article/details/129965699MongoDB 查询文档…

【Ubuntu20.04】ROS noetic的g2o与系统g2o冲突问题

文章目录 0.问题描述1.问题原因2.解决方法2.1.方法12.1.方法2 3.成功效果 0.问题描述 \qquad 从github安装2023版本的g2o时&#xff0c;若ROS也安装了g2o&#xff0c;则会在编译时触发运行时冲突。具体表现为段错误&#xff0c;如若需要排查是否为ROS的g2o导致&#xff0c;则需…

MySQL:存储过程与函数、视图

一、学习目标 掌握如何创建存储过程掌握如何创建存储函数熟悉变量的使用方法熟悉如何定义条件和处理程序了解光标的使用方法掌握流程控制的使用掌握如何调用存储过程和函数熟悉如何查看存储过程和函数掌握修改存储过程和函数的方法熟悉如何删除存储过程和函数掌握创建存储过程…