给send()传递ref是不行的,因为这个ref是在发送线程(或者说负责发送的闭包)里的,
一旦发送线程结束(或者说发送的闭包销毁了),ref即失效,此后接收线程收到这个ref后就是dangling reference。
这样去掉for带来的问题后,也是报错:
thread::spawn(move || {
let vals = vec![
String::from("hi"),
String::from("from"),
String::from("the"),
String::from("thread"),
];
let v1 = &vals[0];
tx.send(v1).unwrap();
});
或者说,要给send()传递ref,那么这个ref必须是static生命周期的,要求太高。
比如改成这样,表面上看起来ref的生命周期比tx的长。也报错,提示要传递static级别的ref。
fn main() {
let vals = vec![
String::from("hi"),
String::from("from"),
String::from("the"),
String::from("thread"),
];
let v1 = &vals[0];
{
//let (tx, rx) = mpsc::channel();
let (tx, rx) = mpsc::channel::<&String>();
thread::spawn(move || {
tx.send(v1).unwrap();
});
for received in rx {
println!("Got: {}", received);
}
}
}
参考的这个:
https://stackoverflow.com/questions/65641458/borrowed-value-does-not-live-long-enough-with-arc-thread-and-channel
https://users.rust-lang.org/t/solved-channel-in-a-loop-in-a-thread-borrowed-value-does-not-live-long-enough/26733
上面第一个链接里总结了lifetime check不跨线程,是thread local的。
第二个链接里有个总结是:不要跨线程传递ref,而是传递owned value。
【 在 txgx 的大作中提到: 】
: 肯定不是这样判断的!rustc还没到这么智能。
: 它好像是跟线程周期比较,因为线程可认为是'static的,而&val则不是。
: 不过我觉得send结束对val的引用也应结束,应该是编译器弱智原因。
: ...................
--
修改:z16166 FROM 123.115.133.*
FROM 123.115.133.*