我想编写一个接受整数的函数,并生成使用该整数的线程。可以计算整数。它不必是文字。如果我使用诸如usize
之类的具体类型,它将起作用,但是当我尝试将其概括时,它fails to compile:
fn g<A>(a: A)
where
A: num::PrimInt + Copy + std::fmt::Debug + Send,
{
let hs = (0..3).map(|_| {
std::thread::spawn(move || {
println!("{:?}", a);
})
});
for h in hs {
h.join().unwrap();
}
}
错误是:
1 | fn g<A>(a: A)
| - help: consider adding an explicit lifetime bound `A: 'static`...
...
6 | std::thread::spawn(move || {
| ^^^^^^^^^^^^^^^^^^
|
note: ...so that the type `[closure@src/main.rs:6:28: 8:10 a:A]` will meet its required lifetime bounds
--> src/main.rs:6:9
|
6 | std::thread::spawn(move || {
| ^^^^^^^^^^^^^^^^^^
由于我具有Copy
特质,因此它应该能够为每个线程复制该值,因此不需要使用期限限制的建议。我该如何解决?
答案 0 :(得分:1)
Copy
和'static
是不同的约束,并且两者都是在线程之间移动值所必需的。尽管您可能只打算将整数(同时满足Copy
和'static
的情况)传递给泛型函数,但编译器无法确定。必须能够证明该功能主体对所有可能的类型参数有效。 reference to a local variable是Copy
但不是'static
的类型的示例:
fn assert_is_copy<T: Copy>(_: T) {}
fn assert_is_static<T: 'static>(_: T) {}
fn main() {
let x: usize = 5;
assert_is_copy(x);
assert_is_static(x);
assert_is_copy(&x);
//assert_is_static(&x); // FAILS TO COMPILE
}
我想您会同意,您不想将对 堆栈变量的引用传递给不同的线程(尽管在some limited cases中是安全的)。如果这样做,可以分离该线程,弹出带有局部变量的堆栈框架,并导致未定义的行为!
This answer对说T: 'static
的含义给出了一个简单(大部分)正确的解释。
答案 1 :(得分:1)
其他人解释了为什么您的代码不起作用,但是如果您仍然想知道如何使其工作,只需在您的代码中添加+ 'static
约束:
fn g<A>(a: A)
where
A: num::PrimInt + Copy + std::fmt::Debug + Send + 'static,
{
let hs = (0..3).map(|_| {
std::thread::spawn(move || {
println!("{:?}", a);
})
});
for h in hs {
h.join().unwrap();
}
}
答案 2 :(得分:0)
基于其他答案,我的问题的直接答案如下:
在Rust中,无法将计算得出的非文字PrimInt
传递给多个线程。