无法从泛型函数中的引用构造(值的寿命不够长)
Cannot construct from a reference in a generic function (value does not live long enough)
我有一个方法接受一些参数,从中创建(解密)一个中间值并尝试从该中间值构造一个类型实例。只要类型是固定的,这就可以正常工作。如果我想通过泛型支持多种类型,我 运行 就会遇到麻烦。这是缩小的代码:
impl Factory
{
pub fn get<'a, T>(&'a self, value: &'a str) -> T
where T: From<&'a str>
{
let value_parsed = value.chars().rev().collect::<String>();
return T::from(&value_parsed);
}
}
您可以 运行 完整代码 here。编译产生以下错误:
31 | pub fn get<'a, T>(&'a self, value: &'a str) -> T
| -- lifetime `'a` defined here
...
35 | return T::from(&value_parsed);
| --------^^^^^^^^^^^^^-
| | |
| | borrowed value does not live long enough
| argument requires that `value_parsed` is borrowed for `'a`
36 | }
| - `value_parsed` dropped here while still borrowed
正如我所说,在方法签名中使用 Item
而不是泛型类型可以消除此错误。不传递对 T::from()
的引用,而是移动临时值也是一个选项,但考虑到 value_parsed
实际上并没有在这里被消耗,这没有什么意义,它变得尴尬并且与我的其余部分不一致代码库。
有什么方法可以确保 value_parsed
活得足够长?或者除了不使用引用之外还有其他解决方案吗?
原来在这里使用我自己的特征是有效的,它不需要我在签名中指定对类型的引用——因此不需要将生命周期与特征相关联:
trait Get<T>
{
fn get(value: &T) -> Self;
}
使用这个特征,方法可以编译:
pub fn get<'a, T>(&'a self, value: &'a str) -> T
where T: Get<String>
{
let value_parsed = value.chars().rev().collect::<String>();
return T::get(&value_parsed);
}
我不确定这是否是最佳解决方案,但这个解决方案有效。
您可以使用 higher-rank trait bound 来指示类型 T
可以由具有 any 生命周期的值构成,而不是 specific 在函数上用作泛型时的生命周期:
pub fn get<T>(&self, value: &str) -> T
where T: for<'a> From<&'a str>
// ^^^^^^^
您之前的内容表明 T
可以根据生命周期基于 self
和 value
的引用构建,但是,因为 value_parsed
是一个局部变量,对它的引用不能满足该生命周期约束。
我有一个方法接受一些参数,从中创建(解密)一个中间值并尝试从该中间值构造一个类型实例。只要类型是固定的,这就可以正常工作。如果我想通过泛型支持多种类型,我 运行 就会遇到麻烦。这是缩小的代码:
impl Factory
{
pub fn get<'a, T>(&'a self, value: &'a str) -> T
where T: From<&'a str>
{
let value_parsed = value.chars().rev().collect::<String>();
return T::from(&value_parsed);
}
}
您可以 运行 完整代码 here。编译产生以下错误:
31 | pub fn get<'a, T>(&'a self, value: &'a str) -> T
| -- lifetime `'a` defined here
...
35 | return T::from(&value_parsed);
| --------^^^^^^^^^^^^^-
| | |
| | borrowed value does not live long enough
| argument requires that `value_parsed` is borrowed for `'a`
36 | }
| - `value_parsed` dropped here while still borrowed
正如我所说,在方法签名中使用 Item
而不是泛型类型可以消除此错误。不传递对 T::from()
的引用,而是移动临时值也是一个选项,但考虑到 value_parsed
实际上并没有在这里被消耗,这没有什么意义,它变得尴尬并且与我的其余部分不一致代码库。
有什么方法可以确保 value_parsed
活得足够长?或者除了不使用引用之外还有其他解决方案吗?
原来在这里使用我自己的特征是有效的,它不需要我在签名中指定对类型的引用——因此不需要将生命周期与特征相关联:
trait Get<T>
{
fn get(value: &T) -> Self;
}
使用这个特征,方法可以编译:
pub fn get<'a, T>(&'a self, value: &'a str) -> T
where T: Get<String>
{
let value_parsed = value.chars().rev().collect::<String>();
return T::get(&value_parsed);
}
我不确定这是否是最佳解决方案,但这个解决方案有效。
您可以使用 higher-rank trait bound 来指示类型 T
可以由具有 any 生命周期的值构成,而不是 specific 在函数上用作泛型时的生命周期:
pub fn get<T>(&self, value: &str) -> T
where T: for<'a> From<&'a str>
// ^^^^^^^
您之前的内容表明 T
可以根据生命周期基于 self
和 value
的引用构建,但是,因为 value_parsed
是一个局部变量,对它的引用不能满足该生命周期约束。