gpt4 book ai didi

reference - 如何从 &Vec 或 Vec<&T> 创建 &T 的迭代器?

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

我有一个有两个变体的枚举。它要么包含对 Vec 的引用的 String s 或者它包含一个 VecString 的引用小号:

enum Foo<'a> {
Owned(&'a Vec<String>),
Refs(Vec<&'a String>),
}

我想遍历对 String 的引用s 在这个枚举中。

我试图在 Foo 上实现一个方法,但不知道如何让它返回正确的迭代器:

impl<'a> Foo<'a> {
fn get_items(&self) -> Iter<'a, String> {
match self {
Foo::Owned(v) => v.into_iter(),
Foo::Refs(v) => /* what to put here? */,
}
}
}

fn main() {
let test: Vec<String> = vec!["a".to_owned(), "b".to_owned()];
let foo = Foo::Owned(&test);

for item in foo.get_items() {
// item should be of type &String here
println!("{:?}", item);
}
}

playground

通过 &Vec<T> 实现这种抽象的惯用方法是什么?和 Vec<&T>get_items也可能返回不同的东西,只要它实现了 IntoIterator。 trait 以便我可以在 for 中使用它循环。

最佳答案

您不能为此只使用 std::slice::Iter 类型。

如果您不想复制字符串或向量,则必须实现自己的迭代器,例如:

struct FooIter<'a, 'b> {
idx: usize,
foo: &'b Foo<'a>,
}

impl<'a, 'b> Iterator for FooIter<'a, 'b> {
type Item = &'a String;
fn next(&mut self) -> Option<Self::Item> {
self.idx += 1;
match self.foo {
Foo::Owned(v) => v.get(self.idx - 1),
Foo::Refs(v) => v.get(self.idx - 1).map(|s| *s),
}
}
}

impl<'a, 'b> Foo<'a> {
fn get_items(&'b self) -> FooIter<'a, 'b> {
FooIter { idx: 0, foo: self }
}
}

fn main() {
let test: Vec<String> = vec!["a".to_owned(), "b".to_owned()];
let foo = Foo::Owned(&test);
for item in foo.get_items() {
println!("{:?}", item);
}
let a = "a".to_string();
let b = "b".to_string();
let test: Vec<&String> = vec![&a, &b];
let foo = Foo::Refs(test);
for item in foo.get_items() {
println!("{:?}", item);
}
}

关于reference - 如何从 &Vec<T> 或 Vec<&T> 创建 &T 的迭代器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58049711/

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