#rust
#закрытие #Ржавчина
Вопрос:
Я хочу создать вектор функций
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: amp;str, keyword: amp;str| {
match_camel_case(str, keyword, 3)
};
а затем укажите тип моего вектора:
let all_rerankers: Vec<|str: amp;str, kwd: amp;str| -> MatchScore>
= vec![ match_full
, match_partial
, match_regex
, close_camel_case
];
Однако его компиляция показывает мне, что Rust относится к ним по-разному:
mismatched types: expected `fn(amp;str, amp;str) -> MatchScore`,
found `|amp;str, amp;str| -> MatchScore`
(expected extern fn, found fn)
close_camel_case
^~~~~~~~~~~~~~~~
(и аналогичная ошибка типа в моем vec!
макросе)
Также, похоже, проводится различие между Fn
типом и типом закрытия. Я могу сделать эту компиляцию, обернув каждую match_*
функцию в замыкание, но я уверен, что есть лучшее решение.
Вопрос:
- В чем здесь фактическое несоответствие? сообщение об ошибке, похоже, указывает
Fn
на тип закрытия vs, но тогдаexpected extern fn, found fn
в сообщении об ошибке также есть - Как я могу сопоставить тип? (а именно, преобразовать закрытие в
fn
тип, поскольку оно чистое)
моя версия rustc: rustc 0.12.0-pre-nightly (09cebc25a 2014-09-07 00:31:28 0000)
(при необходимости можно обновить)
Ответ №1:
Это похоже на какую-то досадную проблему при выводе типов. Если вы сделаете это:
let mut all_rerankers: Vec<|str: amp;str, kwd: amp;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, но старые закрытия скоро устареют, поэтому я не уверен, стоит ли это исправлять.
Комментарии:
1. На самом деле это не проблема. Это все равно, что поместить 3 элемента некоторого типа X в вектор, а затем ожидать, что вектор изменится на более общий тип Y. Если тип не задан, выводимый тип является первым, добавленным в Vec. И это имеет место здесь.