reference - 如何从 &Vec 中创建 &T 的迭代器还是 Vec<&T>?
问题描述
我有一个有两个变体的枚举。它要么包含Vec
对String
s的引用,要么包含对 sVec
的引用String
:
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);
}
}
&Vec<T>
在and上实现这种抽象的惯用方法是什么Vec<&T>
?get_items
也可能返回不同的东西,只要它实现了IntoIterator
特征,以便我可以在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);
}
}
推荐阅读
- javascript - JavaScript 中模块的执行上下文是什么?如何在浏览器的控制台中显式访问它?
- python - 通过 SQL Server 代理作业在 Conda 中使用 Numpy 运行 python 脚本
- sql - 来自 SQL 源的 BIT 列由数据收集器转换为布尔值
- css - Material-UI Grid - 自动堆叠项目以占用最小垂直空间
- pandas - Pandas - 在不复制数据的情况下计算行数
- css - 2021 年 CSS 动画最佳实践是什么,以确保与所有浏览器兼容?
- swift - iOS 14 TableViewCell 无法设置选定的背景颜色
- arrays - 无法访问 Julia 数组(BoundsError:尝试访问索引 [1] 处的 0 元素 Vector{Int64})
- php - 通过不处理存在数据透视表的查询来排序 laravel 8
- php - 在查询中获取 ACF 后元值