Struct 大纲结构方法

Struct 大纲结构方法,struct,rust,lifetime,Struct,Rust,Lifetime,我需要一些数据对象来序列化它自己,并生成一个可以通过UDP发送的版本。问题是序列化serde_json::to_字符串创建的字符串仅在作用域结束之前有效,这对我来说很有意义,因此as_字节中的字节版本a&[u8]无法将其引用到作用域之外。我尝试过添加一些寿命参数,但没有成功;我还不太了解生命周期参数 #[macro_use] extern crate serde_derive; extern crate serde_json; use std::str; #[derive(Debug, Se

我需要一些数据对象来序列化它自己,并生成一个可以通过UDP发送的版本。问题是序列化serde_json::to_字符串创建的字符串仅在作用域结束之前有效,这对我来说很有意义,因此as_字节中的字节版本a&[u8]无法将其引用到作用域之外。我尝试过添加一些寿命参数,但没有成功;我还不太了解生命周期参数

#[macro_use]
extern crate serde_derive;
extern crate serde_json;

use std::str;

#[derive(Debug, Serialize, Deserialize)]
struct Test {
    text: String,
}

impl Test {
    pub fn new(input: &str) -> Self {
        Test {
            text: String::from(input),
        }
    }

    pub fn to_utf8(&self) -> &[u8] {
        // serde_json::to_string returns Result<String, ...>
        // String.as_bytes() returns &[u8]
        serde_json::to_string(&self).unwrap().as_bytes()
    }
}

fn main() {
    let a = Test::new("abc");
    println!("{:?}", a.to_utf8());
}
错误[E0597]:借用值的有效期不足 ->src/main.rs:22:9 | 22 | serde_json::to_string&self.unwrap.as_字节 |我的寿命不够长 23 | } |-临时价值仅在此之前有效 | 注意:借用值必须在19:5对方法体上定义的匿名生存期1有效。。。 ->src/main.rs:19:5 | 19 |/pub fn to_utf8&self->和[u8]{ 20 | |//serde_json::to_字符串返回结果 21 | |//String.as_字节返回&[u8] 22 | | serde|u json::to_string&self.unwrap.as_字节 23 | | } | |_____^
正如您所计算的,切片不能超出范围。我认为你不能用生命周期注释来解决这个问题:显式生命周期实际上不能使对象活得更长,它们只会阻止编译器对哪些生命周期是相同的做出过于严格的假设

实现这一点的方法是将这些字节的所有权还给调用者,而不是在片中借用它们。最明显的候选者是Vec:

这是一个额外的副本,这是不幸的,但幸运的是Serde提供了一个函数,可以直接为您提供此输出

pub fn to_utf8(&self) -> Vec<u8> {
    serde_json::to_vec(&self).unwrap()
} 

现在,您可以返回一个Vec,该Vec将由调用者拥有,并且可以根据调用者的需要使用多长时间。您可以使用与使用切片完全相同的Vec,如果需要,您甚至可以从中借用底层切片。

请注意,String有into_bytes方法,只需获得字符串的所有权,即可创建一个没有任何副本的Vec,因此您可以跳过as_bytes,Vec::from dance。但您的to_vec解决方案更为优雅@oli_obk-ker说得很好。我只是想首先展示一个显而易见的解决方案,在不太修改代码的情况下获得一个Vec,然后将其发展成我实际推荐的解决方案。Playerd link,这样我就不必粘贴错误消息-强迫每个阅读你的问题的人都单击一个链接以交换一个人,从而避免复制和粘贴一些文本,这是不礼貌的。@Shepmaster,不是这样的意思。我认为最好是看到代码“在运行”,并且在我看来,当错误产生时,代码会变得更加枯燥。
pub fn to_utf8(&self) -> Vec<u8> {
    serde_json::to_vec(&self).unwrap()
}