首页 > 解决方案 > 变量的生存时间不足以通过通道发送

问题描述

我正在尝试Cow<[u8]>通过频道发送包含的消息。但是,终身规则不允许我通过它。

use std::borrow::Cow;
use std::sync::mpsc;

#[derive(Debug, Default, PartialEq, Clone)]
pub struct PlayerAction<'a> {
    pub data: Cow<'a, [u8]>,
}

#[derive(Debug, Clone)]
pub enum NetworkMessage<'a> {
    PlayerActionMessage(PlayerAction<'a>),
}

pub struct ConnectionsManager<'a> {
    channel: mpsc::Sender<NetworkMessage<'a>>,
}

pub struct MessageHandler<'a> {
    pub connection_manager: ConnectionsManager<'a>,
}

fn read_message<'a>(bytes: &'a Vec<u8>) -> NetworkMessage {
    NetworkMessage::PlayerActionMessage(PlayerAction {
        data: Cow::Borrowed(&bytes),
    })
}

impl<'a> MessageHandler<'a> {
    fn on_message(&mut self, msg: Vec<u8>) {
        let readm = read_message(&msg);
        self.connection_manager.channel.send(readm);
    }
}

fn main() {}

操场

error[E0597]: `msg` does not live long enough
  --> src/main.rs:30:35
   |
30 |         let readm = read_message(&msg);
   |                                   ^^^ borrowed value does not live long enough
31 |         self.connection_manager.channel.send(readm);
32 |     }
   |     - borrowed value only lives until here
   |
note: borrowed value must be valid for the lifetime 'a as defined on the impl at 28:1...
  --> src/main.rs:28:1
   |
28 | impl<'a> MessageHandler<'a> {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^

MessageHandleroutlifes Vec<u8>,但我不知道如何以其他方式传递它。

有什么办法可以通过Vec<u8>,让它比on_message函数寿命更长吗?

标签: rustlifetimecopy-on-write

解决方案


这是您可以进行的单行更改以使此代码正确:

fn on_message(&mut self, msg: &'a [u8])

而不是Vec<u8>按值获取,而是引用已经保证至少与'a. 这使得调用者有责任确保您传递给的任何内容都on_message将存在足够长的时间以通过通道发送。


但也许你不能那样做。要么调用者会遇到同样的问题,你不能把它推得更远,要么是签名Vec<u8>的必需部分。on_message如果是这种情况,您将不得不更改read_message. 这是一种可能性:

fn read_message<'b>(bytes: Vec<u8>) -> NetworkMessage<'b> {
    NetworkMessage::PlayerActionMessage(PlayerAction {
        data: Cow::Owned(bytes),
    })
}

impl<'a> MessageHandler<'a> {
    fn on_message(&mut self, msg: Vec<u8>) {
        let readm = read_message(msg);
        self.connection_manager.channel.send(readm);
    }
}

移入msg使read_message编译器可以自由选择它想要的任何生命周期'b。在on_message它可以选择'a使代码编译。这种方法的缺点是,如果您需要在将其发送到通道后再次使用它,您可能必须这样.clone()Vec


推荐阅读