本文介绍了通用函数中的 Rust Lifetime 问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的函数,我想在 Rust 中使其通用.我收到了终生错误.我仍然掌握生锈的终生一面.

I have a simple function that I want to make generic, in rust. I am getting a lifetime error. I am still getting the hang of the lifetime side of rust.

该函数只是使用 serde 的序列化将 1 个结构体转换为另一个结构体.

The function simply converts 1 struct into another using serde's serialization.

这里是一个 rust playground/a> 完整的简单场景.

Here is a a rust playground with the full simple scenario.

代码:

pub fn convert<'de: 'a, 'a, T>(from: &'a Left, print: bool) -> (T, &'a Left)
where
    T: Deserialize<'de> + std::fmt::Debug {

    let serialized = serde_json::to_string(&from);
    let serialized = serialized.unwrap();
    let deserialized: T;
    {
    let deserialized_raw = serde_json::from_str(&serialized);
    deserialized = deserialized_raw.unwrap();
    }
    if print {
        println!("-------------A-----------------------------------");
        println!("serialized = {}", &serialized);
        println!("--------------B----------------------------------");
        println!("deserialized = {:?}", deserialized);
        println!("--------------C----------------------------------");
    };
    (deserialized, from)
}

错误:

error[E0597]: `serialized` does not live long enough
  --> src/main.rs:38:49
   |
30 | pub fn convert<'de: 'a, 'a, T>(from: &'a Left, print: bool) -> (T, &'a Left)
   |                --- lifetime `'de` defined here
...
38 |     let deserialized_raw = serde_json::from_str(&serialized);
   |                            ---------------------^^^^^^^^^^^-
   |                            |                    |
   |                            |                    borrowed value does not live long enough
   |                            argument requires that `serialized` is borrowed for `'de`
...
49 | }
   | - `serialized` dropped here while still borrowed

我尝试了几种有无生命周期的方法.我尝试添加块,看看这是否会改变事情而没有运气.

I tried this a few ways with and without lifetimes. I tried adding blocks to see if that changes things with no luck.

对我做错了什么有任何想法吗?

Any thoughts on what I am doing wrong?

- 添加了完整的编译器错误输出

Edited:- Added the full compiler error output

推荐答案

对于编译器来说,生命周期参数总是代表生命周期严格长于函数调用的生命周期.然而,在这里你试图使用一个局部变量并声称它有生命周期'de,这是不可能的,因为它是一个局部变量,因此它的生命周期比函数调用短.

To the compiler, lifetime parameters always represent lifetimes that live strictly longer than the function call. However, here you're trying to use a local variable and claim it has lifetime 'de, which is impossible because it's a local variable, thus it has a lifetime shorter than the function call.

为了将 trait 中的生命周期参数与局部变量混合,我们必须使用 更高-等级特征边界.我们希望 T每个 生命周期 'de(不仅仅是一个特定的生命周期选择)实现 Deserialize由来电者).这是这样写的(注意我们现在可以省略 'a 生命周期):

In order to mix lifetime parameters in traits with local variables, we must use higher-rank trait bounds. We want T to implement Deserialize<'de> for every lifetime 'de (not just one specific lifetime chosen by the caller). This is written like this (note that we can now elide the 'a lifetime):

pub fn convert<T>(from: &Left, print: bool) -> (T, &Left)
where
    T: for<'de> Deserialize<'de> + std::fmt::Debug
{
    // no changes here
}

这篇关于通用函数中的 Rust Lifetime 问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-27 20:04