如何使用vec宏创建特定数据类型的Vec?

4

类似 let v = vec![1, 2, 3]; 这样的语句默认类型为 i32,但我想指定类型为 u8

其中一种替代方式是使用:

let v: Vec<u8> = vec![1, 2, 3];


let v: Vec<u8> = Vec::new();
v.push(1);
v.push(2);
v.push(3);

有没有更好的方法直接使用宏?在这两种情况下,我都需要声明变量。

有时候,我需要在 assert 语句中使用向量。如果有一种方法可以避免创建变量,我可以这样写:

pub fn func1() -> &[u8] {
  // return slice [1, 2, 3] of [u8];
}
assert_eq!(vec![1, 2, 3], func1());

你可以很容易地定义自己的宏来执行let v = tvec![u8; 1, 2, 3];操作。 - Denys Séguret
pub fn func1() -> &[u8] 也是无效的。 - Shepmaster
@DenysSéguret - 自定义宏是如何工作的? - Coder
1
@VikasGoel,macro_rules! 对于像这样简单的代码来说非常简单,因此您应该查看它们,但在您的特定情况下,您应该像Ikolbly建议的那样简单地执行:vec![1u8,2,3] - Denys Séguret
2个回答

9

在这种情况下,向量的类型将自动推断。以下代码可以编译通过:

fn func1() -> Vec<u8> {
    vec![1, 2, 3]
}

fn main() {
    assert_eq!(func1(), vec![1, 2, 3]);
}

如果需要显式指定类型,可以这样做:vec![1u8, 2, 3]


您能否扩展一下您的答案,阐明为什么这是“惯用的方式”,正如OP所请求的那样? - Shepmaster
2
那是个好问题,实际上我不知道。我从未考虑过可能有其他的方法来处理它(就这个特定情况下使用assert_eq来说)。 - lkolbly

3

虽然我不确定这种方式是否习惯用语,但我建议

vec![1, 2, 3] as Vec<u8>

或者按照建议定义一个宏:

macro_rules! tvec [
    ($t:ty; $($e:expr),*) => { vec![$($e as $t),*] as Vec<$t> }
];

并且可以像这样使用tvec![u8; 1, 2, 3]。即使是空向量也适用。 这里有一个示例


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接