2
votes

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

1 Answers

1
votes

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.