【问题标题】:How to hold borrowed value to struct's filed in Rust如何在 Rust 中将借来的值保存到 struct 字段
【发布时间】:2020-04-24 10:00:09
【问题描述】:

我只想在结构中使用tokio::net::TcpStream.split 方法并将其保留为其字段变量,但我收到错误error[E0597]: 'stream' does not live long enough。当我试图为结构的字段(如Struct std::path::Path)保存借用值时,我多次遇到此类问题。我知道Path 问题将通过使用PathBuf 来解决,但这次我不确定。你能给我一个建议让它工作吗?

use tokio::net::TcpStream;
use tokio::net::tcp::{ReadHalf, WriteHalf};

struct TT<'a>{
    pub reader: Option<ReadHalf<'a>>,
    pub writer: Option<WriteHalf<'a>>,
}

impl<'a> TT<'a> {
    fn set_reader_and_writer(&mut self, mut stream: TcpStream) {
        let (reader, writer) = stream.split();
        self.reader = Some(reader);
        self.writer = Some(writer);
    }
}
$ cargo build                                                                                                                                                                    [master|…4]
    Blocking waiting for file lock on build directory
   Compiling tcpst v0.1.0 (/tmp/tcpst)
error[E0597]: `stream` does not live long enough
  --> src/main.rs:11:32
   |
9  | impl<'a> TT<'a> {
   |      -- lifetime `'a` defined here
10 |     fn set_reader_and_writer(&mut self, mut stream: TcpStream) {
11 |         let (reader, writer) = stream.split();
   |                                ^^^^^^ borrowed value does not live long enough
12 |         self.reader = Some(reader);
   |         -------------------------- assignment requires that `stream` is borrowed for `'a`
13 |         self.writer = Some(writer);
14 |     }
   |     - `stream` dropped here while still borrowed

error: aborting due to previous error

For more information about this error, try `rustc --explain E0597`.
error: could not compile `tcpst`.

【问题讨论】:

  • 你需要通过引用TcpStream,这样你就可以定义TT的生命周期比TcpStream的生命周期短。在这里,您将 TcpStream 移动 到方法中,然后拆分它(借用它),然后......它死了,所以借用无效。或者,在两个字段或类似字段中存储一个Rc&lt;TcpStream&gt;

标签: rust ownership tokio


【解决方案1】:

问题在于流的读取和写入部分都借用了对创建它们的流的引用。在您的代码中,原始流被丢弃在函数的末尾,这将使这些引用无效。最简单的解决方案是将set_reader_and_writer 的签名更改为&amp;mut stream 而不是取得所有权。

这是一个非常容易理解的错误,因为split 的签名没有明确说明其生命周期(stream 必须至少与返回值一样长)。但是,如果您检查the source,它会显示ReadHalfWriteHalf 的生命周期(以及为什么允许从函数签名中省略它们)。

【讨论】:

    猜你喜欢
    • 2018-12-13
    • 1970-01-01
    • 1970-01-01
    • 2020-07-23
    • 1970-01-01
    • 2021-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多