Dart 2.13 版现已发布

作者 / Kevin Moore & Michael Thomsen
Dart 2.13 版现已发布,其中新增了类型别名功能,这是目前用户呼声第二高的语言功能。Dart 2.13 还改进了 Dart FFI 以及更好的性能,并且我们还为 Dart 提供了新的官方镜像。本文将为您奉上 2.12 版中推出的空安全功能的最新信息,介绍 2.13 版本的新特性,以及 Docker 和 Google Cloud 对 Dart 后端支持的新消息。另外,还会预告在后续版本中的其他变化。
空安全更新
在今年 3 月份发布的 Dart 2.12 中,我们推出了 健全的空安 全功能。空安全可谓是 Dart 最近推出的一项重要功能,旨在帮助您避免空值错误 (这类错误经常难以发现),有效提升工作效率。我们希望发布 package 的开发者能够及时跟进这项发布,更新 pub.dev 上分享的 package 以支持空安全。
我们极其欣喜地看到,在发布后的短短几个月内,空安全就已被广泛采用,目前 pub.dev 上前 500 个最受欢迎的 package 中,93% 的 package 已经支持空安全。 在此,谨向如此迅速跟进的所有 package 开发者致以最诚挚的谢意,感谢大家帮助推动整个生态系统不断向前!
有了这么多 package 支持空安全,您就可以开始考虑着手将自己的应用迁移到使用空安全的环境。要开始迁移,请首先使用 dart pub outdated 检查应用的依赖项。详细步骤,请参阅 空安全迁移指南。我们还调整了 dart create 和 flutter create 模板,现在它们在新的应用程序和 package 中默认启用空安全。
推出类型别名功能
类型别名是 2.13 版中新增的语言功能,也是广大开发者翘首以盼的功能,曾在语言问题的反馈中高居 第二位。有了这一功能,开发者就能够创建函数类型的别名,但不能创建其他任何类型。
利用类型别名您可以为任何现有的类型创建新的名称,然后将新创建的名称用在原始类型可以出现的任何地方。创建新名称并不会真的定义一个新类型,只不过是引入一个简短的别名而已。该别名甚至能通过类型等同测试:
typedef Integer = int;
void main() {
print(int == Integer); // true
}
那么,类型别名可以怎么用?一种常见的用法是给某类型指定一个更短或更具描述性的名称,以便您的代码更易于理解和维护。
比如,给 JSON 类型指定别名就是种不错的用法 (此示例由 GitHub 用户 Levi-Lesches 提供,特此感谢)。在下列示例中,我们可以定义一个新的类型别名 Json,它将一个 JSON 文档描述为一个 map,其键为 String,值为任意值 (使用动态类型)。这样,当我们定义名为 fromJson 的构造函数和 json get函数时,就能使用该 Json 类型别名。
typedef Json = Map<String, dynamic>;
class User {
final String name;
final int age;
User.fromJson(Json json) :
name = json['name'],
age = json['age'];
Json get json => {
'name': name,
'age': age,
};
}
您也可以对指代某个类的类型别名调用构造函数,比如以下示例就非常合规:
main() {
var j = Json();
j['name'] = 'Michael';
}
通过使用类型别名来指代复杂类型,可以让读者更容易理解您代码的不变量。例如,以下代码定义了一个类型别名来描述键值为泛型类型 X、值为类型 List<X> 的映射。如果给该类型指定一个具有单一类型参数的名称,映射的常规结构在代码读者眼中会变得更为清晰。
typedef MapToList<X> = Map<X, List<X>>;
void main() {
MapToList<int> m = {};
m[7] = [7]; // OK
m[8] = [2, 2, 2]; // OK
for (var x in m.keys) {
print('$x --> ${m[x]}');
}
}
=>
7 --> [7]
8 --> [2, 2, 2]
如果您尝试使用不匹配的类型,将出现分析错误:
m[42] = ['The', 'meaning', 'of', 'life'];
=>
The element type 'String' can't be assigned to the list type 'int'.
您甚至可以使用类型别名来重命名公共库中的类。假设现在公共库中有一个 PoorlyNamedClass 类,您想要将它重命名为 BetterNamedClass。如果您只是重命名该类,那么您的 API 客户那边将会出现突发编译错误。而使用类型别名,则不会出现这一问题,您可以随意重命名,只不过要先为旧的类名称定义一个新的类型别名,再给旧名称添加几行 @Deprecated 注解。这样,使用 PoorlyNamedClass 的代码虽然会出现警告,但仍可继续编译并照旧正常运行,让用户有时间升级其代码。
mylibrary.dart:
class BetterNamedClass {}
@Deprecated('Use BetterNamedClass instead')
typedef PoorlyNamedClass = BetterNamedClass;
main.dart
import 'mylibrary.dart';
void main() {
PoorlyNamedClass p;
}
=>
'PoorlyNamedClass' is deprecated and shouldn't be used. Use BetterNamedClass instead.
下面介绍实现 BetterNamedClass 和弃用 PoorlyNamedClass 的方法 (在一个名为 mylibrary.dart 的文件中)。
class BetterNamedClass {...}
@Deprecated('Use BetterNamedClass instead')
typedef PoorlyNamedClass = BetterNamedClass;
下面是尝试使用 PoorlyNamedClass 时会发生的情况:
import 'mylibrary.dart';
void main() {
PoorlyNamedClass p;
}
=>
'PoorlyNamedClass' is deprecated and shouldn't be used. Use BetterNamedClass instead.
类型别名功能从 Dart 2.13 版开始即可使用,要启用此功能,需要将您 pubspec 中版本较低的 Dart SDK 约束设置为最低 2.13 版,如下所示:
environment:
sdk: ">=2.13.0 <3.0.0"
此功能支持向后兼容,这要归功于 语言的版本管理。也就是说,SDK 约束版本低于 2.13 的 package 可以安全地引用 2.13 版 package 中定义的类型别名,尽管 2.13 版之前的 package 不能定义其自己的类型别名。
Dart 2.13 FFI 的变化
我们还在 Dart FFI (这是用来调用 C 语言代码的互操作机制) 中引入了一些新功能。
首先,FFI 现在支持包含内联数组 (#35763) 的结构。假设某 C 语言结构具有如下内联数组:
struct MyStruct {
uint8_t arr[8];
}
现在,只需将包含一个类型实参的元素类型指定给 Array,即可直接将该结构体封装在 Dart 中,如下所示:
class StructInlineArray extends Struct {
@Array(8)
external Array<Uint8> arr;
}
其次,FFI 现在支持封装结构体 (#38158)。结构体通常都被放置在内存中,以便其位于地址边界内的成员能够被 CPU 更轻松地存取。使用 封装结构体 时,为了减少整体内存占用量,经常会以平台特有的方式忽略一些填充字节。借助新的 @Packed(<alignment>) 注解,您可以轻松指定填充字节。例如,下列代码创建的结构体就指定其在内存中时的字节对齐为 4。
@Packed(4)
class TASKDIALOGCONFIG extends Struct {
@Uint32()
external int cbSize;
@IntPtr()
external int hwndParent;
@IntPtr()
external int hInstance;
@Uint32()
external int dwFlags;
…
}
Dart 2.13 在性能方面的提升
我们一直在不断努力降低 Dart 代码的应用体量和内存占用量。在大型 Flutter 应用中,经过 AOT 编译 Dart 程序的元数据的内部结构可能要占用非常可观的内存。这些元数据的存在大多是为了实现热重载、交互式调试,以及格式化可读堆栈轨迹等功能,这些功能在需要部署的应用中从不会用到。过去几年来,我们一直在重构 Dart 原生运行时环境,以便尽可能多地消除这种开销。其中一些改进适用于所有以版本模式构建的 Flutter 应用,而有些则需要使用 --split-debug-info 标志将 AOT 编译应用中的调试信息拆分出来,从而放弃可读的堆栈轨迹。
Dart 2.13 在内存消耗上取得了很大的进步,在使用 --split-debug-info 时,程序元数据占用的空间量降幅显著。例如,Flutter Gallery 的空间占用降幅达到 30%: 在 --split-debug-info 模式下,程序元数据在 Dart 2.12 中要占用 5.7Mb,而在 Dart 2.13 中仅需 3.7Mb。以 Flutter Gallery 应用为例,在 Android 平台上,包含调试信息的发布 APK 大小为 112.4MB,不包含的情况下大小为 106.7MB (总体积减少了 5%)。该 APK 中包含了大量的资源。仅从 APK 内部的元数据体积来说,从 Dart 2.12 平台上的 5.7MB 减少至 Dart 2.13 平台上的 3.7MB (减少了35%!)。
如果对您来说应用体量和内存占用量比较重要,可以使用 --split-debug-info 标志省略调试信息。请注意,一旦这么做,您需要使用 symbolize 命令 来重新使堆栈轨迹可读。
Dart 官方 Docker 镜像发布以及 Cloud 支持
Dart 现在在 官方镜像 中可用,虽然 Dart 早已提供了 Docker 镜像,但为了遵循最佳实践,这些 新的 Dart 镜像 是由 Docker 进行测试和验证的。它们还支持 AOT 编译,可以大大减少构建容器的大小,并且可以在容器环境中提升部署速度——如 Cloud Run。
虽然 Dart 始终专注于使 Flutter 等应用框架在每个屏幕上构建出色的界面,但我们意识到,大多数用户体验的背后至少有一个托管服务。通过让 Dart 轻松构建后端服务来支持全栈体验,开发者可以使用与前端 widget 相同的语言和业务逻辑,将他们的应用扩展到云端。
通常来说,将 Dart 用于 Flutter 应用程序的后端,特别符合 Google 无服务器管理平台 Cloud Run 的简单性和可扩展性。这也包括零扩展,意味着当您的后端不处理任何请求时,就不会产生成本。我们与 Google Cloud 团队合作,提供 Dart 的函数框架,这是一个 packages、工具和实例的集合,使开发者们能够轻松地编写 Dart 函数,以取代处理 HTTP 请求和 CloudEvents 的完整服务器部署。
您可以查看我们的 Google Cloud 官方文档 以便开始使用。
后续更新预告
在接下来的版本中,还会有一些令人激动的改变。和以往一样,您可以使用 language funnel 追踪器留意我们的后续工作。
我们一直努力改进的一个方面是,为 Dart 和 Flutter 定义一组新的 canonical lint。lint 是配置 Dart 静态分析 的一种高效方式,但由于可能有成百上千个 lint 要启用或禁用,有时可能会难以抉择。眼下,我们正打算定义两组要在 Dart 和 Flutter 项目中默认应用的 canonical lint。预计这两组 lint 将在下一个稳定版中默认启用。如果您想要提前预览,请查看 lints 和 flutter_lints 这两个 package。
最后,如果您深度嵌套了 Dart VM 运行时环境,请注意,我们打算弃用其现有的机制。我们将用一个基于 Dart FFI 的更快、更灵活的模型取代它 (请参阅追踪问题 #45451)。
Dart 2.13 版现已发布
Dart 2.13 版现已在 Dart 2.13 和 Flutter 2.2 SDK 中推出,此版本新增了类型别名功能,还改进了 FFI。
如果您一直在等待将自己的依赖项迁移到空安全环境的时机,不妨使用 dart pub outdated 再次检查一下。目前,前 500 个最受欢迎的 package 中,93% 的 package 都已迁移,现在没准就是您迁移的好时机。在此,谨向那些已经迁移的开发者致以最衷心的感谢!
欢迎试用本指南中介绍的新功能和改进后的功能,并将您使用后的感想告诉我们。请在下方评论区留言。
Dart 2.13 版现已发布的更多相关文章
- Microsoft Message Analyzer (微软消息分析器,“网络抓包工具 - Network Monitor”的替代品)官方正式版现已发布
Microsoft Message Analyzer (微软消息分析器,“网络抓包工具 - Network Monitor”的替代品)官方正式版现已发布 来自官方日志的喜悦 被誉为全新开始的消息分析器 ...
- Microsoft Message Analyzer (微软消息分析器,“网络抓包工具 - Network Monitor”的替代品)官方正式版现已发布
来自官方日志的喜悦 被誉为全新开始的消息分析器时代,由MMA为您开启,博客原文写的很激动,大家可以点击这里浏览:http://blogs.technet.com/b/messageanalyzer/a ...
- 适用于 Flutter 的 Google 移动广告 SDK 正式版现已发布
作者 / Zoey Fan,Flutter 产品经理 应用变现有多种方法: 通过实体企业的店面接受付款.提供订阅或应用内购买,或者直接在应用中投放广告.经过六个月的 beta 测试期,我们很高兴能够推 ...
- Tapdata 的 2.0 版 ,开源的 Live Data Platform 现已发布
https://www.bilibili.com/video/BV1tT411g7PA/?aid=470724972&cid=766317673&page=1 点击上方链接,一分钟快速 ...
- 声笔码7.00版现已进入Beta测试阶段
声笔码7.00版现已进入Beta测试阶段,有兴趣的朋友可以试试,欢迎多提宝贵意见. 由于论坛附件限制了1M的大小所以无法上传,需要的朋友可加入声笔系列码群(QQ群号:445906697),到共享文件夹 ...
- Fuel4D 2.1 免费跨平台游戏引擎 现已发布
Fuel4D 2.1 免费跨平台游戏引擎 现已发布 开发环境:纯 C/C++,无JAVA.O-C. 支持 WIN32.安卓 系统. 详情见官方网站:http://www.fuel4d.com 或者进F ...
- Eclipse4.3正式版已发布
Eclipse4.3正式版已发布,传送门http://www.eclipse.org/downloads/
- KiCad 5.1.0 正式版终于发布
KiCad 5.1.0 正式版终于发布 前几天看到 KiCad 5.1.0 在官方的测试文件夹中,过了三天正式发布了,看来没什么问题了. 据说比 5.0 快了很多. 以下为官方的新闻. KiCad 5 ...
- [海蜘蛛] 海蜘蛛 V8 全线无限试用版 免费发布破解教程
http://bbs.p52.cn/forum.php?mod=viewthread&tid=3499&extra=page%3D1&page=1&_dsign=79c ...
随机推荐
- Topshelf一个用于使用.NET构建Windows服务框架
1 Topshelf是什么? Topshelf是用于托管使用.NET框架编写的Windows服务的框架.服务的创建得到简化,从而使开发人员可以创建一个简单的控制台应用程序,可以使用Topshelf将其 ...
- CodeForces CF875C题解
题解 非常有意思的\(2-SAT\)的题. 听学长讲完之后感觉确实容易想到\(2-SAT\),顺理成章. 显然,对于两个串,对咱们来说有意义的显然是两个串中第一个不同的数字.那么,我们假设两个串分别是 ...
- 截取pod ip地址最后一列
资源清单: --- apiVersion: extensions/v1beta1 kind: Deployment metadata: name: init-demo namespace: test ...
- xctf - stack2
xctf - stack2 文件check一下,几乎全开了 运行一下程序,好像很正常呢: 再来一个大的,好像有点儿问题,变1.00了 在ida中查看,在输入的时候没有检查数据大小 可以通过劫持eip获 ...
- 认识Git并了解Git的基本知识
目录 认识Git 版本控制 版本控制的发展史 安装Git Git的核心概念 Git的使用原理 Git的工作流程 Git的基本流程 Git与SVN的区别 Git的基本使用 初始化Git 创建一个Git仓 ...
- 鸿蒙手机版JNI实战(JNI开发、SO库生成、SO库使用)
鸿蒙JNI开发现状 现阶段,不仅鸿蒙JNI相关的开发资料较少,而且Phone相关的JNI开发资料几乎没有,这对于新入行的鸿蒙开发者们来说,非常不友好. 也可能会给Android工程(使用了SO库的工程 ...
- commons-pool2 池化技术探究
一.前言 我们经常会接触各种池化的技术或者概念,包括对象池.连接池.线程池等,池化技术最大的好处就是实现对象的重复利用,尤其是创建和使用大对象或者宝贵资源(HTTP连接对象,MySQL连接对象)等方面 ...
- Mysql通配符的使用
通配符的分类:%百分号通配符: 匹配任意字符,包括0个到多个_下划线通配符:表示只能匹配单个字符,不能多也不能少,就是一个字符. escape:用来转义特定字符 [字符列] :字符列中任何一个 ...
- ASP检测客户是否取消微信公众号
有时因为项目内需要用到检测客户是否已经取消关注微信公众号,只有没被取消执行相关模板信息发送.图文信息发送.视频语音等信息发送给客户才有意义.也可以知道多少客户还在我们的微信公众号关注内.方便后期做公众 ...
- 03- web表单测试
软件分为 b/s c/s两种架构 表单测试 1.用户注册,登录,信息提交. 2.用户查询商品. 3.用户订购商品. 4.用户查询订单等. 表单测试实例 表单数据添加测试(一) 添加按钮可用,测试点击添 ...