1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
/// 创建一个包含参数的 [`Vec`]。
///
/// `vec!` 允许使用与数组表达式相同的语法定义 Vec。
/// 该宏有两种形式:
///
/// - 创建一个包含给定元素列表的 [`Vec`]:
///
/// ```
/// let v = vec![1, 2, 3];
/// assert_eq!(v[0], 1);
/// assert_eq!(v[1], 2);
/// assert_eq!(v[2], 3);
/// ```
///
/// - 根据给定的元素和大小创建 [`Vec`]:
///
/// ```
/// let v = vec![1; 3];
/// assert_eq!(v, [1, 1, 1]);
/// ```
///
/// 请注意,与数组表达式不同,此语法支持所有实现 [`Clone`] 的元素,并且元素的数量不必是常量。
///
/// 这将使用 `clone` 复制表达式,因此在具有非标准 `Clone` 实现的类型上使用此表达式时应格外小心。
/// 例如,`vec![Rc::new(1); 5]` 将对相同的 boxed 整数值创建五个引用的 vector,而不是对 boxed 整数独立引用的五个引用。
///
///
/// 另外,请注意,允许使用 `vec![expr; 0]`,并产生一个空的 vector。
/// 然而,这仍然会计算 `expr`,并立即丢弃结果值,因此请注意副作用。
///
/// [`Vec`]: crate::vec::Vec
///
///
///
///
///
#[cfg(all(not(no_global_oom_handling), not(test)))]
#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_diagnostic_item = "vec_macro"]
#[allow_internal_unstable(rustc_attrs, liballoc_internals)]
macro_rules! vec {
() => (
$crate::__rust_force_expr!($crate::vec::Vec::new())
);
($elem:expr; $n:expr) => (
$crate::__rust_force_expr!($crate::vec::from_elem($elem, $n))
);
($($x:expr),+ $(,)?) => (
$crate::__rust_force_expr!(<[_]>::into_vec(
// 这个 rustc_box 不是必需的,但它在构造具有许多元素的数组时会显着缩短编译时间。
//
#[rustc_box]
$crate::boxed::Box::new([$($x),+])
))
);
}
// HACK(japaric): 对于 cfg(test),此宏定义所需的固有 `[T]::into_vec` 方法不可用。
// 而是使用仅适用于 cfg (test) 的 `slice::into_vec` 函数。
// NB 有关更多信息,请参见 slice.rs 中的 slice::hack 模块
//
#[cfg(all(not(no_global_oom_handling), test))]
#[allow(unused_macro_rules)]
macro_rules! vec {
() => (
$crate::vec::Vec::new()
);
($elem:expr; $n:expr) => (
$crate::vec::from_elem($elem, $n)
);
($($x:expr),*) => (
$crate::slice::into_vec($crate::boxed::Box::new([$($x),*]))
);
($($x:expr,)*) => (vec![$($x),*])
}
/// 使用运行时表达式的插值创建 `String`。
///
/// `format!` 收到的第一个参数是格式字符串。这必须是字符串字面量。格式字符串的作用是包含在 {{} 中。
///
/// 除非使用命名或位置参数,否则传递给 `format!` 的其他参数将以给定的顺序替换格式字符串中的 {}。有关更多信息,请参见 [`std::fmt`]。
///
///
/// `format!` 的常见用法是字符串的连接和内插。
/// [`print!`] 和 [`write!`] 宏使用相同的约定,具体取决于字符串的预期目标。
///
/// 要将单个值转换为字符串,请使用 [`to_string`] 方法。这将使用 [`Display`] 格式 trait。
///
/// [`std::fmt`]: ../std/fmt/index.html
/// [`print!`]: ../std/macro.print.html
/// [`write!`]: core::write
/// [`to_string`]: crate::string::ToString
/// [`Display`]: core::fmt::Display
///
/// # Panics
///
/// 如果格式化 trait 实现返回了错误,则会出现 `format!` panics。
/// 这表明实现不正确,因为 `fmt::Write for String` 本身从不返回错误。
///
/// # Examples
///
/// ```
/// format!("test");
/// format!("hello {}", "world!");
/// format!("x = {}, y = {y}", 10, y = 30);
/// let (x, y) = (1, 2);
/// format!("{x} + {y} = 3");
/// ```
///
///
///
///
///
#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "format_macro")]
macro_rules! format {
($($arg:tt)*) => {{
let res = $crate::fmt::format($crate::__export::format_args!($($arg)*));
res
}}
}
/// 强制 AST 节点使用表达式以改善模式位置的诊断。
#[doc(hidden)]
#[macro_export]
#[unstable(feature = "liballoc_internals", issue = "none", reason = "implementation detail")]
macro_rules! __rust_force_expr {
($e:expr) => {
$e
};
}