2411rust,实现特征

news2024/11/24 9:12:34

原文

Rust2024中,impl Trait位置的默认工作方式有了变化.是为了简化impl Trait,以更好地匹配人们一般的需求.

还添加了一个灵活的语法,让你需要时可完全控制.

Rust2024开始,一直在更改,何时可在返回位置impl Trait隐藏类型中使用泛型参数的规则:

1,即对返回位置impl Trait隐藏类型,的新的默认值,可在域中用任意泛型参数,而不仅是(仅适合Rust2024)类型;
2,用来显式声明可用哪些类型一个语法(可在任意版本中使用).

新的显式语法"用约束":如,impl Trait+use<'x,T>表示允许隐藏类型使用'xT(但不能使用域内其他泛型参数).

背景:返回位置impl Trait

本篇涉及返回位置impl Trait,如以下示例:

fn process_data(
    data: &[Datum]
) -> impl Iterator<Item = ProcessedDatum> {
    data
        .iter()
        .map(|datum| datum.process())
}

在此返回位置``使用->impl Iterator,表明该函数返回实际类型由编译器根据函数体确定的"某种迭代器".它叫做"隐藏类型",因为调用者无法确切地知道它是什么;

他们必须针对Iterator特征编码.但是,在生成代码时,编译器根据实际的精确类型生成代码,从而确保充分优化调用者.

尽管调用者不知道确切的类型,但确实需要知道它继续借用数据参数,这样可确保在迭代数据引用保持有效.

此外,调用者必须可无需查看函数体,仅根据类型签名来弄清楚它.

Rust当前规则是,返回位置impl Trait值只有在impl Trait自身中有引用的生命期时,才能使用引用.此例中,impl Iterator<Item = ProcessedDatum>引用生命期,因此抓数据非法的.

你可在玩耍地上亲眼看到它.

此时收到的错误消息(“隐藏类型抓生命期”)不是很直观,但它确实附带了如何修复它的有用建议:
帮助:要声明impl Iterator<Item = ProcessedDatum>
''_'时,你可添加显式''_'生命期约束

impl Iterator<Item = ProcessedDatum> + '_ {

此建议的显式版本,函数签名变为:

fn process_data<'d>(
    data: &'d [Datum]
) -> impl Iterator<Item = ProcessedDatum> + 'd {
    data
        .iter()
        .map(|datum| datum.process())
}

在此版本中,在impl Trait类型中显式引用,'d数据的生命期,因此允许使用.即只要正在使用迭代器,就必须持续借用数据,即它(正确地)此例中标记错误:

let mut data: Vec<Datum> = vec![Datum::default()];
let iter = process_data(&data);
data.push(Datum::default()); //<-错误!
iter.next();

此设计的可用性问题

impl Trait中可用哪些泛型参数规则是在早期根据一组有限的示例确定的.随着时间,会注意到它们有许多问题.

1,不是正确的默认值

主要代码基(编译器和crates.io上的)的调查发现,绝大多数返回位置impl Trait值都要用生命期,因此默认不抓没用.

2,不够灵活

当前规则是返回位置impl Trait总是允许使用类型参数,有时如果它们出现在约束中,允许使用生命期参数.

如上,该默认值是错误的,因为大多数函数实际上确实想允许返回类型使用生命期参数:这至少有变通.
默认值也是错误的,因为某些函数想要显式声明它们不在返回类型使用类型参数,且现在无法覆盖它.

最初意图是类型别名impl Trait可解决该用例,但很麻烦.

3,难以解释

因为默认值错误的,所以用户经常遇见这些错误!添加编译器提示以建议+'_有用,但用户必须遵守不完全理解的提示并不是很好.

4,错误的建议

impl Trait添加+'_参数可能会很怪,但并不是很难.可惜,它一般是错误的注解,导致不必要的编译器错误,正确的修复很复杂,有时甚至不可能.考虑如下示例:

fn process<'c, T> {
    context: &'c Context,
    data: Vec<T>,
) -> impl Iterator<Item = ()> + 'c {
    data
        .into_iter()
        .map(|datum| context.process(datum))
}

此处,处理函数用context.process来处理数据中的(T类型)每个元素.因为返回值使用环境,因此按+'c声明它.

在此真正目标是允许类型中,使用'c;写+'c实现该目标,因为现在在约束列表中有'c.但是,虽然编写+'c是使'c出现在约束中的方便方法,但也表明隐藏类型必须比'c更久.

该要求是不必要的,实际上会导致本例编译错误,在玩耍地上试一下.

5,与Rust的其他部分不一致

当前设计还与Rust其他部分不一致.

异步FN去糖

Rust定义异步fn来去糖返回->impl Future的普通fn.因此,你想像处理此函数:

async fn process(data: &Data) { .. }

…将(大致)去糖为:

fn process(
    data: &Data
) -> impl Future<Output = ()> {
    async move {
        ..
    }
}

实际上,因为可用生命期的规则有问题,这不是实际的去糖.实际的去糖针对一个特殊的允许使用所有生命期impl Trait.

但是该形式的impl Trait并未向终端用户公开.

impl Trait中的特征

Rust2024设计

上述问题促使在Rust2024结合了两件事来用新的方法:

1,一个新的默认值,即返回位置impl Trait隐藏类型可用域中不仅是类型(仅适合Rust2024)的泛型参数;

2,一个显式声明可用哪些类型的语法.

新的显式语法"用约束":如,impl Trait+use<'x,T>表示允许隐藏类型使用'xT(但不能使用域内其他泛型参数).

现在默认可使用生命期

Rust2024中,默认是返回位置impl Trait值的隐藏类型使用域内无论是类型还是生命期泛型参数.

即在Rust2024中可很好编译这篇博文初始示例,设置玩耍地中的版本2024来试试:

fn process_data(
    data: &[Datum]
) -> impl Iterator<Item = ProcessedDatum> {
    data
        .iter()
        .map(|datum| datum.process())
}

好!

impl Trait可包含一个use<>bound来精确指定使用的泛型类型和生命期

例外是,当函数仅接受读取值且不包含在返回值中的引用参数时.一个示例是下面的indices()函数:它接受一个&[T]类型的切片,但它唯一做的是读取长度,用它来创建一个迭代器.
返回值中不需要切片自身:

fn indices<'s, T>(
    slice: &'s [T],
) -> impl Iterator<Item = usize> {
    0 .. slice.len()
}

Rust2021中,该声明隐式地表示切片没有返回类型.但在Rust2024中,默认值恰恰相反.即像此调用者停止在Rust2024中编译,因为他们现在假设直到迭代完成,数据是借用的:

fn main() {
    let mut data = vec![1, 2, 3];
    let i = indices(&data);
    data.push(4); //<-错误!<--假设访问`'&data'`
    i.next(); //
}

这实际上可能就是你想要的!即你可稍后修改indices()的定义,这样它实际上在结果中包含切片.即,新的默认值延续了impl Trait的传统,即保留在不中断调用者时,函数更改其实现灵活性.

但是,如果它不是你想要的呢?如果想保证indices()不会在其返回值中,保存参数切片的引用,你现在在返回类型中包含use<>约束来显式表示返回类型中可包含哪些泛型参数来完成.

indices()时,返回类型实际上不使用泛型,因此最好写为use<>:

fn indices<'s, T>(
    slice: &'s [T],
) -> impl Iterator<Item = usize> + use<> {
    //-----返回类型不使用`''s'或'T'`
    0 .. slice.len()
}

这与早期版本中impl Trait的限制相应,它总是必须抓类型参数.此时,可如下,避免了编译错误,但仍比必要的更保守:

fn indices<T>(
    slice: &[T],
) -> impl Iterator<Item = usize> + use<T> {
    0 .. slice.len()
}

或:'静态约束.对完全不抓引用特例,也可用'静态绑定,如下(自己试一下):

fn indices<'s, T>(
    slice: &'s [T],
) -> impl Iterator<Item = usize> + 'static {
    //-------返回类型不会抓引用.
    0 .. slice.len()
}

"此时,静态约束很方便,特别是考虑到当前use<>约束的实现限制,但use<>约束总体上更灵活.

如,编译器有一个返回newtype索引I而不是usize索引的变量,因此它包含一个use<I>声明.

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

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

相关文章

【解决】Unity TMPro字体中文显示错误/不全问题

问题描述&#xff1a;字体变成方块 原因&#xff1a;字体资源所承载的长度有限 1.找一个中文字体放入Assets中 2.选中字体创建为TMPro 字体资源 3.选中创建好的字体资源&#xff08;蓝色的大F&#xff09; 在右边的属性中找到Atlas Width h和 Atlas Heigth,修改的大一点&…

深度学习:GPT-1的MindSpore实践

GPT-1简介 GPT-1&#xff08;Generative Pre-trained Transformer&#xff09;是2018年由Open AI提出的一个结合预训练和微调的用于解决文本理解和文本生成任务的模型。它的基础是Transformer架构&#xff0c;具有如下创新点&#xff1a; NLP领域的迁移学习&#xff1a;通过最…

CKA认证 | Day2 K8s内部监控与日志

第三章 Kubernetes监控与日志 1、查看集群资源状态 在 Kubernetes 集群中&#xff0c;查看集群资源状态和组件状态是非常重要的操作。以下是一些常用的命令和解释&#xff0c;帮助你更好地管理和监控 Kubernetes 集群。 1.1 查看master组件状态 Kubernetes 的 Master 组件包…

概念解读|K8s/容器云/裸金属/云原生...这些都有什么区别?

随着容器技术的日渐成熟&#xff0c;不少企业用户都对应用系统开展了容器化改造。而在容器基础架构层面&#xff0c;很多运维人员都更熟悉虚拟化环境&#xff0c;对“容器圈”的各种概念容易混淆&#xff1a;容器就是 Kubernetes 吗&#xff1f;容器云又是什么&#xff1f;容器…

JDBC编程---Java

目录 一、数据库编程的前置 二、Java的数据库编程----JDBC 1.概念 2.JDBC编程的优点 三.导入MySQL驱动包 四、JDBC编程的实战 1.创造数据源&#xff0c;并设置数据库所在的位置&#xff0c;三条固定写法 2.建立和数据库服务器之间的连接&#xff0c;连接好了后&#xff…

移动充储机器人“小奥”的多场景应用(上)

在当前现代化城市交通体系中&#xff0c;移动充储机器人“小奥”发挥着至关重要的作用。该机器人不仅是一个简单的设备&#xff0c;而是一个集成了高科技的移动充电站&#xff0c;为新能源汽车提供了一种前所未有的便捷充电解决方案。该机器人配备了先进的电池管理系统&#xf…

element dialog会隐藏body scroll 导致tab抖动 解决方案如下

element dialog会隐藏body scroll 导致tab抖动 解决方案如下 在dialog标签添加 :lockScroll"false"搞定

Android 功耗分析(底层篇)

最近在网上发现关于功耗分析系列的文章很少&#xff0c;介绍详细的更少&#xff0c;于是便想记录总结一下功耗分析的相关知识&#xff0c;有不对的地方希望大家多指出&#xff0c;互相学习。本系列分为底层篇和上层篇。 大概从基础知识&#xff0c;测试手法&#xff0c;以及案例…

Bugku CTF_Web——my-first-sqli

Bugku CTF_Web——my-first-sqli 进入靶场 随便输一个看看 点login没有任何回显 方法一&#xff1a; 上bp抓包 放到repeter测试 试试万能密码&#xff08;靶机过期了重新开了个靶机&#xff09; admin or 11--shellmates{SQLi_goeS_BrrRrRR}方法二&#xff1a; 拿包直接梭…

BUUCTF—Reverse—easyre(1)

非常简单的逆向 拿到exe文件先查下信息&#xff0c;是一个64位程序&#xff0c;没有加壳&#xff08;壳是对代码的加密&#xff0c;起混淆保护的作用&#xff0c;一般用来阻止逆向&#xff09;。 然后拖进IDA(64位)进行反汇编 打开以后就可以看到flag flag{this_Is_a_EaSyRe}

全面击破工程级复杂缓存难题

目录 一、走进业务中的缓存 &#xff08;一&#xff09;本地缓存 &#xff08;二&#xff09;分布式缓存 二、缓存更新模式分析 &#xff08;一&#xff09;Cache Aside Pattern&#xff08;旁路缓存模式&#xff09; 读操作流程 写操作流程 流程问题思考 问题1&#…

React基础知识一

写的东西太多了&#xff0c;照成csdn文档编辑器都开始卡顿了&#xff0c;所以分篇写。 1.安装React 需要安装下面三个包。 react:react核心包 react-dom:渲染需要用到的核心包 babel:将jsx语法转换成React代码的工具。&#xff08;没使用jsx可以不装&#xff09;1.1 在html中…

Vue3中使用:deep修改element-plus的样式无效怎么办?

前言&#xff1a;当我们用 vue3 :deep() 处理 elementui 中 el-dialog_body和el-dislog__header 的时候样式一直无法生效&#xff0c;遇到这种情况怎么办&#xff1f; 解决办法&#xff1a; 1.直接在 dialog 上面增加class 我试过&#xff0c;也不起作用&#xff0c;最后用这种…

鸿蒙进阶-状态管理

大家好啊&#xff0c;这里是鸿蒙开天组&#xff0c;今天我们来学习状态管理。 开始组件化开发之后&#xff0c;如何管理组件的状态会变得尤为重要&#xff0c;咱们接下来系统的学习一下这部分的内容 状态管理机制 在声明式UI编程框架中&#xff0c;UI是程序状态的运行结果&a…

leetcode:129. 求根节点到叶节点数字之和

给你一个二叉树的根节点 root &#xff0c;树中每个节点都存放有一个 0 到 9 之间的数字。 每条从根节点到叶节点的路径都代表一个数字&#xff1a; 例如&#xff0c;从根节点到叶节点的路径 1 -> 2 -> 3 表示数字 123 。 计算从根节点到叶节点生成的 所有数字之和 。…

(南京观海微电子)——GH7006+BOE2.6_GV026WVQ-N81-1QP0_800RGB480_MIPI_LVDS_RGB原理介绍

1. 原理介绍 2. 代码 // Model - GV026WVQ-1QP0 // IC - GH7006 // Width - 800 // Height - 480 // REV: - V01 // DATA - 20240507 // INTERFACE- MIPI //"Vfp" value"16" /> //"…

速度革命:esbuild如何改变前端构建游戏 (1)

什么是 esbuild&#xff1f; esbuild 是一款基于 Go 语言开发的 JavaScript 构建打包工具&#xff0c;以其卓越的性能著称。相比传统的构建工具&#xff08;如 Webpack&#xff09;&#xff0c;esbuild 在打包速度上有着显著的优势&#xff0c;能够将打包速度提升 10 到 100 倍…

Excel的图表使用和导出准备

目的 导出Excel图表是很多软件要求的功能之一&#xff0c;那如何导出Excel图表呢&#xff1f;或者说如何使用Excel图表。 一种方法是软件生成图片&#xff0c;然后把图片写到Excel上&#xff0c;这种方式&#xff0c;因为格式种种原因&#xff0c;导出的图片不漂亮&#xff0c…

自动化运维-Linux通用性日志切割脚本

一、公司提供的参考脚本&#xff1a; #!/bin/bash # 定义需要清理的文件 log_file("/mpjava/ly.mp.dfpv.acc.biz/bin/nohup.out""/mpjava/ly.mp.dfpv.acc.service/bin/nohup.out"# 添加更多微服务的日志目录路径 ) # 获取当天日期 date_now$(date %Y%m%d)…

Let‘s Encrypt SSL证书:acmessl.cn申请免费3个月证书

目录 一、CA机构 二、Lets Encrypt特点 三、申请SSL 一、CA机构 ‌Lets Encrypt‌是一个由非营利组织Internet Security Research Group (ISRG)运营的证书颁发机构&#xff08;CA&#xff09;&#xff0c;旨在通过自动化和开放的方式为全球网站提供免费、可靠的SSL/TLS证书。…