У меня есть структура с двумя параметрами типа, один из которых имеет тип по умолчанию:
use std::marker::PhantomData;
struct Foo<T, F = ()>(PhantomData<(T, F)>);
impl<T, F> Foo<T, F> {
fn new() -> Self { Self(PhantomData) }
fn foo(&self, _: T) {}
}
let foo = Foo::new();
foo.foo(0u32);
Приведенный выше код приводит к:
error[E0282]: type annotations needed
--> src/main.rs:17:15
|
17 | let foo = Foo::new();
| --- ^^^^^^^^ cannot infer type for `F`
| |
| consider giving `foo` a type
Я не понимаю, почемутип по умолчанию здесь не используется.Обратите внимание, что поговорка let foo: Foo<u32> = Foo::new();
уже работает - поэтому нет необходимости указывать параметр F
.Но зачем указывать T
?Так что я уже растерялся.
Но потом я вспомнил, что все это работает с HashMap
!Он определяется как struct HashMap<K, V, S = RandomState>
.И мне никогда не нужно было ничего уточнять.Например, это работает:
use std::collections::HashMap;
let mut map = HashMap::new();
map.insert(0u32, 'x');
( Все на игровой площадке )
Почему поведение типа / логического вывода по умолчанию отличается между Foo
и HashMap
? Использует ли hashmap какую-то магию компилятора?