如何在关联类型中指定生命周期参数?

2023-12-02

我有这个特点和简单的结构:

use std::path::{Path, PathBuf};

trait Foo {
    type Item: AsRef<Path>;
    type Iter: Iterator<Item = Self::Item>;

    fn get(&self) -> Self::Iter;
}

struct Bar {
    v: Vec<PathBuf>,
}

我想实施Foo特质为Bar:

impl Foo for Bar {
    type Item = PathBuf;
    type Iter = std::slice::Iter<PathBuf>;

    fn get(&self) -> Self::Iter {
        self.v.iter()
    }
}

但是我收到这个错误:

error[E0106]: missing lifetime specifier
  --> src/main.rs:16:17
   |
16 |     type Iter = std::slice::Iter<PathBuf>;
   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^ expected lifetime parameter

我发现无法指定关联类型内的生命周期。我特别想表达的是,迭代器的寿命不能超过self寿命。

我该如何修改Foo特质,或Bar特质实施,使这项工作有效?

铁锈游乐场


您的问题有两种解决方案。让我们从最简单的开始:

为你的特质增添一生

trait Foo<'a> {
    type Item: AsRef<Path>;
    type Iter: Iterator<Item = Self::Item>;
    
    fn get(&'a self) -> Self::Iter;
}

这要求您在使用该特征的任何地方都注释生命周期。当您实现该特征时,您需要进行通用实现:

impl<'a> Foo<'a> for Bar {
    type Item = &'a PathBuf;
    type Iter = std::slice::Iter<'a, PathBuf>;
    
    fn get(&'a self) -> Self::Iter {
        self.v.iter()
    }
}

当您需要通用参数的特征时,您还需要确保对特征对象的任何引用都具有相同的生命周期:

fn fooget<'a, T: Foo<'a>>(foo: &'a T) {}

实现对您的类型的引用的特征

不要为您的类型实现该特征,而是为了对您的类型的引用而实现它。该特质永远不需要以这种方式了解有关生命周期的任何信息。

然后,特征函数必须按值获取其参数。在您的情况下,您将实现该特征以供参考:

trait Foo {
    type Item: AsRef<Path>;
    type Iter: Iterator<Item = Self::Item>;
    
    fn get(self) -> Self::Iter;
}

impl<'a> Foo for &'a Bar {
    type Item = &'a PathBuf;
    type Iter = std::slice::Iter<'a, PathBuf>;
    
    fn get(self) -> Self::Iter {
        self.v.iter()
    }
}

Your fooget函数现在简单地变成

fn fooget<T: Foo>(foo: T) {}

这样做的问题是fooget函数不知道T实际上是一个&Bar。当您致电get函数,你实际上是从foo多变的。您无需移出对象,只需移动参考即可。如果你的fooget函数尝试调用get两次,该函数将无法编译。

如果你想要你的fooget函数只接受参数,其中FooTrait 是为了引用而实现的,您需要显式地声明这个边界:

fn fooget_twice<'a, T>(foo: &'a T)
where
    &'a T: Foo,
{}

The where子句确保您仅在引用时调用此函数Foo是为了参考而不是类型而实现的。也可以对两者实施。

从技术上讲,编译器可以自动推断生命周期fooget_twice所以你可以把它写成

fn fooget_twice<T>(foo: &T)
where
    &T: Foo,
{}

但它还不够聪明yet.


对于更复杂的情况,您可以使用尚未实现的 Rust 功能:通用关联类型(服务贸易总协定)。为此所做的工作正在被跟踪问题 44265.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在关联类型中指定生命周期参数? 的相关文章

随机推荐

  • 并行 ForEach 与 SQL 插入 C#

    我有一个如下所示的对象 但数据量很大 我们观察到插入到我们的 SQL 数据库中需要很长时间 因为我们使用普通的foreach 主要思想是插入每个部门并获取生成的身份号码 然后插入分配有该部门 ID 的嵌套员工
  • 按行删除每行列子集中的重复项,按行仅保留第一个副本

    我有以下 pandas 数据框 超过 700 万行 import pandas as pd data date 2023 02 22 2023 02 21 2023 02 23 x1 descx1a descx1b descx1c x2 A
  • angular2firebase - 使用 Angular 6 的多个实例

    我正在升级到Angular 6 using AngularFire2 我的应用程序引用了 2Firebase项目使用这样的代码来创建数据库引用 public initFirebaseApp config FirebaseAppConfig
  • 寻找实时网络服务器分析包[关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 目前不接受答案 我是一家县医院教育科的程序员 我希望能够在只能在内部访问的 IIS6 Web 服务器上查看一些实时统计数据 我正在寻找类似于 1and1 com 为
  • 圆角包含在小分区中的大图像的侧面在 Chrome 中不起作用

    我正在尝试用圆角化背景图像的侧面border radius财产 这是我的场景 我将一个大图像放在一个小分区中作为背景 并将溢出隐藏起来 现在我需要对小部门进行四舍五入 我成功绕过了小师 但图像的角不是圆角的 HTML div class v
  • 如何自动调整 iFrame 的大小? [复制]

    这个问题在这里已经有答案了 可能的重复 根据内容调整 iframe 的大小 我正在加载 iFrame 并希望父级根据 iFrame 内容的高度自动更改高度 简而言之 所有页面都属于同一域 因此我不应该遇到跨站点脚本问题 在任何其他元素上 我
  • Keras - 绘制训练、验证和测试集准确性

    我想绘制这个简单神经网络的输出 model compile loss binary crossentropy optimizer adam metrics accuracy history model fit x test y test n
  • 使用node-csv和meteor-file将CSV导入到集合中

    现在已经挣扎了几个小时 尝试导入从客户端上传的 CSV流星文件并使用转换为 CSVnode csv服务器端 我基本上需要用用户上传的 CSV 文件中的数据填充我的集合 server filehandler js Meteor methods
  • 如何克隆包含装箱特征对象的 HashMap?

    I have HashMap使用自定义哈希器 这个的项目HashMap没有实现特征Clone 这是一个特征 但是有一个克隆项目的功能 如下所示 use std collections HashMap use std hash BuildHa
  • 使用 std::unique_ptr/std::shared_ptr 确认线程安全

    我的应用程序有一个 IRC 模块 本质上是一个普通的客户端 由于这是高度线程化的 因此我面临插件检索的风险 例如 用户昵称 它当时有效 但解析器触发更新 更改所述昵称 一旦另一个线程再次执行 它就会处理指向现在无效内存的指针 因为不可能将
  • 如何将 SPListitem 从一个 SPList 复制到另一个 SPList

    我需要将项目从一个 SPList 复制到另一个 这是不起作用的代码 public void CopyList SPList src Copy items from source List to Destination List foreac
  • 使用 Google 地图 API 进行标记的路线

    因此 我正在使用 Google Maps API 目前我有一个自定义标记来突出显示该位置 如果可能的话 我想做的是能够单击它并让它弹出谷歌地图方向对话框 例如THIS 通常在谷歌地图上点击地名时会得到 目前 我刚刚将其设置为放大标记 但显然
  • 从 Windows 服务更新 ASP.Net 成员资格

    我正在为一家物业管理公司做一个项目 有存储所有租户和物业组合的后端系统 以及允许用户查看其套餐 服务请求等的前端网站 我需要编写一个 Windows 服务 从后端提取他们的信息并将其放入会员数据库中 我不知道如何配置服务以连接到会员提供商
  • Qt 嵌入应用程序内的屏幕旋转

    在我们的目标设备中 我们使用 qws 参数运行 QtE 应用程序 要旋转屏幕 我们指定 display Transformed rot90 作为应用程序参数 效果很好 但是 我们有一个在应用程序内旋转屏幕的功能 因此我们尝试 QScreen
  • 文字函数的隐式参数

    边读边玩 框架文档 我遇到了这个片段 def index Action implicit request gt session get connected map user gt Ok Hello user getOrElse Unauth
  • 如何以编程方式重新配置 uima ruta 分析引擎(更改参数值)?

    这是问题的延续 如何从 Maven 项目运行外部 ruta 脚本而不将脚本或其类型系统放在类路径中 请指导我以编程方式重新配置分析引擎 通过更改参数值 情况 您有一个 UIMA Ruta 分析引擎的正确 xml 描述符 并且您想要重新配置
  • 如何重置 VSTS 计数器?

    我们需要重置 VSTS 计数器 我没有看到任何方法可以通过用户界面来做到这一点 有一种方法可以直接调用重置构建计数器REST API 但为了做到这一点 您需要知道计数器 id 您应该能够通过调用找到它得到一个定义休息 API 不幸的是 无论
  • 波浪号的意义

    string path context Server MapPath Temp or string path context Server MapPath Temp 一样吗 我知道 代表根 但想知道两者之间的区别 folder and fo
  • 将 y 轴转换为百分比 ggplot

    我使用堆积条形图 带有 coord flip 来尝试比较对照组和治疗组在测试前和测试后的分布 这是我正在使用的几种技术之一 这是情节 这是代码 抱歉 没有数据集就无法重现 如果这是一个问题 我将制作一个可重现的数据集 因为我无法共享真实数据
  • 如何在关联类型中指定生命周期参数?

    我有这个特点和简单的结构 use std path Path PathBuf trait Foo type Item AsRef