变量的生存时间不够长,无法通过通道发送

mik*_*bal 3 lifetime copy-on-write rust

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() {}
Run Code Online (Sandbox Code Playgroud)

操场

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() {}
Run Code Online (Sandbox Code Playgroud)

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

有什么办法可以通过,Vec<u8>让它比on_message函数活得更久吗?

tre*_*tcl 5

您可以进行以下一行更改以使此代码正确:

fn on_message(&mut self, msg: &'a [u8])
Run Code Online (Sandbox Code Playgroud)

不要Vec<u8>按值获取 a,而是获取对已经保证生存时间至少与 一样长的切片的引用'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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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