以下是我的问题的简化/摘要版本:
fn main() {
let foo_selectors = vec![0, 1];
let foos: Vec<_> = foo_selectors
.into_iter()
.flat_map(|i| get_foo(i).into_iter())
.collect();
println!("{:?}", foos);
}
fn get_foo(i: u8) -> [u8; 3] {
if i % 2 == 0 {
[1, 2, 3]
} else {
[4, 5, 6]
}
}
Run Code Online (Sandbox Code Playgroud)
我收到以下错误消息:
fn main() {
let foo_selectors = vec![0, 1];
let foos: Vec<_> = foo_selectors
.into_iter()
.flat_map(|i| get_foo(i).into_iter())
.collect();
println!("{:?}", foos);
}
fn get_foo(i: u8) -> [u8; 3] {
if i % 2 == 0 {
[1, 2, 3]
} else {
[4, 5, 6]
}
}
Run Code Online (Sandbox Code Playgroud)
该错误消息抱怨借用,但是into_iter
据我所知,我已经在很多地方使用了迭代值的所有权。我想拥有从返回的值的所有权get_foo
并将其元素插入foos
。我怎样才能做到这一点?
如何在Flat_map中获取值的所有权
这里没有什么特别的flat_map
。调用时get_foo
,返回值的所有权会转移到调用方,就像Rust中的其他任何地方一样。
据我所知,我到处都使用过in_iter,它拥有迭代值的所有权。
通常,是的,但不是数组。有关原因,请参见下面的链接问题。这是问题的根源。该flat_map
闭包拥有的结果get_foo
,然后您对其进行引用。该引用不能超出闭包,但这就是您要执行的操作。
解决方法是,您可以Vec
从函数中返回a :
fn get_foo(i: u8) -> Vec<u8> {
if i % 2 == 0 {
vec![1, 2, 3]
} else {
vec![4, 5, 6]
}
}
Run Code Online (Sandbox Code Playgroud)
您也可以将返回的数组转换为调用Vec
内部flat_map
。
如果您认为情况允许,可以实现自己的迭代器:
struct CloneArrayIter<T> {
arr: [T; 3],
idx: usize,
}
impl<T> CloneArrayIter<T> {
fn new(arr: [T; 3]) -> Self {
Self { arr, idx: 0 }
}
}
impl<T> Iterator for CloneArrayIter<T>
where
T: Clone,
{
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
if self.idx < 3 {
let value = self.arr[self.idx].clone();
self.idx += 1;
Some(value)
} else {
None
}
}
}
Run Code Online (Sandbox Code Playgroud)
并用作 .flat_map(|i| CloneArrayIter::new(get_foo(i)))
我可能只使用ArrayVec
from arrayvec:
extern crate arrayvec;
use arrayvec::ArrayVec;
fn main() {
let foo_selectors = vec![0, 1];
let foos: Vec<_> = foo_selectors
.into_iter()
.flat_map(|i| get_foo(i))
.collect();
println!("{:?}", foos);
}
fn get_foo(i: u8) -> ArrayVec<[u8; 3]> {
if i % 2 == 0 { [1, 2, 3] } else { [4, 5, 6] }.into()
}
Run Code Online (Sandbox Code Playgroud)
也可以看看:
归档时间: |
|
查看次数: |
448 次 |
最近记录: |