gpt4 book ai didi

rust - 用于存储具有不同通用参数的结构的特征

转载 作者:行者123 更新时间:2023-11-29 08:00:38 26 4
gpt4 key购买 nike

我需要存储相同结构的相同 Vec 实例,但具有不同的通用参数。这是结构定义:

struct Struct<'a, T: 'a> {
items: Vec<&'a T>
}

该结构有一个方法将迭代器返回到不依赖于泛型类型参数 T 的类型:

impl<'a, T: 'a> Struct<'a, T> {
fn iter(&self) -> slice::Iter<&i32> {
unimplemented!()
}
}

我需要为向量中的那些不同结构访问这个方法,所以我实现了这个特性:

type Iter<'a> = Iterator<Item=&'a i32>;

trait Trait {
fn iter(&self) -> Box<Iter>;
}

我已经为 Struct 实现了特性:

impl<'a, T: 'a> Trait for Struct<'a, T> {
fn iter(&self) -> Box<Iter> {
Box::new(self.iter())
}
}

但是编译器提示:

<anon>:21:9: 21:30 error: type mismatch resolving `<core::slice::Iter<'_, &i32> as core::iter::Iterator>::Item == &i32`:
expected &-ptr,
found i32 [E0271]
<anon>:21 Box::new(self.iter())
^~~~~~~~~~~~~~~~~~~~~
<anon>:21:9: 21:30 help: see the detailed explanation for E0271
<anon>:21:9: 21:30 note: required for the cast to the object type `core::iter::Iterator<Item=&i32> + 'static`
<anon>:21 Box::new(self.iter())
^~~~~~~~~~~~~~~~~~~~~

我已经为特征中的生命周期参数尝试了不同的可能性,但它们都不起作用。我怎样才能使它工作?

Rust Playground snippet

编辑

正如@MatthieuM 所指出的。一个问题是类型别名不能正常工作。这是证明这一点的另一个例子:

use std::slice;

type Iter<'a> = Iterator<Item=&'a i32>;

struct Struct<'a> { _phantom: std::marker::PhantomData<&'a i32> }

impl<'a> Struct<'a> {
fn direct<'b>(i: &'b slice::Iter<'a, i32>) -> &'b Iterator<Item=&'a i32>
{ i }

fn aliased<'b>(i: &'b slice::Iter<'a, i32>) -> &'b Iter<'a>
{ i }
}

在此示例中,direct 编译,但 aliased 未编译,错误为:

<anon>:12:7: 12:8 error: the type `core::slice::Iter<'a, i32>` does not fulfill the required lifetime
<anon>:12 { i }
^
note: type must outlive the static lifetime

但它们似乎是一回事。发生了什么事?

最佳答案

问题 1 — slice::Iter<T>有一个 Iterator::Item&T ,因此您的引用水平不匹配。改变你的方法是

fn iter(&self) -> slice::Iter<i32>

问题 2 — Box<SomeTrait>相当于Box<SomeTrait + 'static> ,但您的迭代器不适用于 'static生命周期。你需要明确地引入生命周期:

Box<SomeTrait + 'a>

问题 3 — 我不明白如何为特征创建类型别名,这看起来很奇怪。无论如何你可能都不想要它。相反,为整个盒装版本创建一个类型别名:

type IterBox<'a> = Box<Iterator<Item=&'a i32> + 'a>;

问题 4 — 重新排列您的 main这样引用就会存在足够长的时间并增加可变性:

fn main() {
let i = 3;
let v = vec![&i];
let mut traits : Vec<Box<Trait>> = Vec::new();
traits.push(Box::new(Struct{ items: v }));
}

一起:

use std::slice;

type IterBox<'a> = Box<Iterator<Item=&'a i32> + 'a>;

trait Trait {
fn iter<'a>(&'a self) -> IterBox;
}

struct Struct<'a, T: 'a> {
items: Vec<&'a T>
}

impl<'a, T: 'a> Struct<'a, T> {
fn iter(&self) -> slice::Iter<i32> {
unimplemented!()
}
}

impl<'a, T: 'a> Trait for Struct<'a, T> {
fn iter(&self) -> IterBox {
Box::new(self.iter())
}
}

fn main() {
let i = 3;
let v = vec![&i];
let mut traits: Vec<Box<Trait>> = Vec::new();
traits.push(Box::new(Struct { items: v }));
}

关于rust - 用于存储具有不同通用参数的结构的特征,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32882108/

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