【问题标题】:What is the Rust way to call a method requireing a string slice from a String什么是 Rust 调用需要来自 String 的字符串切片的方法的方法
【发布时间】:2021-12-07 09:02:17
【问题描述】:

我是 rust 初学者(但经验丰富的程序员),我正在尝试创建一个简单的实用程序函数来从 json 文件中读取数据,并且显然缺少重要的 rust 理解来实现它。我环顾四周,但我无法解决其他生锈问题。我正在尝试做这样的事情:

pub fn read_data_from_json<'a, T: Deserialize<'a>, P: AsRef<Path>>(path: P) -> T {
    let result = std::fs::read_to_string(path).unwrap();
    return serde_json::from_str(&result).unwrap();
}

问题是我想为serde_json::from_str() 提供它需要的&amp;str,但从读取文件中获得String。所以 rust 编译器说:

40 |     return serde_json::from_str(&result).unwrap();
   |            ---------------------^^^^^^^-
   |            |                    |
   |            |                    borrowed value does not live long enough

原因显然是result 变量在from_str() 完成值之前被删除,但我无法获得“只是切片”的值。我已经尝试过as_str()&amp;*&amp;'static str 和其他几个选项来尝试完成这项工作,但我显然遗漏了一些东西,因为它似乎是一个基本的用例。我必须承认我对“生命周期”和所涉及的泛型仍然有些模糊,所以问题可能就在那里。

【问题讨论】:

标签: rust serde


【解决方案1】:

我建议您阅读 serde 手册中的 Understanding deserializer lifetimes。他们在那里建议T: DeserializeOwned,明确提及您的用例:

通常这是因为要反序列化的数据在函数返回之前就被丢弃了,所以T不能借用它。

所以解决办法是:

use serde::de::DeserializeOwned;

pub fn read_data_from_json<T: DeserializeOwned, P: AsRef<Path>>(path: P) -> T {
    let result = std::fs::read_to_string(path).unwrap();
    return serde_json::from_str(&result).unwrap();
}

【讨论】:

  • 请注意,这可能涉及更改要反序列化的结构,因为它必须拥有自己的数据。
  • 好吧很有趣,但这仅仅是 serde 的零拷贝序列化方式的问题吗?我认为这是我需要了解的借款的一般情况。我觉得我应该能够告诉 Rust 只保留引用直到函数/范围退出,或者我只想要切片而不是字符串对象。
  • @leondepeon Rust 确实保留了引用,直到函数/范围退出。如果您将其结果分配给局部变量并在函数内部使用它,您的from_str() 调用会很好,因此它不会超过result。但是您尝试 return 构造的值,这是不允许的,因为一旦删除了 result,其中的零拷贝引用就会悬空。
猜你喜欢
  • 1970-01-01
  • 2023-01-15
  • 1970-01-01
  • 2011-05-15
  • 1970-01-01
  • 2018-12-21
  • 2011-06-15
  • 2017-10-07
  • 1970-01-01
相关资源
最近更新 更多