rust - 我如何绑定(bind) Higher Rank Trait Bound 生命周期?

标签 rust

我有一个迭代器特征,它使用通用关联类型来允许返回值引用迭代器拥有的数据:

pub trait MyIterator {
    type T<'a>
    where
        Self: 'a;

    fn next<'b>(&'b mut self) -> Option<Self::T<'b>>;
}

一个示例实现如下所示:

struct FooIterator<'counter> {
    data: Vec<String>,
    counter: &'counter AtomicU32,
    index: usize
}

impl<'counter> MyIterator for FooIterator<'counter> {
    type T<'d> = &'d str
    where
        Self: 'd;
    
    fn next<'e>(&'e mut self) -> Option<Self::T<'e>> {
        self.counter.fetch_add(1, Ordering::SeqCst);
        self.index += 1;
        Some(&self.data[self.index])
    }
}

现在,我想要一个返回 impl MyIterator 对象而不公开实现类型的工厂。但是,我不知道如何写生命周期。

我的第一次尝试是:

struct Factory {
    data: Vec<String>,
    counter: AtomicU32,
}

impl Factory {
    fn new() -> Self {
        Factory {
            data: vec!["a".to_string(), "b".to_string(), "c".to_string(), "d".to_string()],
            counter: AtomicU32::new(0),
        }
    }
    
    fn create<'f>(&'f self) -> impl MyIterator<T<'_> = &'_ str> {
        FooIterator {
            data: self.data.clone(),
            counter: &self.counter,
            index: 0
        }
    }
}

但是,这会在尝试使用返回的迭代器时导致双重借用错误,如下所示:https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=6490de8f21539537764d8f628454c5c1

接下来我尝试使用 Higher Rank Trait Bound,这似乎应该有效,但我无法编译以下内容,因为 'g 似乎不在范围内where 子句 ( https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=beb46184de6f96bf83b64e838da4a335 ):

fn create<'f>(&'f self) -> impl for<'g> MyIterator<T<'g> = &'g str> + 'f where 'f: 'g {
    FooIterator {
        data: self.data.clone(),
        counter: &self.counter,
        index: 0
    }
}

没有返回 impl MyIterator 代码工作正常,但我不想公开 FooIterator 类型。看到这个 Playground :https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=2c595c136077791a692ea6e0a41c057c

最佳答案

您的问题出在 MyIterator 定义中,因为 next 函数对自身进行可变借用并返回与该可变借用一样长的东西,即不是您对迭代器的期望。

这很微妙,因为它不会使代码变得不可靠,它只会强制执行过多的约束,这反过来又导致无法在不出错的情况下使用该特征。对 MyIterator 特征中的生命周期进行简单的重构使其工作。 See the playground .

关于rust - 我如何绑定(bind) Higher Rank Trait Bound 生命周期?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72065426/

相关文章:

rust - 如何获得与Rust HashMap的最大值关联的 key ?

rust - 我怎样才能让编译器警告我标记为 pub 的未使用代码?

postgresql - 如何将 HashMap 作为 JSON 类型插入到 PostgreSQL 中?

rust - 有条件地将命令的标准输出转换为字符串的时间不够长

rust - 如何在 Cargo.toml 中启用每个平台的 crate 功能?

python - 如何修复传递 int 数组时的段错误?

rust - 我的变量的生命周期是否由于添加了明显不相关的指令而发生变化?

rust - 从 String 到 *const i8 的正确方法是什么?

java - 将枚举类型从 Rust 转换为 Java

reference - 如何使用 Rust 对树结构中的单个节点进行多个引用