С кодом возникает несколько проблем.
Прежде всего, вы не можете использовать Fn*
черты непосредственно в стабильной ржавчине. Это включает в себя 1) использование нотации с угловыми скобками и 2) реализацию этих признаков. Однако можно включить флаг функции для обеих этих вещей в нестабильном Rust.
Во-вторых, если вы используете угловые скобки для закрытия признаков, вы должны использовать кортежи аргументы, даже если есть только один аргумент:
FnOnce<(A,)>
В-третьих, сообщение об ошибке, что вместо FnOnce<(T, U), Output=V>
вас следует написать FnOnce(T, U) -> V
. Это то, что подразумевается под сообщением «Использование круглых скобок». Я согласен с тем, что это сообщение вводит в заблуждение, потому что вы не можете реализовать Fn
, когда оно написано так из-за связанных типов. Я предполагаю, что ошибка в реализации типов Fn
должна иметь приоритет над этой ошибкой.
В-четвертых, вы не сможете делать то, что хотите (функция memoizing, поддерживаемая картой хэша), когда вы используете &'a MemoedFun<A, R>
, потому что вам нужен изменяемый указатель для обновления карты. Вы должны реализовать FnOnce
для &'a mut MemoedFun<A, R>
:
impl<'a, A: Eq + Hash, R> FnOnce<(A,)> for &'a mut MemoedFun<A, R> {
type Output = &'a R;
extern "rust-call" fn call_once(self, (arg,): (A,)) -> &'a R {
if self.map.contains_key(&arg) {
&self.map[&arg]
} else {
let r = (self.fun)(&arg);
self.map.entry(arg).or_insert(r)
}
}
}
И, наконец, полученный код придется написать, чтобы использовать этот memoizer не очень. Вы не можете использовать синтаксис функции на вашей «функции» по какой-то причине, так что вам нужно будет использовать call_once()
непосредственно:
fn computer(x: &i32) -> i32 {
println!("Computing for {}", x);
-*x
}
let mut f = memoize(computer);
println!("f(10): {}", (&mut f).call_once((10,)));
println!("f(10): {}", (&mut f).call_once((10,)));
println!("f(42): {}", (&mut f).call_once((42,)));
(попробуйте это here)
Существует причина, почему Fn*
качество ручной реализации не стабилизирован, в конце концов.
Есть ли ржавая ошибка для этого вводящего в заблуждение сообщение об ошибке? Я не мог найти ничего по наивному поиску, – llogiq
Я тоже его не нашел, поэтому я думаю, что имеет смысл его создать. –
Что означает FnOnce (T, U) -> V? Я не могу найти описание этого синтаксиса. Выводится ли специальное ключевое слово? – dspyz