一起看 I/O | Dart 2.13 版现已发布

一起看 I/O | Dart 2.13 版现已发布
www.zeeklog.com  - 一起看 I/O | 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 最近推出的一项重要功能,旨在帮助您避免空值错误 (这类错误经常难以发现),有效提升工作效率。我们希望发布 package 的开发者能够及时跟进这项发布,更新 pub.dev 上分享的 package 以支持空安全。

健全的空安全

https://dart.cn/null-safety

我们极其欣喜地看到,在发布后的短短几个月内,空安全就已被广泛采用,目前 pub.dev 上前 500 个最受欢迎的 package 中,93% 的 package 已经支持空安全。在此,谨向如此迅速跟进的所有 package 开发者致以最诚挚的谢意,感谢大家帮助推动整个生态系统不断向前!

有了这么多 package 支持空安全,您就可以开始考虑着手将自己的应用迁移到使用空安全的环境。要开始迁移,请首先使用 dart pub outdated 检查应用的依赖项。详细步骤,请参阅空安全迁移指南。我们还调整了 dart create 和 flutter create 模板,现在它们在新的应用程序和 package 中默认启用空安全。

空安全迁移指南

https://dart.cn/null-safety/migration-guide#step1-wait

推出类型别名功能

类型别名是 2.13 版中新增的语言功能,也是广大开发者翘首以盼的功能,曾在语言问题的反馈中高居第二位。有了这一功能,开发者就能够创建函数类型的别名,但不能创建其他任何类型。

第二位

https://github.com/dart-lang/language/issues?q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc

利用类型别名您可以为任何现有的类型创建新的名称,然后将新创建的名称用在原始类型可以出现的任何地方。创建新名称并不会真的定义一个新类型,只不过是引入一个简短的别名而已。该别名甚至能通过类型等同测试:

typedef Integer = int;


void main() {
  print(int == Integer); // true
}

那么,类型别名可以怎么用?一种常见的用法是给某类型指定一个更短或更具描述性的名称,以便您的代码更易于理解和维护。

比如,给 JSON 类型指定别名就是种不错的用法 (此示例由 GitHub 用户 Levi-Lesches 提供,特此感谢)。在下列示例中,我们可以定义一个新的类型别名 Json,它将一个 JSON 文档描述为一个 map,其键为 String,值为任意值 (使用动态类型)。这样,当我们定义名为 fromJson 的构造函数和 json get 函数时,就能使用该 Json 类型别名。

Levi-Lesches

https://github.com/Levi-Lesches

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 不能定义其自己的类型别名。

语言的版本管理

https://dart.cn/guides/language/evolution#language-versioning

Dart 2.13 FFI 的变化

我们还在 Dart FFI (这是用来调用 C 语言代码的互操作机制) 中引入了一些新功能。

首先,FFI 现在支持包含内联数组 (#35763) 的结构。假设某 C 语言结构具有如下内联数组:

#35763

https://github.com/dart-lang/sdk/issues/35763

struct MyStruct {
  uint8_t arr[8];
}

现在,只需将包含一个类型实参的元素类型指定给 Array,即可直接将该结构体封装在 Dart 中,如下所示:

class StructInlineArray extends Struct {
  @Array(8)
  external Array<Uint8> arr;
}

其次,FFI 现在支持封装结构体 (#38158)。结构体通常都被放置在内存中,以便其位于地址边界内的成员能够被 CPU 更轻松地存取。使用封装结构体时,为了减少整体内存占用量,经常会以平台特有的方式忽略一些填充字节。借助新的 @Packed(<alignment>) 注解,您可以轻松指定填充字节。例如,下列代码创建的结构体就指定其在内存中时的字节对齐为 4。

#38158

https://github.com/dart-lang/sdk/issues/38158

封装结构体

http://www.catb.org/esr/structure-packing/

@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 编译应用中的调试信息拆分出来,从而放弃可读的堆栈轨迹。

--split-debug-info

https://dart.cn/docs/perf/app-size#reducing-app-size

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 命令来重新使堆栈轨迹可读。

--split-debug-info

https://dart.cn/docs/perf/app-size#reducing-app-size

symbolize 命令

https://dart.cn/docs/deployment/obfuscate#reading-an-obfuscated-stack-trace

Dart 官方 Docker 镜像发布以及 Cloud 支持

Dart 现在在官方镜像中可用,虽然 Dart 早已提供了 Docker 镜像,但为了遵循最佳实践,这些新的 Dart 镜像是由 Docker 进行测试和验证的。它们还支持 AOT 编译,可以大大减少构建容器的大小,并且可以在容器环境中提升部署速度——如 Cloud Run。

官方镜像

https://docs.docker.com/docker-hub/official_images/

新的 Dart 镜像

https://hub.docker.com/_/dart

Cloud Run

https://cloud.google.com/run

虽然 Dart 始终专注于使 Flutter 等应用框架在每个屏幕上构建出色的界面,但我们意识到,大多数用户体验的背后至少有一个托管服务。通过让 Dart 轻松构建后端服务来支持全栈体验,开发者可以使用与前端 widget 相同的语言和业务逻辑,将他们的应用扩展到云端。

通常来说,将 Dart 用于 Flutter 应用程序的后端,特别符合 Google 无服务器管理平台 Cloud Run 的简单性和可扩展性。这也包括零扩展,意味着当您的后端不处理任何请求时,就不会产生成本。我们与 Google Cloud 团队合作,提供 Dart 的函数框架,这是一个 packages、工具和实例的集合,使开发者们能够轻松地编写 Dart 函数,以取代处理 HTTP 请求和 CloudEvents 的完整服务器部署。

Dart 的函数框架

https://pub.dev/packages/functions_framework

您可以查看我们的 Google Cloud 官方文档以便开始使用:

https://dart.cn/server/google-cloud

后续更新预告

在接下来的版本中,还会有一些令人激动的改变。和以往一样,您可以使用 language funnel 追踪器留意我们的后续工作:

https://github.com/dart-lang/language/projects/1

我们一直努力改进的一个方面是,为 Dart 和 Flutter 定义一组新的 canonical lint。lint 是配置 Dart 静态分析的一种高效方式,但由于可能有成百上千个 lint 要启用或禁用,有时可能会难以抉择。眼下,我们正打算定义两组要在 Dart 和 Flutter 项目中默认应用的 canonical lint。预计这两组 lint 将在下一个稳定版中默认启用。如果您想要提前预览,请查看 lints 和 flutter_lints 这两个 package。

静态分析

https://dart.cn//guides/language/analysis-options

lints

https://pub.dev/packages/lints

flutter_lints

https://pub.dev/packages/flutter_lints

最后,如果您深度嵌套了 Dart VM 运行时环境,请注意,我们打算弃用其现有的机制。我们将用一个基于 Dart FFI 的更快、更灵活的模型取代它 (请参阅追踪问题 #45451)。

#45451

https://github.com/dart-lang/sdk/issues/45451

Dart 2.13 版现已发布

Dart 2.13 版现已在 Dart 2.13 和  SDK 中推出,此版本新增了类型别名功能,还改进了 FFI。

Dart 2.13

https://dart.cn/get-dart

Flutter 2.2

https://flutter.cn/docs/get-started/

如果您一直在等待将自己的依赖项迁移到空安全环境的时机,不妨使用 dart pub outdated 再次检查一下。目前,前 500 个最受欢迎的 package 中,93% 的 package 都已迁移,现在没准就是您迁移的好时机。在此,谨向那些已经迁移的开发者致以最衷心的感谢!

dart pub outdated

https://dart.cn/null-safety/migration-guide

欢迎试用本指南中介绍的新功能和改进后的功能,并将您使用后的感想告诉我们。请在下方评论区留言。

www.zeeklog.com  - 一起看 I/O | Dart 2.13 版现已发布

推荐阅读

如页面未加载,请刷新重试

www.zeeklog.com  - 一起看 I/O | Dart 2.13 版现已发布

点击屏末 | 阅读原文 | 即刻获取 Dart SDK


www.zeeklog.com  - 一起看 I/O | Dart 2.13 版现已发布
www.zeeklog.com  - 一起看 I/O | Dart 2.13 版现已发布
www.zeeklog.com  - 一起看 I/O | Dart 2.13 版现已发布

Read more

60个“特征工程”计算函数(Python代码)

60个“特征工程”计算函数(Python代码)

转自:coggle数据科学 近期一些朋友询问我关于如何做特征工程的问题,有没有什么适合初学者的有效操作。 特征工程的问题往往需要具体问题具体分析,当然也有一些暴力的策略,可以在竞赛初赛前期可以带来较大提升,而很多竞赛往往依赖这些信息就可以拿到非常好的效果,剩余的则需要结合业务逻辑以及很多其他的技巧,此处我们将平时用得最多的聚合操作罗列在下方。 最近刚好看到一篇文章汇总了非常多的聚合函数,就摘录在下方,供许多初入竞赛的朋友参考。 聚合特征汇总 pandas自带的聚合函数 * 其它重要聚合函数 其它重要聚合函数&分类分别如下。 def median(x):     return np.median(x) def variation_coefficient(x):     mean = np.mean(x)     if mean != 0:         return np.std(x) / mean     else:         return np.nan def variance(x):     return

By Ne0inhk
90w,确实可以封神了!

90w,确实可以封神了!

要说24年一定最热的技术,还得是AIGC! 前段时间阿里旗下的开源项目,登上GitHub热榜! AI大热,如今ChatGPT的优异表现,必然会出现各种细分场景应用的工具软件,和大量岗位项目! 山雨欲来风满楼,强人工智能的出现,所有科技公司已经开始巨量扩招此领域的人才。算法的岗位,近三个月已经增长68%!这件事在HR届也是相当震撼的。 目前各行各业都不景气的市场,人工智能岗位却一直保持常青!甚至同属AI边缘岗都比其他岗薪资高40%! 与此同时,AI算法岗上岸也不简单,竞争激烈,好公司核心岗位不用说,谁都想去。 所以事实就是,想要上岸,门槛也逐渐变高,项目经历、实习经历都很重要,越早明白这个道理就越能提前建立起自己的优势。 但我在b站逛知识区的时候,经常看到有些同学,因为一些客观原因导致无法参加实习,这种情况下,如果你想提升背景,增加项目经历的话,可以试试这个《CV/NLP 算法工程师培养计划》。 目前已经有上千位同学通过该计划拿到offer了,最新一期学员就业薪资最高能拿到78K!年薪94w! 优势就是有BAT大厂讲师带领,手把手带做AI真实企业项目(包含CV、NLP等

By Ne0inhk
再见nohup!试试这个神器,Python Supervisor!

再见nohup!试试这个神器,Python Supervisor!

👇我的小册 45章教程:() ,原价299,限时特价2杯咖啡,满100人涨10元。 作者丨Ais137 https://juejin.cn/post/7354406980784373798 1. 概述 Supervisor 是一个 C/S 架构的进程监控与管理工具,本文主要介绍其基本用法和部分高级特性,用于解决部署持久化进程的稳定性问题。 2. 问题场景 在实际的工作中,往往会有部署持久化进程的需求,比如接口服务进程,又或者是消费者进程等。这类进程通常是作为后台进程持久化运行的。 一般的部署方法是通过 nohup cmd & 命令来部署。但是这种方式有个弊端是在某些情况下无法保证目标进程的稳定性运行,有的时候 nohup 运行的后台任务会因为未知原因中断,从而导致服务或者消费中断,进而影响项目的正常运行。 为了解决上述问题,通过引入 Supervisor 来部署持久化进程,提高系统运行的稳定性。 3. Supervisor 简介 Supervisor is a client/

By Ne0inhk
第一本给程序员看的AI Agent图书上市了!

第一本给程序员看的AI Agent图书上市了!

AI Agent火爆到什么程度? OpenAI创始人奥特曼预测,未来各行各业,每一个人都可以拥有一个AI Agent;比尔·盖茨在2023年层预言:AI Agent将彻底改变人机交互方式,并颠覆整个软件行业;吴恩达教授在AI Ascent 2024演讲中高赞:AI Agent是一个令人兴奋的趋势,所有从事AI开发的人都应该关注。而国内的各科技巨头也纷纷布局AI Agent平台,如:钉钉的AI PaaS、百度智能云千帆大模型平台等等。 Agent 是未来最重要的智能化工具。对于程序员来说,是时候将目光转向大模型的应用开发了,率先抢占AI的下一个风口AI Agent。 小异带来一本新书《大模型应用开发 动手做 AI Agent》,这本书由《GPT图解》的作者黄佳老师创作,从0到1手把手教你做AI Agent。现在下单享受5折特惠! ▼点击下方,即可5折起购书 有这样一本秘籍在手,程序员们这下放心了吧,让我们先来揭开 Agent 的神秘面纱。 AI Agent 面面观

By Ne0inhk