问题描述
我目前正在为 Rust (1.0) 的生命周期而苦苦挣扎,尤其是在通过通道传递结构时.
I'm currently struggling with lifetimes in Rust (1.0), especially when it comes to passing structs via channels.
我如何编译这个简单的例子:
How would I get this simple example to compile:
use std::sync::mpsc::{Receiver, Sender};
use std::sync::mpsc;
use std::thread::spawn;
use std::io;
use std::io::prelude::*;
struct Message<'a> {
text: &'a str,
}
fn main() {
let (tx, rx): (Sender<Message>, Receiver<Message>) = mpsc::channel();
let _handle_receive = spawn(move || {
for message in rx.iter() {
println!("{}", message.text);
}
});
let stdin = io::stdin();
for line in stdin.lock().lines() {
let message = Message {
text: &line.unwrap()[..],
};
tx.send(message).unwrap();
}
}
我明白了:
error[E0597]: borrowed value does not live long enough
--> src/main.rs:23:20
|
23 | text: &line.unwrap()[..],
| ^^^^^^^^^^^^^ does not live long enough
...
26 | }
| - temporary value only lives until here
|
= note: borrowed value must be valid for the static lifetime...
我能理解为什么会这样(line
只存在于 for
的一次迭代中),但我不知道这样做的正确方法是什么.
I can see why this is (line
only lives for one iteration of for
), but I can't figure out what the right way of doing this is.
- 我应该按照编译器的提示,尝试将
&str
转换为&'static str
吗? - 如果每一行都有一个
'static
生命周期,我是否会泄漏内存? - 我什么时候应该使用
'static
呢?这是我应该尽量避免的事情还是完全没问题? - 是否有更好的方法通过通道在结构中传递
String
?
- Should I, as the compiler hints, try to convert the
&str
into&'static str
? - Am I leaking memory if every line would have a
'static
lifetime? - When am I supposed to use
'static
anyway? Is it something I should try to avoid or is it perfectly OK? - Is there a better way of passing
String
s in structs via channels?
对于那些幼稚的问题,我深表歉意.我已经花了很长时间进行搜索,但我无法完全理解它.这可能是我的动态语言背景妨碍了:)
I apologize for those naive questions. I've spent quite some time searching already, but I can't quite wrap my head around it. It's probably my dynamic language background getting in the way :)
顺便说一句:&input[..]
是否可以将 String
转换为 &str
被认为可以?这是我能找到的唯一稳定的方法来做到这一点.
As an aside: Is &input[..]
for converting a String
into a &str
considered OK? It's the only stable way I could find to do this.
推荐答案
&'a T
不能转换成 &'static T
除非泄漏记忆.幸运的是,这根本没有必要.没有理由向线程发送借用的指针并将行保留在主线程上.您不需要主线程上的行.只需发送行本身,即发送 String
.
You can't convert &'a T
into &'static T
except by leaking memory. Luckily, this is not necessary at all. There is no reason to send borrowed pointers to the thread and keep the lines on the main thread. You don't need the lines on the main thread. Just send the lines themselves, i.e. send String
.
如果需要从多个线程访问(并且您不想克隆),请使用Arc
(将来,Arc 也可以工作).这样,字符串在线程之间共享,正确共享,以便在没有线程再使用它时准确地释放它.
If access from multiple threads was necessary (and you don't want to clone), use Arc<String>
(in the future, Arc<str>
may also work). This way the string is shared between threads, properly shared, so that it will be deallocated exactly when no thread uses it any more.
在线程之间发送非'static
引用是不安全的,因为你永远不知道另一个线程会继续使用它多久,所以你不知道借用何时到期并且对象可以被释放.请注意,作用域线程没有这个问题(不在 1.0 中,但正如我们所说的那样正在重新设计)确实允许这样做,但是常规的、spawn
ed 线程有.
Sending non-'static
references between threads is unsafe because you never know how long the other thread will keep using it, so you don't know when the borrow expires and the object can be freed. Note that scoped threads don't have this problem (which aren't in 1.0 but are being redesigned as we speak) do allow this, but regular, spawn
ed threads do.
'static
不是你应该避免的东西,它的作用非常好:表示一个值在程序运行的整个持续时间内都存在.但如果这不是您想要传达的内容,那当然是错误的工具.
'static
is not something you should avoid, it is perfectly fine for what it does: Denoting that a value lives for the entire duration the program is running. But if that is not what you're trying to convey, of course it is the wrong tool.
这篇关于如何对线程使用静态生命周期?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!