请帮帮我,我完全糊涂了。
如何使此代码工作?
我需要更改线程中的结构成员...
#[derive(Debug)]
struct S {
str: String,
b: bool,
i: u128,
}
fn main() {
let mut vec_s = vec![];
vec_s.push(S {
str: "a".to_string(),
b: false,
i: 0,
});
let mut threads = vec![];
for s in vec_s {
{
let mut _s = &s;
threads.push(std::thread::spawn(move || {
_s.b = true;
_s.str = "b".to_string();
_s.i = 1;
}));
}
}
for thread in threads {
let _ = thread.join();
}
dbg!(&vec_s);
}
编译器会输出许多错误:
error[E0594]: cannot assign to `_s.b`, which is behind a `&` reference
--> src/main.rs:23:17
|
23 | _s.b = true;
| ^^^^^^^^^^^ cannot assign
error[E0594]: cannot assign to `_s.str`, which is behind a `&` reference
--> src/main.rs:24:17
|
24 | _s.str = "b".to_string();
| ^^^^^^ cannot assign
error[E0594]: cannot assign to `_s.i`, which is behind a `&` reference
--> src/main.rs:25:17
|
25 | _s.i = 1;
| ^^^^^^^^ cannot assign
error[E0597]: `s` does not live long enough
--> src/main.rs:21:26
|
21 | let mut _s = &s;
| ^^ borrowed value does not live long enough
22 | threads.push(std::thread::spawn(move || {
| __________________________-
23 | | _s.b = true;
24 | | _s.str = "b".to_string();
25 | | _s.i = 1;
26 | | }));
| |______________- argument requires that `s` is borrowed for `'static`
27 | }
28 | }
| - `s` dropped here while still borrowed
error[E0382]: borrow of moved value: `vec_s`
--> src/main.rs:34:10
|
9 | let mut vec_s = vec![];
| --------- move occurs because `vec_s` has type `Vec<S>`, which does not implement the `Copy` trait
...
19 | for s in vec_s {
| ----- `vec_s` moved due to this implicit call to `.into_iter()`
...
34 | dbg!(&vec_s);
| ^^^^^^ value borrowed here after move
|
note: this function takes ownership of the receiver `self`, which moves `vec_s`
--> /home/martin/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/traits/collect.rs:261:18
|
261 | fn into_iter(self) -> Self::IntoIter;
| ^^^^
help: consider iterating over a slice of the `Vec<S>`'s content to avoid moving into the `for` loop
|
19 | for s in &vec_s {
| +
1条答案
按热度按时间yhived7q1#
您正在尝试执行多线程。多线程访问的所有内容都必须是线程安全的。此外,Rust非常严格(零未定义行为容忍),编译器必须了解您的代码是线程安全的。
这里最大的问题是Rust的借位检查器不知道你的线程在某个点被加入。因此它不允许你创建对你的
S
对象的引用,因为它不能证明这些引用存在了多久。Rust必须能够证明它们在你的S
对象被删除之前被销毁了;那是拉斯特借钱安全保证一部分对于您的特定用例,Rust引入了thread scopes。通过它们,编译器最终可以了解线程的生存期。
修复了一些次要的所有权问题(对循环使用
&mut vec_s
,否则vec_s
对象将被循环使用),现在可以这样做:第一个
另一个优化:
如果你实际上并没有使用
JoinHandle
来传播错误或类似的东西,那么在这个例子中你根本就不需要它们。scope
已经在作用域的末尾自动加入了它所产生的所有线程:第一次