Dart 3.3 发布:扩展类型、JavaScript Interop 等

news2024/11/27 4:01:44

参考链接:https://medium.com/dartlang/dart-3-3-325bf2bf6c13

跟随 Flutter 3.19 发布的还有 Dart 3.3 ,Dart 3.3 主要包含扩展类型增强,性能优化和 native 代码交互推进,例如本次改进的JavaScript Interop 模型就引入了类型安全,所以这一切都为 WebAssembly 支持铺平了道路。

在《Flutter 2024 路线规划里》 ,Web 平台上未来 CanvasKit 将成为默认渲染,所以未来 Dart 在 Web 上肯定是 Wasm Native 的路线。

扩展类型

扩展类型是一种编译时抽象,它用不同的纯静态接口来 “Wrapper” 现有类型,同时它们也是 Dart 和静态 JS 互操作的主要实现基础,因为它们可以轻松修改现有类型的接口(对于任何类型的相互调用都至关重要),而不会产生实际 Wrapper 的成本。

extension type E(int i) {
  // Define set of operations.
}

扩展类型引入了类型的零成本 wrappers,使用它们来优化性能敏感的代码,尤其是在与 native 平台交互时,扩展类型提供了具有特定成员自定义类型的便利性,同时消除了典型的 wrappers 分配开销。

extension type Wrapper(int i) {
  void showValue() {
    print('my value is $i');
  }
}

void main() {
  final wrapper = Wrapper(42);
  wrapper.showValue(); // Prints 'my value is 42'
}

上面的例子实现了一个 Wrapper 扩展类型,但将其用作普通的 Dart 类型,在实际使用里,开发者可以实例化它并调用函数。

这里的主要区别在于 Dart 将其编译为普通 Dart int 类型,扩展类型允许创建具有唯一的成员类型,而无需分配典型 wrappers 类型的间接成本,例如以下例子包装了对应的 int 类型以创建仅允许对 ID 号有意义的操作的扩展类型。

extension type IdNumber(int id) {
  // Wraps the 'int' type's '<' operator:
  operator <(IdNumber other) => id < other.id;
  // Doesn't declare the '+' operator, for example,
  // because addition does not make sense for ID numbers.
}

void main() {
  // Without the discipline of an extension type,
  // 'int' exposes ID numbers to unsafe operations:
  int myUnsafeId = 42424242;
  myUnsafeId = myUnsafeId + 10; // This works, but shouldn't be allowed for IDs.

  var safeId = IdNumber(42424242);
  safeId + 10; // Compile-time error: No '+' operator.
  myUnsafeId = safeId; // Compile-time error: Wrong type.
  myUnsafeId = safeId as int; // OK: Run-time cast to representation type.
  safeId < IdNumber(42424241); // OK: Uses wrapped '<' operator.
}

因此,虽然 extension members 功能(Dart 2.7 开始)允许向现有类型添加函数和属性,但扩展类型功能也可以执行相同的操作,并且还允许定义隐藏底层表示的新 API

这对于与 native code 的相互调用特别有用。可以直接使用原生类型,无需创建 Wrapper 和相关间接的成本,同时仍然提供干净的生产 Dart API。

扩展类型与 Wrapper 具有相同的用途,但不需要创建额外的运行时对象,当开发者需要包装大量对象时,Wrapper 这个行为可能会变得昂贵,由于扩展类型仅是静态的并且在运行时编译,因此它们本质上是零成本。

扩展方法(也称为“扩展”)是类似于扩展类型的静态抽象。但是扩展方法是直接向其基础类型的每个实例添加功能;扩展类型不同,扩展类型的接口仅适用于静态类型为该扩展类型的表达式

默认情况下它们与其基础类型的接口不同。

扩展类型有两个同样有效但本质上不同的核心用例:

  • 为现有类型提供扩展接口,当扩展类型实现其表示类型时,一般可以认为它是“透明的”,因为它允许扩展类型“看到”底层类型。

    透明扩展类型可以调用表示类型的所有成员(未重新声明的),以及它定义的任何辅助成员,这将为现有类型创建一个新的扩展接口,新接口可用于静态类型为扩展类型的表达式,例如如下代码里,v1.i 可以正常调用,但是 int 类似的 v2 不可以调用 v2.i

extension type NumberT(int value) 
  implements int {
  // Doesn't explicitly declare any members of 'int'.
  NumberT get i => this;
}
void main () {
  // All OK: Transparency allows invoking `int` members on the extension type:
  var v1 = NumberT(1); // v1 type: NumberT
  int v2 = NumberT(2); // v2 type: int
  var v3 = v1.i - v1;  // v3 type: int
  var v4 = v2 + v1; // v4 type: int
  var v5 = 2 + v1; // v5 type: int
  // Error: Extension type interface is not available to representation type
  v2.i;
}

  • 为现有类型提供不同的接口,不透明的扩展类型(不是 implement 其表示类型)被静态地视为全新类型,与其表示类型不同,所以无法将其分配给其表示类型,并且它不会公开其表示类型的成员,例如 NumberE 不能为 int ,并且 :
extension type NumberE(int value) {
  NumberE operator +(NumberE other) =>
      NumberE(value + other.value);

  NumberE get next => NumberE(value + 1);
  bool isValid() => !value.isNegative;
}

void testE() { 
  var num1 = NumberE(1);
  int num2 = NumberE(2); // Error: Can't assign 'NumberE' to 'int'.
  
  num1.isValid(); // OK: Extension member invocation.
  num1.isNegative(); // Error: 'NumberE' does not define 'int' member 'isNegative'.
  
  var sum1 = num1 + num1; // OK: 'NumberE' defines '+'.
  var diff1 = num1 - num1; // Error: 'NumberE' does not define 'int' member '-'.
  var diff2 = num1.value - 2; // OK: Can access representation object with reference.
  var sum2 = num1 + 2; // Error: Can't assign 'int' to parameter type 'NumberE'. 
  
  List<NumberE> numbers = [
    NumberE(1), 
    num1.next, // OK: 'i' getter returns type 'NumberE'.
    1, // Error: Can't assign 'int' element to list type 'NumberE'.
  ];
}

另外需要注意,扩展类型是编译时包装构造,在运行时绝对没有扩展类型的踪迹,任何类型查询或类似的运行时操作都适用于表示类型,在任何情况下,扩展类型的表示类型都不是其子类型,因此在需要扩展类型的情况下表示类型不能互换使用。

JavaScript Interop

Dart 3.3 引入了一种与 JavaScript 和 Web 相互调用的新模型,它从一组用于与 JavaScript 交互的新 API 开始:dart:js_interop 。

现在,Dart 开发人员可以访问类型化 API 来与 JavaScript 交互,该 API 通过静态强制明确定义了两种语言之间的边界,在编译之前消除了许多问题。

除了用于访问 JavaScript 代码的新 API 之外,Dart 现在还包含一个新模型,用于使用扩展类型在 Dart 中表示 JavaScript 类型,如下代码就是前面拓展类型的实际使用实例:

import 'dart:js_interop';

/// Represents the `console` browser API.
extension type MyConsole(JSObject _) implements JSObject {
  external void log(JSAny? value);
  external void debug(JSAny? value);
  external void info(JSAny? value);
  external void warn(JSAny? value);
}

基于扩展类型的语法比扩展成员允许更多的表达和健全性。这简化了 Dart 中 JavaScript API 的利用,更多详细信息可以查看:https://dart.dev/interop/js-interop 。

改进 browser libraries

从 1.0 版本开始,Dart SDK 就包含了一套全面的 browser libraries,其中包括核心 dart:html 库以及 SVG、WebGL 等库。

改进后的 JavaScript 调用模型提供了重新构想这些库的机会,未来 browser libraries 支持将集中在 package:web上,这简化了版本控制、加速了更新并与MDN资源保持一致,这一系列的改进推动了将 Dart 编译为 WebAssembly。

从今天开始,开启 WebAssembly 的未来

Dart 3.3 为WebAssembly 的 Web 应用奠定基础,虽然 Flutter Web 中的 WebAssembly 支持仍处于试验阶段,但是这对于 Dart 和 Flutter 是明显的方向。

要使用 WebAssembly 在 Web 上运行 Flutter 应用,需要使用新的 JavaScript Interop 机制和 package:web ,旧版 JavaScript 和 browser libraries 保持不变,并支持编译为 JavaScript 代码。但是,如果编译为 WebAssembly 需要迁移,例如:

import 'dart:html' as html; // Remove
import 'package:web/web.dart' as web; // Add

dependencies:
  web: ^0.5.0

更多可见:https://dart.dev/interop/js-interop/package-web

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

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

相关文章

【lesson56】生产者消费者模型

文章目录 学习生产者消费者模型过程中要回答的两个问题生产者消费者模型的概念基于阻塞队列的生产者消费者模型编码实现Common.hLockGuard.hppCondtion.hppBlockQueue.hppTask.hppConProd.cc 学习生产者消费者模型过程中要回答的两个问题 1.条件变量是在条件满足的时候&#x…

使用 XML 和 YAML 文件的文件输入和输出

目标 您将找到以下问题的答案&#xff1a; 如何使用YAML或XML文件打印和读取文件和OpenCV的文本条目&#xff1f;如何对 OpenCV 数据结构做同样的事情&#xff1f;如何为您的数据结构执行此操作&#xff1f;使用 OpenCV 数据结构&#xff0c;例如 cv&#xff1a;&#xff1a;…

SolidWorks如何在一个零件的基础上绘制另一个零件

经过测试&#xff0c;新建零件&#xff0c;然后插入零件a&#xff0c;在a的基础上绘制b,这种做法无法断开a与b的联系。虽然可以通过切除命令&#xff0c;切除b&#xff0c;但不是正途。 在装配体中可以实现&#xff1a; &#xff08;1&#xff09;建立装配体 &#xff08;2&…

在线黑色响应式全屏滚动主页html源码

html5黑色大气的个人博客全屏滚动个人主页源码 右键记事本即可修改 直接上传服务器空间就可使用

【HTML】过年不能放烟花,那就放电子烟花

闲谈 大家回家过年可能都多多少少放过些&#x1f9e8;&#xff0c;但是有些在城市上过年的小伙伴可能就没有机会放鞭炮了。不过没关系&#xff0c;我们懂技术&#xff0c;我们用技术自娱自乐&#xff0c;放电子烟花&#xff0c;总不可能被警长叔叔敲门问候吧。 开干 首先&…

一个比SDXL更快的模型——Stable Cascade【必坑指北】

2024年的春节假期&#xff0c;AIGC界又发生了重大革命性事件。 OpenAI 发布了首款文生视频模型——Sora。简单来说就是&#xff0c;AI视频要变天了&#xff01;之前的SVD&#xff0c;还是Google的Lumiere最多就几十帧&#xff0c;大约十秒左右&#xff0c;但是Sora却是SOTA级别…

文生视频:Sora模型报告总结

作为世界模拟器的视频生成模型 我们探索视频数据生成模型的大规模训练。具体来说&#xff0c;我们在可变持续时间、分辨率和宽高比的视频和图像上联合训练文本条件扩散模型。我们利用对视频和图像潜在代码的时空补丁进行操作的变压器架构。我们最大的模型 Sora 能够生成一分钟…

BUGKU-WEB 网站被黑

题目描述 题目截图如下&#xff1a; 进入场景看看&#xff1a; 解题思路 提示说&#xff1a; 网站被黑了 黑客会不会留下后门&#xff08;那就是留了&#xff09;那就扫描目录先看看再说发现确实有登入界面&#xff0c;但是密码不知道&#xff08;爆破走起&#xff09; …

Matplotlib plt.plot:从入门到精通,只需一篇文章!

Matplotlib plt.plot&#xff1a;从入门到精通&#xff0c;只需一篇文章&#xff01; 利用Matplotlib进行数据可视化示例 &#x1f335;文章目录&#x1f335; &#x1f4ca; 1. 引言&#xff1a;为什么Matplotlib在数据可视化中如此重要&#xff1f;&#x1f4ca;✨ 2. plt.pl…

【LLM-RAG】BGE M3-embedding模型(模型篇|混合检索、多阶段训练)

note M3-Embedding联合了3种常用的检索方式&#xff0c;对应三种不同的文本相似度计算方法。可以基于这三种检索方式进行多路召回相关文档&#xff0c;然后基于三种相似度得分平均求和对召回结果做进一步重排。 多阶段训练过程&#xff1a; 第一阶段&#xff1a;第一阶段的自…

C语言希尔排序详解!!!速过

目录 希尔排序是什么&#xff1f; 关于时间复杂度 希尔排序的源代码 希尔排序源代码的详解 希尔排序是什么&#xff1f; 之前我们说了三个排序&#xff08;插入排序&#xff0c;选择排序&#xff0c;冒泡排序&#xff09;有需要的铁铁可以去看看之前的讲解。 但因为之前的…

政安晨:【示例演绎】【Python】【Numpy数据处理】快速入门(二)

环境准备 大家如果第一次看到&#xff0c;可以先从我这个演绎系列的第一篇文章开始&#xff0c;包括准备环境等等。 第一篇文章如下&#xff1a; 政安晨&#xff1a;【示例演绎】【Python】【Numpy数据处理】快速入门&#xff08;一&#xff09;https://blog.csdn.net/snowd…

结构体对齐规则及为什么会有结构体对齐

前言&#xff1a; 大家在学习结构体中&#xff0c;在计算结构体大小时想必会很疑惑&#xff0c;为什么结构体的大小不是按照常理像数组一样一个字节一个字节的挨在一起放&#xff1f;今天带大家一起深入探讨一下背后的规则和原因。 结构体对齐规则&#xff1a; 结构体对齐其实…

Kotlin基本语法2基本内置方法

1.Kotlin的可空性 fun main() {var str:String? "butterfly" //?问好代表可空类型str null } 安全的管理 1.1 安全操作调用符 fun main() {var str:String? "butterfly" //?问好代表可空类型str nullprintln(str?.capitalize())//当String为null时…

Windows11系统下对jar文件解压修改后在压缩为jar文件

一、准备内容 安装JAVA环境——若已安装则忽略 我这里以在Windows11中安装JAVA 的JDK8环境为例进行安装配置说明: 1.1、下载JDK安装包 Java Downloads | Oraclehttps://www.oracle.com/java/technologies/downloads/#java8-windows 1.2、安装JDK

流量主小程序/公众号h5开源代码 源码分享

小程序开源代码合集 1、网课搜题小程序源码/小猿题库多接口微信小程序源码自带流量主 搭建教程 1、微信公众平台注册自己的小程序 2、下载微信开发者工具和小程序的源码 3、上传代码到自己的小程序 界面截图&#xff1a; 开源项目地址&#xff1a;https://ms3.ishenglu.com…

【计算机网络】物理层|传输介质|物理层设备|宽带接入技术

目录 一、思维导图 二、传输介质 1.传输介质——导引型 2.传输介质——非导引型​编辑 三、物理层设备 1.物理层设备&#xff1a;中继器&集线器 2.宽带接入技术&#xff08;有线&#xff09; ​编辑 四、趁热打铁☞习题训练 五、物理层总思维导图 推荐 前些天发现…

【电路笔记】-LR串联电路

LR串联电路 文章目录 LR串联电路1、概述2、示例1所有线圈、电感器、扼流圈和变压器都会在其周围产生磁场,由电感与电阻串联组成,形成 LR 串联电路。 1、概述 在本节有关电感器的第一个文章中,我们简要介绍了电感器的时间常数,指出流过电感器的电流不会瞬时变化,而是会以恒…

常见的几种Web安全问题测试简介

Web项目比较常见的安全问题 1.XSS(CrossSite Script)跨站脚本攻击 XSS(CrossSite Script)跨站脚本攻击。它指的是恶意攻击者往Web 页面里插入恶意html代码&#xff0c;当用户浏览该页之时&#xff0c;嵌入其中Web 里面的html 代码会被执行&#xff0c;从而达到恶意用户的特殊…

【Docker】Docker Container操作案例 | 综合实战

文章目录 Docker Container操作案例容器的基本操作容器状态迁移容器批量处理技巧容器交互模式attached模式detached模式interactive模式 容器与宿主机内容复制容器自动删除容器自动重启容器环境变量设置容器详情查看容器执行单行命令容器镜像导入导出容器日志查看容器资源查看 …