遍历向量并将枚举转换为整数

时间:2019-05-28 00:26:21

标签: rust

我有一个枚举向量,我想将其转换为整数值,以便进行数值比较。

我不断遇到借用警告“无法移出借用上下文”

我尝试了以下各种排列:

enum SomeEnum {
    A,
    B,
    C,
}

let values = vec![SomeEnum::A, SomeEnum::B];

for val in values.iter() {
  let i = *val as i32;
  // if i < X do something
}

2 个答案:

答案 0 :(得分:5)

调用values.iter()时,您将Vec tor作为切片引用,因为它是impls Deref<Target=[T]>。它在借用的Iterator上返回&T。然后,您尝试以下行:

let i = *val as i32;

这有一个问题:val的类型为&SomeEnum,因此您不能将值移出引用,而不能将其移出引用或复制它们,因为{{ 1}}并不暗示SomeEnumCopy。要解决此问题,您可以根据情况从以下选项中进行选择:

    通过使Clone Copy
  • Copy的值。这样做会导致rust隐式按位复制值。
enum
  • 在迭代器上使用Iterator::copied扩展名。这将复制每个值,使其迭代器产生#[derive(Copy)] enum SomeEnum { A, B, C, } 而不是T。还要注意,当前这是一个每晚的api,因此您必须等待一会儿才能使其稳定。
&T
  • 将其克隆。 Clone是一种特性,它允许实现者使用#[derive(Copy)] enum SomeEnum { A, B, C, } let values = vec![SomeEnum::A, SomeEnum::B]; for val in values.iter().copied() { let i = val as i32; } 复制数据的方式,但也可以执行另一种操作,以防简单地按位impl进行复制是不安全的。
Copy
  • 使用Iterator::cloned。再次与#[derive(Clone)] enum SomeEnum { A, B, C, } 类似,除了Iterator::copied是对象并且稳定之外。
Clone
  • 使用#[derive(Clone)] enum SomeEnum { A, B, C, } let values = vec![SomeEnum::A, SomeEnum::B]; for val in values.iter().cloned() { let i = val as i32; } 。这样一来,您就可以不再使用Vec,而是在Vec中使用每个值。这是最不灵活的方法,由于您将其移至into_iter(self)中,因此导致您无法访问Vec
values

还有其他几种方法可以解决此问题,但这是最简单的方法。

其他解决方法是:

  • 自定义enum SomeEnum { A, B, C, } let values = vec![SomeEnum::A, SomeEnum::B]; for val in values.into_iter() { let i = val as i32; } 的数学运算
  • 实施impl特质,以使其更明显地表明您正在转换。

答案 1 :(得分:2)

iter使用对元素的引用遍历集合。 into_iter(会引起移动)将使您可以访问实际元素。如果您接受此举,可以帮助简化枚举序数值的转换:

for val in values.into_iter() {
    let i = val as i32;
    // if i < X do something
}

或者,如果您希望能够再次迭代载体,则可以使用克隆:

#[derive(Clone)]
enum SomeEnum {
    A,
    B,
    C,
}

允许在分配枚举值的新实例后进行强制转换:

let values = vec![SomeEnum::A, SomeEnum::B];
for val in values.iter() {
    let i = (val.clone()) as i32;
    // if i < X do something
}