trait FromValue<'a> {
fn from_value(value: &'a str) -> Self;
}
impl<'a> FromValue<'a> for String {
fn from_value(value: &'a str) -> Self {
value.into()
}
}
我创建一个FromValue<'a>
这样的trait,带有一个生命周期变量。
struct Value;
impl Value {
fn get<'a, T>(&'a self) -> T where T: FromValue<'a> {
T::from_value("hello")
}
}
创建一个空struct,作用去调用from_value
,即使self
并不需要。
最后,我创建了几个函数,再去调用这个get
:
// 编译通过
fn try_get1<'a, T>() -> T where T: FromValue<'a> {
Value.get()
}
// 编译通过
fn try_get2() -> String {
let value = Value;
value.get()
}
// 编译失败,遇到生命周期问题,提示value不够长久
fn try_get3<'a, T>() -> T where T: FromValue<'a> {
let value = Value;
value.get()
}
它们作用都是调用Value.get
,为什么只有try_get3
失败了,value.get()
不是应该会得带有所有权的返回值的吗?
感谢不吝赐教。
Ext Link: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=ae65e5d97ebdf0d19474b72e204481ac
1
共 2 条评论, 1 页
评论区
写评论太感谢了,真是醍醐灌顶。
我还是太年轻,见笑了;看来需要提高一下知识水平。
为什么只有 try_get3 失败了?
因为约束了返回值 T 需要和 self 一样长的生命周期,所以
当你把 &'a self 的约束放宽成 &self:
try_get3 可以通过编译。因为 try_get3 相当于返回具有 'static 生命周期的数据:
为什么 try_get1 两种情况下都可以通过?
因为这是有效的:
即 Value 作为返回值,其引用的生命周期是 'static 的,而
Value.get()
的实际形式为(&Value).get()
,所以纠正几个小问题
一、生命周期“变量”的说法是从何而来?只有生命周期、生命周期参数、生命周期注解、lifetime bounds 这些术语,而 “变量” 的概念是很明确的。
二、“value.get() 不是应该会得带有所有权的返回值的吗?” —— 不一定。因为
T: FromValue<'a>
,该 trait bound 没有限定必须为引用(泛型 T 可以是引用或者非引用类型),当你有以下实现时:你的例子一样可以运行
Edit: playground