【问题标题】:expected trait core::ops::FnMut, found type parameter预期特征 core::ops::FnMut,找到类型参数
【发布时间】:2015-04-26 15:11:22
【问题描述】:

我不明白为什么下面的代码无法编译。似乎 rust 并没有“扩展”类型参数,因为它看起来很适合我。

代码(生锈游戏笔: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

【问题讨论】:

  • 顺便说一下,约定会将newData 设为Data::new

标签: rust


【解决方案1】:

您需要至少部分地从Box&lt;F&gt;Box&lt;FnMut&gt; 拼出演员表来帮助生锈。

因为Box&lt;Trait&gt;隐含Box&lt;Trait + 'static&gt;,所以还需要加上绑定的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&lt;F&gt;Box&lt;FnMut ...&gt;不是同一个类型,但是在大多数情况下前者会自动转换为后者。在此处的 Option 中,我们只需要通过编写显式转换来帮助转换。

【讨论】:

    【解决方案2】:

    虽然 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| {}));
    }
    

    这样你对调用者的限制更少,他们的代码也变得更简单。

    【讨论】:

      猜你喜欢
      • 2022-01-20
      • 1970-01-01
      • 2014-11-20
      • 2020-10-13
      • 2021-03-11
      • 2017-09-13
      • 2018-04-11
      • 2022-11-20
      • 1970-01-01
      相关资源
      最近更新 更多