期望的trait core :: ops :: FnMut,找到类型参数

时间:2015-04-26 15:11:23

标签: rust

我不明白为什么下面的代码无法编译。生锈似乎并没有“扩大”。 type参数,因为它看起来与我匹配。

代码(防锈围栏:http://is.gd/gC82I4

use std::sync::{Arc, Mutex};

struct Data{
    func: Option<Box<FnMut(String) + Send>>
}

fn newData<F>(func: Option<Box<F>>) -> Data
where F: FnMut(String) + Send{
    Data{
        func: func
    }
}

fn main(){
    let _ = newData(Some(Box::new(|msg|{})));
}

错误

<anon>:10:15: 10:19 error: mismatched types:
 expected `core::option::Option<Box<core::ops::FnMut(collections::string::String) + Send>>`,
    found `core::option::Option<Box<F>>`
(expected trait core::ops::FnMut,
    found type parameter) [E0308]
<anon>:10         func: func
                        ^~~~
error: aborting due to previous error
playpen: application terminated with error code 101

2 个答案:

答案 0 :(得分:3)

你需要至少部分地将演员从Box<F>拼写到Box<FnMut>来帮助生锈。

由于Box<Trait>暗示Box<Trait + 'static>,您还需要添加绑定的F: 'static

struct Data {
    func: Option<Box<FnMut(String) + Send>>
}

fn new_data<F>(func: Option<Box<F>>) -> Data where
    F: FnMut(String) + Send + 'static
{
    Data {
        func: func.map(|x| x as Box<_>)
    }
}

fn main() {
    let _ = new_data(Some(Box::new(|msg|{ })));
}

这里要注意的是Box<F>Box<FnMut ...>的类型不同,但前者在大多数情况下会自动转换为后者。在选项内部,我们只需要通过编写显式转换来帮助转换。

答案 1 :(得分:3)

虽然user139873的回答是绝对正确的,但我想补充说,通过值将闭包传递给函数并将其装入函数中更为惯用:

struct Data {
    func: Option<Box<FnMut(String) + Send>>
}

fn new_data<F>(func: Option<F>) -> Data where
        F: FnMut(String) + Send + 'static {
    Data {
        func: func.map(|f| Box::new(f) as Box<_>)
    }
}

fn main() {
    let _ = new_data(Some(|msg| {}));
}

这样,您可以减少对调用者的限制,并且他们的代码变得更简单。