在vec!宏实现中有这样的规则:
($($x:expr),+ $(,)?) => (
$crate::__rust_force_expr!(<[_]>::into_vec(box [$($x),+]))
);
Run Code Online (Sandbox Code Playgroud)
<[_]>里面到底是什么?
kmd*_*eko 30
分解语法的特定部分:
<T>::ff是显式调用与类型关联的语法T。通常 justT::f就足够了,但迂腐地说,::需要一个path,这就是为什么在这里使用它,因为[_]不是。允许<...>将任何类型用作路径。请参阅为什么在实现基于类型的宏时需要在 <$a> 中使用尖括号?[T]是表示 type 的切片的类型T。_用作类型的是占位符或“通配符”。它本身不是类型,但用于指示应该推断类型。请参阅使用下划线实例化 Rust 泛型意味着什么?loo*_*ops 15
让我们一步步看看如何<[_]>::into_vec(box [$($x),+])生成 a Vec:
[$($x),+]扩展为输入元素数组:[1, 2, 3]box ...将其放入Box. box表达式是仅限夜间使用的语法糖 for Box::new:box 5是语法糖 for Box::new(5)(实际上是相反的:内部Box::new使用box,它是在编译器中实现的)<[_]>::into_vec(...)to_vec对包含具有推断类型 ( ) 的元素的切片调用该方法[_]。出于[_]语法原因,需要将 括在尖括号中以调用切片类型上的方法。Andinto_vec是一个函数,它接受一个装箱切片并生成一个Vec:
pub fn into_vec<A: Allocator>(self: Box<Self, A>) -> Vec<T, A> {
// ...
}
Run Code Online (Sandbox Code Playgroud)
这可以通过许多更简单的方法来完成,但此代码经过微调以提高vec!. Vec例如,由于可以提前知道的大小,into_vec因此不会导致Vec在构造期间重新分配 。