在函数体上迭代具有生命周期的通用值时,借用值的寿命不够长
Borrowed value does not live long enough when iterating over a generic value with a lifetime on the function body
fn func<'a, T>(arg: Vec<Box<T>>)
where
String: From<&'a T>,
T: 'a,
{
let s: Vec<String> = arg.iter().map(|s| String::from(s)).collect();
do_something_else(arg);
}
fn do_something_else<T>(arg: Vec<Box<T>>) {}
编译器抱怨 arg
活得不够长。为什么呢?
error[E0597]: `arg` does not live long enough
--> src/lib.rs:6:26
|
6 | let s: Vec<String> = arg.iter().map(|s| String::from(s)).collect();
| ^^^ borrowed value does not live long enough
7 | do_something_else(arg);
8 | }
| - borrowed value only lives until here
|
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 1:9...
--> src/lib.rs:1:9
|
1 | fn func<'a, T>(arg: Vec<Box<T>>)
| ^^
约束 String: From<&'a T>
,强调函数的生命周期参数 'a
,将允许您将对 T
的引用转换为 String
。但是,对从迭代器 获得的元素的引用比 'a
更具限制性(因此,它们的寿命不够长)。
由于转换应该适用于任何生命周期的引用,您可以用更高等级的特征边界 (HRTB) 替换约束:
fn func<T>(arg: Vec<Box<T>>)
where
for<'a> String: From<&'a T>,
{
let s: Vec<String> = arg.iter().map(|s| String::from(s)).collect();
do_something_else(arg);
}
这里使用 From
来获取拥有的字符串也是我从未见过的。也许您会对 Display
特征感兴趣,这样您就可以调用 to_string()
:
fn func<T>(arg: Vec<Box<T>>)
where
T: Display,
{
let _: Vec<_> = arg.iter().map(|s| s.to_string()).collect();
// ...
}
另请参阅:
fn func<'a, T>(arg: Vec<Box<T>>)
where
String: From<&'a T>,
T: 'a,
{
let s: Vec<String> = arg.iter().map(|s| String::from(s)).collect();
do_something_else(arg);
}
fn do_something_else<T>(arg: Vec<Box<T>>) {}
编译器抱怨 arg
活得不够长。为什么呢?
error[E0597]: `arg` does not live long enough
--> src/lib.rs:6:26
|
6 | let s: Vec<String> = arg.iter().map(|s| String::from(s)).collect();
| ^^^ borrowed value does not live long enough
7 | do_something_else(arg);
8 | }
| - borrowed value only lives until here
|
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 1:9...
--> src/lib.rs:1:9
|
1 | fn func<'a, T>(arg: Vec<Box<T>>)
| ^^
约束 String: From<&'a T>
,强调函数的生命周期参数 'a
,将允许您将对 T
的引用转换为 String
。但是,对从迭代器 获得的元素的引用比 'a
更具限制性(因此,它们的寿命不够长)。
由于转换应该适用于任何生命周期的引用,您可以用更高等级的特征边界 (HRTB) 替换约束:
fn func<T>(arg: Vec<Box<T>>)
where
for<'a> String: From<&'a T>,
{
let s: Vec<String> = arg.iter().map(|s| String::from(s)).collect();
do_something_else(arg);
}
这里使用 From
来获取拥有的字符串也是我从未见过的。也许您会对 Display
特征感兴趣,这样您就可以调用 to_string()
:
fn func<T>(arg: Vec<Box<T>>)
where
T: Display,
{
let _: Vec<_> = arg.iter().map(|s| s.to_string()).collect();
// ...
}
另请参阅: