trait CodecIF: Send + Sync {
fn new() -> Self;
fn process(&self);
}
struct Channel<T> {
pub id: usize,
pub tx: UnboundedSender<Msg>,
_codec: std::marker::PhantomData<T>,
}
impl<T: CodecIF> Channel<T> {
pub fn new(id: usize, map: Arc<DashMap<usize, Channel<T>>>) -> Self {
let (tx, mut rx) = tokio::sync::mpsc::unbounded_channel::<Msg>();
tokio::spawn(async move {
let mut codec = T::new();
codec.process();
map.remove(&id);
});
Channel {
id,
tx,
_codec: std::marker::PhantomData::default(),
}
}
}
编译错误:
error[E0310]: the parameter type `T` may not live long enough
--> src\channel.rs:65:9
|
65 | / tokio::spawn(async move {
66 | | let mut codec = T::new();
67 | |
68 | | codec.process();
69 | |
70 | | map.remove(&id);
71 | | });
| |__________^ ...so that the type `T` will meet its required lifetime bounds
|
help: consider adding an explicit lifetime bound...
|
62 | impl<T: CodecIF + 'static> Channel<T> {
| +++++++++
T是创建在tokio的task里的,生命周期并没有超出这个task,而 impl<T:CodecIF>只是标记了T的类型,为什么要在类型上标注生命周期呢?这里加上'static 确实可以编译通过,但代价是什么呢?
1
共 9 条评论, 1 页
评论区
写评论感谢大家的讲解,最后还是不传入map给task,而是通过mpsc把task结束的消息传递出来的方式解决这个问题,因此也就不需要'static了。
所以 map 需要是 'static。但是 map 的类型包括 T,所以 T 也要是 'static
--
👇
rascalrr: 对,用Arc传进去的,task是动态创建的,如果60s没有新数据进来,就关停task,并drop掉hashmap中的任务信息。 也考虑过用oneshot或者mpsc通知上级线程,但考虑可能存在漏数据的可能性,所以干脆传了一个hashmap进去。
--
👇
dakai-chen: tokio::spawn 的异步任务还捕获了 map
主要是编译器不清楚你是怎么使用T的,他只知道DashMap包含了Channel,而Channel包含了T,然后DashMap又被转移到spawn里,而T有可能是一个引用,所以认为T寿命不够长,T+'static是生命周期标注,只是人为跟编译器说T不是引用,只要能通过编译,不会对编译结果有任何影响
--
👇
rascalrr: 那像我这种例子,泛型只是为了标注类型,并在task内创建并使用,没有通过参数传递任何引用的话。正确的用法就是 T + 'static 么?
那像我这种例子,泛型只是为了标注类型,并在task内创建并使用,没有通过参数传递任何引用的话。正确的用法就是 T + 'static 么?
--
👇
ribs: 可以这么理解,T+'static表示可以一直拥有T,也就是需要转移所有权,因为T的实现也有可能是一个引用,也就是说可以假定不写的时候,有可能是T+'a,所以没办法转移到tokio::spawn的闭包中
对,用Arc传进去的,task是动态创建的,如果60s没有新数据进来,就关停task,并drop掉hashmap中的任务信息。 也考虑过用oneshot或者mpsc通知上级线程,但考虑可能存在漏数据的可能性,所以干脆传了一个hashmap进去。
--
👇
dakai-chen: tokio::spawn 的异步任务还捕获了 map
可以这么理解,T+'static表示可以一直拥有T,也就是需要转移所有权,因为T的实现也有可能是一个引用,也就是说可以假定不写的时候,有可能是T+'a,所以没办法转移到tokio::spawn的闭包中
tokio::spawn 的异步任务还捕获了 map
谢谢~ 这个我看过了,它说的是函数入参 :T 'static 的情况,和我现在遇到的情况不太相同。
--
👇
Pikachu: https://practice.rs/lifetime/static.html
https://practice.rs/lifetime/static.html