下面是我的问题的简化/摘要版本:
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]
}
}我收到以下错误消息:
error[E0597]: borrowed value does not live long enough
--> src/main.rs:6:44
|
6 | .flat_map(|i| get_foo(i).into_iter())
| ---------- ^ temporary value dropped here while still borrowed
| |
| temporary value created here
...
10 | }
| - temporary value needs to live until here错误消息抱怨借款,但我在任何地方都使用了into_iter,据我所知,它获得了迭代值的所有权。我希望获得从get_foo返回的值的所有权,并将其元素插入到foos中。我怎么能这么做?
发布于 2017-08-27 14:26:59
如何在flat_map中获取值的所有权
flat_map在这里没有什么特别之处。调用get_foo时,返回值的所有权将传递给调用方,就像Rust中的其他任何地方一样。
我在任何地方都使用过into_iter,据我所知,它拥有迭代值的所有权。
通常,是的,但不是一个数组。有关原因,请参阅下面的相关问题。这就是问题的根源。flat_map闭包拥有get_foo的结果,然后引用它。引用不能存在于闭包之外,但这正是您所要求的。
作为解决办法,您可以从函数返回一个Vec:
fn get_foo(i: u8) -> Vec<u8> {
if i % 2 == 0 {
vec![1, 2, 3]
} else {
vec![4, 5, 6]
}
}还可以将返回的数组转换为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
}
}
}并将其用作.flat_map(|i| CloneArrayIter::new(get_foo(i)))
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()
}另请参阅:
https://stackoverflow.com/questions/45904760
复制相似问题