将闭包移入线程时,“无法将不可变内容借用为可变内容”

时间:2016-05-23 11:37:03

标签: rust

在Rust中,我想指定当有趣的事情发生时由工作线程调用的回调(例如闭包)。回调的正确类型签名是什么?

这是我想要做的一个例子:

use std::thread;

fn spawner(f: Box<FnMut()->()+Send>) -> thread::JoinHandle<()> {
    thread::spawn(move || {
        f();
    })
}


fn main() {
    let cb = || {
        println!("callback");
    };
    spawner(Box::new(cb)).join().unwrap();
}
src/main.rs:5:9: 5:10 error: cannot borrow immutable `Box` content
`*f` as mutable

src/main.rs:5         f();

2 个答案:

答案 0 :(得分:2)

Rust中的可变性是继承的:因为持有该框的变量FnMut是不可变的,所以该框的内容也是不可变的。无法调用不可变FnMut闭包(f需要能够改变其环境)。

解决方案:使变量fn spawner(mut f: Box<FnMut()->()+Send>) -> thread::JoinHandle<()>变为可变:

<!DOCTYPE html> <html> <title>W3.CSS</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css"> <body class="w3-container"> <h2>Image in a Circle</h2> <p>You do not need boostrap, you can use w3-schools libraries instead</p> <img src="http://i.imgur.com/lGq1IXo.png" class="w3-circle" alt="" style="width:50%"> </body> </html>

答案 1 :(得分:1)

Rust编译器不允许您将不可变参数f移动到闭包中。将其更改为可变(在变量之前添加mut)编译器将停止抱怨并且您将获得所需的行为。

use std::thread;

fn spawner(mut f: Box<FnMut()->()+Send>) -> thread::JoinHandle<()> {
    thread::spawn(move || {
        f();
    })
}


fn main() {
    let cb = || {
        println!("callback");
    };
    spawner(Box::new(cb)).join().unwrap();
}