无法从泛型函数中的引用构造(值的寿命不够长)

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 可以根据生命周期基于 selfvalue 的引用构建,但是,因为 value_parsed 是一个局部变量,对它的引用不能满足该生命周期约束。