链接到游乐场(或以下也是代码):https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=d6a8e4e6b9fa6aa647b2651e58402aa0
我想为库中的代码编写测试。 main
方法外部的代码与库(https://github.com/housleyjk/ws-rs/blob/master/src/lib.rs#L110)具有相同的结构。
在某些时候,我想提供一个可以随时间变化的值。我必须稍后在其他线程中声明该值。困难的部分是,保存变化值的类型的实例是在FnMut
闭包中构造的。
我尝试移动它,我尝试过RefCell
,我尝试过Arc
,但是我失败了。有什么建议吗?
use std::thread::sleep;
use std::time::Duration;
trait Fly {}
trait Surf {
fn will_be_called_after_two_seconds(&mut self);
}
struct Roll;
struct FlyingBird;
impl Fly for FlyingBird {}
struct SurfingDog(bool);
impl Surf for SurfingDog {
fn will_be_called_after_two_seconds(&mut self) {
self.0 = true;
}
}
fn closure_boi<F, S>(x: F) where F: FnMut(Roll) -> S, S: Surf {}
fn main() {
let val = false;
std::thread::spawn(|| {
closure_boi(|_| {
SurfingDog(val)
});
});
sleep(Duration::from_secs(5));
assert_eq!(true, val);
}
答案 0 :(得分:0)
有几个问题可能会导致上述代码无法正常工作:
main
中是一个场景)。解决方法是要么堆分配值并使用Arc
来跟踪它,要么使用crossbeam_utils::thread::scope
创建线程,这确实提供了保证。由于您可能需要生成的线程来保持并行运行,因此我们来研究Arc
。SurfingDog
不能仅包含布尔值,它必须包含对布尔值的引用,或者整个SurfingDog
实例必须在{{1}中可用}。在当前代码中,由另一个线程修改的布尔值驻留在main
值SurfingDog
中,该值是从它收到的闭包中获得的,该值与{{1 }}。Mutex
之类的锁,或者使用AtomicBool
之类的原子类型。考虑到上述情况,这是对编译和运行的代码的修改(playground):
closure_boi