struct - 比结构方法长寿

标签 struct rust lifetime

<分区>

我想要一些数据对象将其自身序列化并制作一个可以通过 UDP 发送的版本。问题是序列化创建的 String (serde_json::to_string) 只存在到范围结束(这对我来说有意义)所以字节版本(a &[u8] from as_bytes) 无法超出范围引用它。我尝试添加一些生命周期参数但没有成功;我实际上还不太了解生命周期参数。

#[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());
}

Playground

error[E0597]: borrowed value does not live long enough
  --> src/main.rs:22:9
   |
22 |         serde_json::to_string(&self).unwrap().as_bytes()
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ does not live long enough
23 |     }
   |     - temporary value only lives until here
   |
note: borrowed value must be valid for the anonymous lifetime #1 defined on the method body at 19:5...
  --> src/main.rs:19:5
   |
19 | /     pub fn to_utf8(&self) -> &[u8] {
20 | |         // serde_json::to_string returns Result<String, ...>
21 | |         // String.as_bytes() returns &[u8]
22 | |         serde_json::to_string(&self).unwrap().as_bytes()
23 | |     }
   | |_____^

最佳答案

如您所见,切片的生命周期不能超过作用域。我不认为你可以用生命周期注解来解决这个问题:显式生命周期实际上不能让对象活得更久,它们只会阻止编译器对哪些生命周期是相同的做出过于严格的假设。

这样做的方法是将这些字节的所有权还给调用者,而不是在切片中借用它们。显而易见的候选者是 Vec :

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

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

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

现在您可以返回 Vec<u8>它将由调用者拥有,并在调用者需要时持续使用。您可以使用 Vec<u8>与使用切片的方式完全相同,如果需要,您甚至可以从中借用底层切片。

关于struct - 比结构方法长寿,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48711176/

相关文章:

rust - 移动到过滤器闭包中的Trait参数的生存期限制应该是什么?

c - sizeof(),C 结构中的对齐方式 :

c - [ANSI-C]像类一样使用结构

struct - 遍历struct Hashmap并将值添加到self的另一部分

rust - 是否可以从子结构调用父结构的方法?

rust - 为什么在解构变量后无法调用方法,但直接访问该字段却可以调用方法?

c++ - 在数组声明中使用常量结构成员

无法将指向结构的指针中的 a::c * 转换为 c *

rust - Const 闭包数组采用对 Rust 中具有生命周期参数的结构的可变引用

rust - 有没有办法选择两个生命周期中较小的一个?