为什么 Rust 有时会在泛型的参数前加上一个 ::?

Why does Rust put a :: before the parameters in generics sometimes?

在 Rust 中声明 vector 类型的变量或哈希映射时,我们会:

let v: Vec<int>
let m: HashMap<int, int>

要实例化,我们需要调用new()。但是,我们这样做:

Vec::<int>::new()
   ^^
HashMap::<int, int>::new()
       ^^

注意 :: 的突然出现。来自 C++,这些很奇怪。为什么会出现这些?具有前导 :: 是否使 IDENTIFIER :: < IDENTFIER …IDENTIFIER < IDENTIFIER 更容易解析,这可能被解释为小于操作? (因此,这只是让语言更容易解析的事情?但如果是这样,为什么不在类型规范中也这样做,以便使两者相互镜像?)

(正如 Shepmaster 所说,通常 Vec::new() 就足够了;通常可以推断出类型。)

解析表达式时,< 是类型参数列表的开头还是小于运算符会产生歧义。 Rust 总是假设后者并且要求 ::< 用于类型参数列表。

当解析类型时,它总是明确的类型参数列表,因此永远不需要 ::<

在 C++ 中,这种歧义保留在解析器中,这使得解析 C++ 比解析 Rust 困难得多。请参阅 here 了解为什么这很重要。

无论如何,大多数 时间在 Rust 中,类型可以被推断,你可以只写 Vec::new()。由于通常不需要 ::< 并且相当难看,因此在类型中只保留 < 是有意义的,而不是使两种语法匹配。

两种不同的语法甚至不一定指定相同类型的参数。

在这个例子中:

let mut map: HashMap<K, V>;

KV填充struct HashMap声明的类型参数,类型本身。

在这个表达式中:

HashMap::<K, V>::new()

KV填写impl块的类型参数,其中定义了方法new! impl 块不需要具有与类型本身相同、一样多或相同的默认类型参数。

在这种特殊情况下,该结构具有参数 HashMap<K, V, S = RandomState>(3 个参数,1 个默认)。并且包含 ::new() 的 impl 块具有参数 impl<K, V>(2 个参数,未针对任意状态实现)。