当前位置: 首页 > news >正文

2411rust,异步函数

原文

Rust异步工作组很高兴宣布,在实现在特征中使用异步 fn目标方面取得了重大进度.将在下周发布稳定的Rust1.75版,会包括特征中支持impl Trait注解和async fn.

稳定化

自从RFC#1522Rust1.26中稳定下来以来,Rust就允许用户按函数的返回类型(一般叫"RPIT")编写impl Trait.

该函数返回"某种实现特征类型".这一般来返回闭包,迭代器其他复杂或无法显式编写的类型.

//给定一个玩家列表,返回在他们的`名字`上的`一个迭代器`.
fn player_names(players: &[Player]
) -> impl Iterator<Item = &String> {players.iter().map(|p| &p.name)
}

Rust1.75开始,你可在特征(RPITIT)定义和trait impl中使用返回位置impl Trait.如,你可用它来编写一个返回迭代器特征方法:

trait Container {fn items(&self) -> impl Iterator<Item = Widget>;
}
impl Container for MyContainer {fn items(&self) -> impl Iterator<Item = Widget> {self.items.iter().cloned()}
}

这一切与异步函数有什么关系呢?嗯,异步函数只是返回->impl Future的函数的"语法糖".因为在特征中,现在允许这些,还允许你编写使用async fn特征.

trait HttpService {async fn fetch(&self, url: Url) -> HtmlBody;
//^^^^^^^^变为:
//  fn fetch(&self, url: Url) -> impl Future<Output = HtmlBody>;
}

差距在哪?

公开特征中的->impl特征

仍不建议在公开特征API中普遍使用->impl Trait,因为用户无法对返回类型加限制.如,无法对容器特征通用的编写此函数:

fn print_in_reverse(container: impl Container) {for item in container.items().rev() {//错误:^^^对`'impl Iterator<Item=Widget>'`未实现`'DoubleEndedIterator'`特征eprintln!("{item}");}
}

尽管某些实现可能会返回实现DoubleEndedIterator迭代器,但在不定义另一个特征时,泛型代码无法利用它.

未来,打算为此添加一个解决方法.当前,->impl Trait最适合内部特征,或当你确信用户不需要额外约束时.否则,应该考虑使用关联类型.

公开特征中的异步函数

因为async fn解糖为->impl Future,因此有同样限制.事实上,如果今天在公开特征中使用空的异步fn,则会看到警告.
警告:不建议在公开特征中使用"async fn",因为无法指定自动特征约束.

异步用户特别感兴趣的是,在返回的未来上的发送约束.因为用户以后无法添加约束,因此错误消息说明你要选择:是否想你的特征多线程,窃取工作程序一起使用?

好的是,现在有个允许在公开特征中使用异步fn的方法!建议使用trait_variant::make过程宏来让你的用户选择.

过程宏是由rustlang组织发布的traitvariant包的一部分.在项目中加上cargo add trait-variant.使用:

#[trait_variant::make(HttpService: Send)]
pub trait LocalHttpService {async fn fetch(&self, url: Url) -> HtmlBody;
}

这创建两个版本特征:用LocalHttpService针对单线程执行器,HttpService针对多线程工作窃取执行器.因为后者更常用,因此此例中名字更短.
它有额外的发送约束:

pub trait HttpService: Send {fn fetch(&self,url: Url,) -> impl Future<Output = HtmlBody> + Send;
}

该宏适合异步,因为impl Future很少需要发送以外的额外约束,因此可成功为用户准备好.

动态分发

使用->impl Traitasyncfn特征不是对象安全的,即不支持动态分发.准备在未来推出的trait-variant包版本中启用动态分发.

未来如何改进

未来,希望允许用户添加自己的约束impl Trait返回类型,这样更普遍更有用.它还支持异步fn更高级用法.语法可能如下:

trait HttpService = LocalHttpService<fetch(): Send> + Send;

因为这些别名不需要特征作者的支持,因此,因此不需要异步特征发送变量.但是,这些变量仍会方便用户,因此期望大多数继续提供它们.

常见问题解答

是否可在特征中使用->impl Trait

私有特征,可自由使用->impl Trait.对公开特征,最好暂时避免使用它们,除非可预见到用户可能需要的所有约束(此时,你可用#[trait_variant::make],与异步一样).
期望取消来会此限制.

是否仍应使用#[async_trait]

你可能要继续使用异步特征原因有几个:
1,想支持低于1.75Rust版本.
2,你需要动态分发.

如上,希望在未来版本启用动态分发.

可在特征中使用async fn吗?有哪些限制

假设,你不用#[async_trait],则完全可以在特征中使用普通异步 fn.如果想支持多线程运行时,记住使用#[trait_variant::make].

最大限制类型必须总是决定实现了特征发送版本还是非发送版本.它不能在其泛型之一上有条件地实现发送版本.

这可在中间件模式中出现,如,如果T:HttpService,则为HttpServiceRequestLimitingService<T>.

为什么我需要#[trait_variant::make]Send约束

简单情况时,发现你的特征似乎与多线程程序配合得很好.但是,有些模式不管用.考虑以下:

fn spawn_task(service: impl HttpService + 'static) {tokio::spawn(async move {let url = Url::from("https://rustlang.org");let _body = service.fetch(url).await;});
}

如果特征上没有Send约束,则无法编译,并显示错误:"不能在线程间安全发送未来".用Send约束创建特征的变量,可避免发送用户此陷阱.

注意,如果未公开你的特征,则不会看到警告,因为如果有问题,总是可自行添加发送约束.

见此博客文章.

我可插件使用async fnimpl Trait

是的,你可以在特征实现中的async fn->implFuture拼写间自由切换.即使一个形式发送约束,因此.这样更易使用trait_variant创建的特征.

trait HttpService: Send {fn fetch(&self, url: Url)-> impl Future<Output = HtmlBody> + Send;
}
impl HttpService for MyService {async fn fetch(&self, url: Url) -> HtmlBody {//只要有`'do_fetch():Send'`就可以了!self.client.do_fetch(url).await.into_body()}
}

为什么这些签名不使用impl Future+'_

对特征中的->impl Trait,提前用了2024年的抓规则.即今天经常看到的+'_,在特征中是不必要的,因为已假设类型来抓输入生命期.

2024版中,此规则针对所有函数签名.

为什么在使用->impl Trait实现特征时收到"细化"警告

如果你的实现签名,包含比特征自身更详细的信息,你会收到警告:

pub trait Foo {fn foo(self) -> impl Debug;
}
impl Foo for u32 {fn foo(self) -> String {
//^^^^^^警告:`实现方法签名`中的`impl Trait`与`trait`方法签名不匹配self.to_string()}
}

原因是你可能泄露更多实现细节.如,如果以下代码编译.

fn main() {//实现者允许使用`'显示'`,还是只允许使用`特征`所说的`'调试'`println!("{}", 32.foo());
}

因为细化了特征实现,它确实可编译,但编译器会要求你在实现上使用#[allow(refining_impl_trait)],确认你打算细化特征接口.

注意,只能在可以命名类型时,才能使用关联类型.一旦impl_trait_in_assoc_type稳定下来,才取消此限制.

这是因为允许知识从未指定签名它们的项目中"泄漏"的auto trait泄漏.

相关文章:

2411rust,异步函数

原文 Rust异步工作组很高兴地宣布,在实现在特征中使用异步 fn的目标方面取得了重大进度.将在下周发布稳定的Rust1.75版,会包括特征中支持impl Trait注解和async fn. 稳定化 自从RFC#1522在Rust1.26中稳定下来以来,Rust就允许用户按函数的返回类型(一般叫"RPIT")编…...

前端网络性能优化问题

DNS预解析 DNS 解析也是需要时间的&#xff0c;可以通过预解析的⽅式来预先获得域名所对应的 IP。 <link rel"dns-prefetch" href"//abcd.cn"> 缓存 强缓存 在缓存期间不需要请求&#xff0c; state code 为 200 可以通过两种响应头实现&#…...

优选算法——双指针

前言 本篇博客为大家介绍双指针问题&#xff0c;它属于优选算法中的一种&#xff0c;也是一种很经典的算法&#xff1b;算法部分的学习对我们来说至关重要&#xff0c;它可以让我们积累解题思路&#xff0c;同时也可以大大提升我们的编程能力&#xff0c;本文主要是通过一些题…...

【Rabbitmq篇】RabbitMQ⾼级特性----消息确认

目录 前言&#xff1a; 一.消息确认机制 • ⾃动确认 • ⼿动确认 手动确认方法又分为三种&#xff1a; 二. 代码实现&#xff08;spring环境&#xff09; 配置相关信息&#xff1a; 1&#xff09;. AcknowledgeMode.NONE 2 &#xff09;AcknowledgeMode.AUTO 3&…...

开源TTS语音克隆神器GPT-SoVITS_V2版本地整合包部署与远程使用生成音频

文章目录 前言1.GPT-SoVITS V2下载2.本地运行GPT-SoVITS V23.简单使用演示4.安装内网穿透工具4.1 创建远程连接公网地址 5. 固定远程访问公网地址 前言 本文主要介绍如何在Windows系统电脑使用整合包一键部署开源TTS语音克隆神器GPT-SoVITS&#xff0c;并结合cpolar内网穿透工…...

【idea】更换快捷键

因为个人习惯问题需要把快捷键替换一下。我喜欢用CTRLD删除一下&#xff0c;用CTRLY复制一样。恰好这两个快捷键需要互换一下。 打开file——>setting——>Keymap——>Edit Actions 找到CTRLY并且把它删除 找到CTRLD 并且把它删除 鼠标右键添加CTRLY 同样操作在Delet…...

最小的子数组(leetcode 209)

给定一个正整数数组&#xff0c;找到大于等于s的连续的最小长度的区间。 解法一&#xff1a;暴力解法 两层for循环&#xff0c;一个区间终止位置&#xff0c;一个区间起始位置&#xff0c;找到大于等于s的最小区间长度&#xff08;超时了&#xff09; 解法二&#xff1a;双指…...

IDEA-Plugins无法下载插件(网络连接问题-HTTP Proxy Settings)

IDEA-Plugins无法下载插件&#xff08;网络连接问题&#xff09; 改成如下配置&#xff1a; 勾选 添这个url即可&#xff1a;https://plugins.jetbrains.com/ 重启插件中心&#xff0c;问题解决。...

AWTK-WIDGET-WEB-VIEW 发布

awtk-widget-web-view 是通过 webview 提供的接口&#xff0c;实现的 AWTK 自定义控件&#xff0c;使得 AWTK 可以方便的显示 web 页面。 项目网址&#xff1a; https://gitee.com/zlgopen/awtk-widget-web-view webview 提供了一个跨平台的 webview 接口&#xff0c;是一个非…...

Mysql每日一题(if函数)

两种写法if()和case if()函数 select *,if(T.xT.y>T.z and T.xT.z>T.y and T.yT.z>T.x,Yes,No) as triangle from Triangle as T; case方法 select *, case when T.xT.y>T.z and T.xT.z>T.y and T.yT.z>T.x then Yes else No end as triangle from Trian…...

Spring Cloud Alibaba [Gateway]网关。

1 简介 网关作为流量的入口&#xff0c;常用功能包括路由转发、权限校验、限流控制等。而springcloudgateway 作为SpringCloud 官方推出的第二代网关框架&#xff0c;取代了Zuul网关。 1.1 SpringCloudGateway特点: &#xff08;1&#xff09;基于Spring5&#xff0c;支持响应…...

【动手学深度学习Pytorch】2. Softmax回归代码

零实现 导入所需要的包&#xff1a; import torch from IPython import display from d2l import torch as d2l定义数据集参数、模型参数&#xff1a; batch_size 256 # 每次随机读取256张图片 train_iter, test_iter d2l.load_data_fashion_mnist(batch_size) # 将展平每个…...

技术周总结 11.11~11.17 周日(Js JVM XML)

文章目录 一、11.11 周一1.1&#xff09;问题01&#xff1a;js中的prompt弹窗区分出来用户点击的是 确认还是取消进一步示例 1.2&#xff09;问题02&#xff1a;在 prompt弹窗弹出时默认给弹窗中写入一些内容 二、11.12 周二2.1) 问题02: 详解JVM中的本地方法栈本地方法栈的主要…...

MATLAB 使用教程 —— 矩阵和数组

矩阵和数组MATLAB 中矩阵和数组长什么样&#xff1f;MATLAB 怎么用矩阵计算&#xff1f;创建和操作矩阵矩阵运算示例串联 访问矩阵的元素 矩阵和数组 MATLAB 是“matrix laboratory”的缩写形式。MATLAB 主要用于处理 整个的矩阵和数组&#xff0c;而其他编程语言大多逐个处理…...

React教程第二节之虚拟DOM与Diffing算法理解

1、什么是虚拟DOM 虚拟DOM 是javascript的一个对象&#xff0c;是内存中的一种数据结构&#xff0c;以树的形式存储UI的状态&#xff0c;树中的每个节点都代表着真实的DOM&#xff0c;用来描述我们希望在页面看到的 HTML结构&#xff1b; 现在的MVVM 框架&#xff0c;大多使用…...

C++——类和对象(part2)

前言 本篇博客继续为大家介绍类与对象的知识&#xff0c;承接part1的内容&#xff0c;本篇内容是类与对象的核心内容&#xff0c;稍微有些复杂&#xff0c;如果你对其感兴趣&#xff0c;请继续阅读&#xff0c;下面进入正文部分。 1. 类的默认成员函数 默认成员函数就是用户…...

【FFmpeg系列】:音频处理

前言 在多媒体处理领域&#xff0c;FFmpeg无疑是一个不可或缺的利器。它功能强大且高度灵活&#xff0c;能够轻松应对各种音频和视频处理任务&#xff0c;无论是简单的格式转换&#xff0c;还是复杂的音频编辑&#xff0c;都不在话下。然而&#xff0c;要想真正发挥FFmpeg的潜…...

Python绘制雪花

文章目录 系列目录写在前面技术需求完整代码代码分析1. 代码初始化部分分析2. 雪花绘制核心逻辑分析3. 窗口保持部分分析4. 美学与几何特点总结 写在后面 系列目录 序号直达链接爱心系列1Python制作一个无法拒绝的表白界面2Python满屏飘字表白代码3Python无限弹窗满屏表白代码4…...

vue3 如何调用第三方npm包内部的 pinia 状态管理库方法

抛砖引玉: 如果在开发vue3项目是, 引用了npm第三方包 ,而且这个包内使用了Pinia 状态管理库,那我们如何去调用 npm内部的 Pinia 状态管理库呢? 实际遇到的问题: 今天在制作npm包时遇到的问题,之前Vue2版本的时候状态管理库用的Vuex ,当时调用npm包内的状态管理库很简单,直接引…...

uni-app快速入门(七)--组件路由跳转和API路由跳转及参数传递

uni-app有两种页面路由跳转模式&#xff0c;即使用navigator组件跳转和调用API跳转&#xff0c;API调转不要理解为调用后台接口的API&#xff0c;而是指脚本函数中使用跳转函数。 一、组件路由跳转 1.1 打开新页面 打开新页面使用组件的open-type"navigate",见下面…...

基于算法竞赛的c++编程(28)结构体的进阶应用

结构体的嵌套与复杂数据组织 在C中&#xff0c;结构体可以嵌套使用&#xff0c;形成更复杂的数据结构。例如&#xff0c;可以通过嵌套结构体描述多层级数据关系&#xff1a; struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...

《Playwright:微软的自动化测试工具详解》

Playwright 简介:声明内容来自网络&#xff0c;将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具&#xff0c;支持 Chrome、Firefox、Safari 等主流浏览器&#xff0c;提供多语言 API&#xff08;Python、JavaScript、Java、.NET&#xff09;。它的特点包括&a…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)

🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...

【Java学习笔记】BigInteger 和 BigDecimal 类

BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点&#xff1a;传参类型必须是类对象 一、BigInteger 1. 作用&#xff1a;适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...

DingDing机器人群消息推送

文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人&#xff0c;点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置&#xff0c;详见说明文档 成功后&#xff0c;记录Webhook 2 API文档说明 点击设置说明 查看自…...

LOOI机器人的技术实现解析:从手势识别到边缘检测

LOOI机器人作为一款创新的AI硬件产品&#xff0c;通过将智能手机转变为具有情感交互能力的桌面机器人&#xff0c;展示了前沿AI技术与传统硬件设计的完美结合。作为AI与玩具领域的专家&#xff0c;我将全面解析LOOI的技术实现架构&#xff0c;特别是其手势识别、物体识别和环境…...

学习一下用鸿蒙​​DevEco Studio HarmonyOS5实现百度地图

在鸿蒙&#xff08;HarmonyOS5&#xff09;中集成百度地图&#xff0c;可以通过以下步骤和技术方案实现。结合鸿蒙的分布式能力和百度地图的API&#xff0c;可以构建跨设备的定位、导航和地图展示功能。 ​​1. 鸿蒙环境准备​​ ​​开发工具​​&#xff1a;下载安装 ​​De…...

uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)

UniApp 集成腾讯云 IM 富媒体消息全攻略&#xff08;地理位置/文件&#xff09; 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型&#xff0c;核心实现方式&#xff1a; 标准消息类型&#xff1a;直接使用 SDK 内置类型&#xff08;文件、图片等&#xff09;自…...

Python网页自动化Selenium中文文档

1. 安装 1.1. 安装 Selenium Python bindings 提供了一个简单的API&#xff0c;让你使用Selenium WebDriver来编写功能/校验测试。 通过Selenium Python的API&#xff0c;你可以非常直观的使用Selenium WebDriver的所有功能。 Selenium Python bindings 使用非常简洁方便的A…...

C++--string的模拟实现

一,引言 string的模拟实现是只对string对象中给的主要功能经行模拟实现&#xff0c;其目的是加强对string的底层了解&#xff0c;以便于在以后的学习或者工作中更加熟练的使用string。本文中的代码仅供参考并不唯一。 二,默认成员函数 string主要有三个成员变量&#xff0c;…...