Как сохранить заимствованное значение для структуры, хранящейся в Rust - PullRequest
1 голос
/ 24 апреля 2020

Я просто хочу использовать метод 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`.

1 Ответ

1 голос
/ 24 апреля 2020

Проблема состоит в том, что обе части чтения и записи потока заимствуют ссылки на поток, из которого они были созданы. В вашем коде исходный поток удаляется в конце функции, что делает эти ссылки недействительными. Самое простое решение - изменить подпись set_reader_and_writer на &mut stream вместо владения.

Это очень понятная ошибка, так как подпись для split не дает времени жизни. явное (что stream должно жить как минимум столько же, сколько возвращаемые значения). Если вы проверите источник , он покажет время жизни ReadHalf и WriteHalf (и почему их разрешено исключать из сигнатуры функции).

...