gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-29 08:20:51 25 4
gpt4 key购买 nike

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

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>,
}

我想为 Bar 实现 Foo 特性:

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 特征实现,才能使其正常工作?

Rust playground

最佳答案

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

为你的特质添加一生

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 函数必须按值获取它的参数。在您的情况下,您将实现该特征以供引用:

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()
}
}

你的 fooget 函数现在变成了

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

问题在于 fooget 函数不知道 T 实际上是一个 &Bar。当您调用get 函数时,您实际上是在移出foo 变量。您不会移出对象,只需移动引用即可。如果您的 fooget 函数尝试调用 get 两次,该函数将无法编译。

如果您希望您的 fooget 函数只接受为引用实现了 Foo 特性的参数,您需要明确声明此绑定(bind):

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

where 子句确保您只为引用调用此函数,其中为引用而不是类型实现了 Foo。它也可以为两者实现。

从技术上讲,编译器可以自动推断 fooget_twice 中的生命周期,因此您可以将其写为

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

但它不够聪明yet .


对于更复杂的情况,您可以使用尚未实现的 Rust 功能:Generic Associated Types (服务贸易协定)。在 issue 44265 中跟踪为此所做的工作.

关于rust - 如何在关联类型中指定生命周期参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48461886/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com