gpt4 book ai didi

rust - 想办法解决 "...does not live long enough"

转载 作者:行者123 更新时间:2023-11-29 08:19:35 25 4
gpt4 key购买 nike

我正在用 Rust 构建多路复用。这是我的第一个应用程序之一,也是一次很棒的学习经历!

但是,我遇到了一个问题,我找不到如何用 rust 解决它:

每当一个新 channel 被添加到多路复用中时,我必须在这个 channel 上监听数据。当 open() 函数请求新 channel 时,它会在堆栈上分配。但是,这个 channel 一定不能分配在堆栈上,而是分配在堆上,因为它应该保持事件状态,不应该在我的接收循环的下一次迭代中被释放。

现在我的代码看起来像这样(v0.10-pre):

extern crate collections;
extern crate sync;

use std::comm::{Chan, Port, Select};
use std::mem::size_of_val;
use std::io::ChanWriter;
use std::io::{ChanWriter, PortReader};
use collections::hashmap::HashMap;
use sync::{rendezvous, SyncPort, SyncChan};
use std::task::try;

use std::rc::Rc;

struct MultiplexStream {
internal_port: Port<(u32, Option<(Port<~[u8]>, Chan<~[u8]>)>)>,
internal_chan: Chan<u32>
}

impl MultiplexStream {
fn new(downstream: (Port<~[u8]>, Chan<~[u8]>)) -> ~MultiplexStream {
let (downstream_port, downstream_chan) = downstream;

let (p1, c1): (Port<u32>, Chan<u32>) = Chan::new();
let (p2, c2):
(Port<(u32, Option<(Port<~[u8]>, Chan<~[u8]>)>)>,
Chan<(u32, Option<(Port<~[u8]>, Chan<~[u8]>)>)>) = Chan::new();

let mux = ~MultiplexStream {
internal_port: p2,
internal_chan: c1
};

spawn(proc() {
let mut pool = Select::new();
let mut by_port_num = HashMap::new();
let mut by_handle_id = HashMap::new();
let mut handle_id2port_num = HashMap::new();

let mut internal_handle = pool.handle(&p1);
let mut downstream_handle = pool.handle(&downstream_port);

unsafe {
internal_handle.add();
downstream_handle.add();
}

loop {
let handle_id = pool.wait();

if handle_id == internal_handle.id() {
// setup new port
let port_num: u32 = p1.recv();

if by_port_num.contains_key(&port_num) {
c2.send((port_num, None))
}
else {
let (p1_,c1_): (Port<~[u8]>, Chan<~[u8]>) = Chan::new();
let (p2_,c2_): (Port<~[u8]>, Chan<~[u8]>) = Chan::new();

/********************************/
let mut h = pool.handle(&p1_); // <--
/********************************/
/* the error is HERE ^^^ */
/********************************/

unsafe { h.add() };
by_port_num.insert(port_num, c2_);
handle_id2port_num.insert(h.id(), port_num);
by_handle_id.insert(h.id(), h);
c2.send((port_num, Some((p2_,c1_))));
}
}
else if handle_id == downstream_handle.id() {
// demultiplex
let res = try(proc() {
let mut reader = PortReader::new(downstream_port);
let port_num = reader.read_le_u32().unwrap();
let data = reader.read_to_end().unwrap();
return (port_num, data);
});
if res.is_ok() {
let (port_num, data) = res.unwrap();
by_port_num.get(&port_num).send(data);
}
else {
// TODO: handle error
}
}
else {
// multiplex
let h = by_handle_id.get_mut(&handle_id);
let port_num = handle_id2port_num.get(&handle_id);
let port_num = *port_num;
let data = h.recv();

try(proc() {
let mut writer = ChanWriter::new(downstream_chan);
writer.write_le_u32(port_num);
writer.write(data);
writer.flush();
});

// todo check if chan was closed
}
}
});

return mux;
}

fn open(self, port_num: u32) -> Result<(Port<~[u8]>, Chan<~[u8]>), ()> {
let res = try(proc() {
self.internal_chan.send(port_num);
let (n, res) = self.internal_port.recv();
assert!(n == port_num);

return res;
});

if res.is_err() {
return Err(());
}
let res = res.unwrap();
if res.is_none() {
return Err(());
}

let (p,c) = res.unwrap();
return Ok((p,c));
}
}

并且编译器引发了这个错误:

multiplex_stream.rs:81:31: 81:35 error: `p1_` does not live long enough
multiplex_stream.rs:81 let mut h = pool.handle(&p1_);
^~~~
multiplex_stream.rs:48:16: 122:4 note: reference must be valid for the block at 48:15...
multiplex_stream.rs:48 spawn(proc() {
multiplex_stream.rs:49 let mut pool = Select::new();
multiplex_stream.rs:50 let mut by_port_num = HashMap::new();
multiplex_stream.rs:51 let mut by_handle_id = HashMap::new();
multiplex_stream.rs:52 let mut handle_id2port_num = HashMap::new();
multiplex_stream.rs:53
...
multiplex_stream.rs:77:11: 87:7 note: ...but borrowed value is only valid for the block at 77:10
multiplex_stream.rs:77 else {
multiplex_stream.rs:78 let (p1_,c1_): (Port<~[u8]>, Chan<~[u8]>) = Chan::new();
multiplex_stream.rs:79 let (p2_,c2_): (Port<~[u8]>, Chan<~[u8]>) = Chan::new();
multiplex_stream.rs:80
multiplex_stream.rs:81 let mut h = pool.handle(&p1_);
multiplex_stream.rs:82 unsafe { h.add() };

有人知道如何解决这个问题吗?

最佳答案

问题是您创建的新 channel 的生命周期不够长——它的范围只是 else block 的范围。您需要确保它的生命周期更长——它的范围必须至少是 pool 的范围。

我没有努力去准确理解你的代码在做什么,但我希望确保端口的生命周期足够长的最简单方法是将它放在一个向量中与 pool 相同的范围,例如let ports = ~[];,用 ports.push(p1_); 插入它,然后将引用作为 &ports[ports.len() - 1 ]. 抱歉,这不会削减它 — 当对其元素的引用处于事件状态时,您不能向矢量添加新项目。如果您希望该方法起作用,则需要对事物进行一些重组。

关于rust - 想办法解决 "...does not live long enough",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22000230/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com