为什么 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>;
K
和V
填充struct HashMap
声明的类型参数,类型本身。
在这个表达式中:
HashMap::<K, V>::new()
K
和V
填写impl块的类型参数,其中定义了方法new
! impl 块不需要具有与类型本身相同、一样多或相同的默认类型参数。
在这种特殊情况下,该结构具有参数 HashMap<K, V, S = RandomState>
(3 个参数,1 个默认)。并且包含 ::new()
的 impl 块具有参数 impl<K, V>
(2 个参数,未针对任意状态实现)。
在 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>;
K
和V
填充struct HashMap
声明的类型参数,类型本身。
在这个表达式中:
HashMap::<K, V>::new()
K
和V
填写impl块的类型参数,其中定义了方法new
! impl 块不需要具有与类型本身相同、一样多或相同的默认类型参数。
在这种特殊情况下,该结构具有参数 HashMap<K, V, S = RandomState>
(3 个参数,1 个默认)。并且包含 ::new()
的 impl 块具有参数 impl<K, V>
(2 个参数,未针对任意状态实现)。