2014-09-17 1 views
2

Я хочу, чтобы создать вектор функцийТип функции против типа Closure

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

Однако компиляции он показывает мне, что Руст относится к ним по-разному:

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

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

(и аналогичный тип ошибки в моей vec! макро)

Это также, кажется, различать Fn типа и типа закрытия. Я могу сделать эту компиляцию, завернув каждую функцию match_* в закрытие, но я уверен, что есть лучшее решение.

Вопрос:

  1. Что такое фактическое несоответствие здесь? сообщение об ошибке, кажется, предлагает Fn против типа закрытия, но тогда есть также expected extern fn, found fn в сообщении об ошибке
  2. Как я могу совместить тип? (А именно, конвертировать замыкание в fn типа, так как это чистое)

моего rustc версии: rustc 0.12.0-pre-nightly (09cebc25a 2014-09-07 00:31:28 +0000) (можно обновить при необходимости)

ответ

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, но старые закрытия устареют в ближайшее время, так что я не уверен, что если это стоит исправить.

+0

Да, это все хорошо. Я могу подождать. Благодарю. –

+1

Это не проблема. Это как нажатие 3 элементов некоторого типа X на вектор, а затем ожидание перехода вектора к некоторому более общему типу Y. Если тип не указан, тип, который выведен, является первым, добавленным в Vec. И это имеет место здесь. – Arjan