Function type vs Closure type

亡梦爱人 提交于 2021-02-16 20:06:11

问题


I want to create a vector of functions

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

However, match_camel_case needs one more parameter than other functions, so I though I could define a closure for 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) 
};

and then specify the type of my vector:

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

However compiling it shows me that Rust treats them differently:

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

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

(and similar type error in my vec! macro)

It also seem to distinguish between Fn type and closure type. I can make this compile by wrapping every match_* function in a closure, but I'm sure there's a better solution.

Question:

  1. What is the actual mismatch here? the error message seems to suggest Fn vs closure type, but then there's also expected extern fn, found fn in the error message
  2. How can I make the type match? (namely, convert closure into fn type, since it's pure)

my rustc version: rustc 0.12.0-pre-nightly (09cebc25a 2014-09-07 00:31:28 +0000) (can upgrade if needed)


回答1:


This looks like some unfortunate problem in type inference. If you do this:

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);

Then everything is fine. The duplication is extensive, but you can easily write a macro whose invocation could look like this:

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

This probably deserves creating an issue in Rust bug tracker, but old closures will be deprecated soon, so I'm not sure if this is worth fixing.



来源:https://stackoverflow.com/questions/25887793/function-type-vs-closure-type

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!