【问题标题】:Function type vs Closure type函数类型与闭包类型
【发布时间】:2014-09-17 10:10:29
【问题描述】:

我想创建一个函数向量

let all_rerankers =  vec![ match_full
                         , match_partial
                         , match_regex
                         , match_camel_case
                         ];

但是,match_camel_case 比其他函数需要多一个参数,所以我虽然可以为 match_camel_case 定义一个闭包

// 3 is the extra parameter needed by match_camel_case
let close_camel_case = |str: &str, keyword: &str| {
    match_camel_case(str, keyword, 3) 
};

然后指定我的向量的类型:

let all_rerankers: Vec<|str: &str, kwd: &str| -> MatchScore>
    = vec![ match_full
          , match_partial
          , match_regex
          , close_camel_case
          ];

但是编译它告诉我 Rust 对待它们的方式不同:

mismatched types: expected `fn(&str, &str) -> MatchScore`, 
found `|&str, &str| -> MatchScore` 
(expected extern fn, found fn)

close_camel_case
^~~~~~~~~~~~~~~~

(以及我的vec! 宏中的类似类型错误)

它似乎也区分了Fn 类型和闭包类型。我可以通过将每个 match_* 函数包装在一个闭包中来进行编译,但我确信有更好的解决方案。

问题:

  1. 这里的实际不匹配是什么?错误消息似乎暗示Fn vs 闭包类型,但错误消息中还有expected extern fn, found fn
  2. 如何使类型匹配? (即把闭包转换成fn类型,因为它是纯的)

我的 rustc 版本:rustc 0.12.0-pre-nightly (09cebc25a 2014-09-07 00:31:28 +0000)(如果需要可以升级)

【问题讨论】:

    标签: closures rust


    【解决方案1】:

    这看起来像是类型推断中的一些不幸问题。如果你这样做:

    let mut all_rerankers: Vec<|str: &str, kwd: &str| -> MatchScore> = Vec::new();
    all_rerankers.push(match_full);
    all_rerankers.push(match_partial);
    all_rerankers.push(match_regex);
    all_rerankers.push(close_camel_case);
    

    然后一切都很好。重复内容很多,但您可以轻松编写一个宏,其调用可能如下所示:

    push_to!(all_rerankers;
        match_full,
        match_partial,
        match_regex,
        close_camel_case
    )
    

    这可能值得在Rust bug tracker 中创建一个问题,但旧的闭包很快就会被弃用,所以我不确定这是否值得修复。

    【讨论】:

    • 这不是问题。这就像将某个 X 类型的 3 个元素推入一个向量,然后期望该向量更改为某个更一般的 Y 类型。如果没有给出类型,则推断的类型是第一个添加到 Vec 的类型。这就是这里的情况。
    猜你喜欢
    • 1970-01-01
    • 2019-09-06
    • 1970-01-01
    • 1970-01-01
    • 2013-11-10
    • 1970-01-01
    • 2018-12-24
    • 2014-10-24
    • 1970-01-01
    相关资源
    最近更新 更多