将枚举值的向量转换为另一个向量

时间:2016-08-08 19:29:19

标签: serialization iterator rust

我有以下代码,它从传递的枚举值向量生成一个字节向量:

return \Redirect::route('route-name-here');

但是在编译时,我在迭代#[derive(Debug, PartialEq)] pub enum BertType { SmallInteger(u8), Integer(i32), Float(f64), String(String), Boolean(bool), Tuple(BertTuple), } #[derive(Debug, PartialEq)] pub struct BertTuple { pub values: Vec<BertType> } pub struct Serializer; pub trait Serialize<T> { fn to_bert(&self, data: T) -> Vec<u8>; } impl Serializer { fn enum_value_to_binary(&self, enum_value: BertType) -> Vec<u8> { match enum_value { BertType::SmallInteger(value_u8) => self.to_bert(value_u8), BertType::Integer(value_i32) => self.to_bert(value_i32), BertType::Float(value_f64) => self.to_bert(value_f64), BertType::String(string) => self.to_bert(string), BertType::Boolean(boolean) => self.to_bert(boolean), BertType::Tuple(tuple) => self.to_bert(tuple), } } } // some functions for serialize bool/integer/etc. into Vec<u8> // ... impl Serialize<BertTuple> for Serializer { fn to_bert(&self, data: BertTuple) -> Vec<u8> { let mut binary: Vec<u8> = data.values .iter() .map(|&item| self.enum_value_to_binary(item)) // <-- what the issue there? .collect(); let arity = data.values.len(); match arity { 0...255 => self.get_small_tuple(arity as u8, binary), _ => self.get_large_tuple(arity as i32, binary), } } } 时收到错误:

map

如何使用error: the trait bound `std::vec::Vec<u8>: std::iter::FromIterator<std::vec::Vec<u8>>` is not satisfied [E0277] .collect(); ^~~~~~~ help: run `rustc --explain E0277` to see a detailed explanation note: a collection of type `std::vec::Vec<u8>` cannot be built from an iterator over elements of type `std::vec::Vec<u8>` error: aborting due to previous error error: Could not compile `bert-rs`. 解决此问题?

1 个答案:

答案 0 :(得分:2)

问题在于enum_value_to_binaryVec<u8>中的每个元素返回values。所以你得到一个Iterator<Item=Vec<u8>>,然后你就可以调用collect::<Vec<u8>>(),但它不知道如何展平嵌套的向量。如果您希望将所有值展平为一个Vec<u8>,则应使用flat_map代替map

let mut binary: Vec<u8> = data.values
            .iter()
            .flat_map(|item| self.enum_value_to_binary(item).into_iter()) 
            .collect();

或者,稍微更具惯用性和性能,您可以让enum_value_to_binary直接返回迭代器。

此外,iter方法返回Iterator<Item=&'a T>,这意味着您只是借用元素,但self.enum_value_to_binary想要对该值取得所有权。有几种方法可以解决这个问题。一种选择是使用into_iter而不是iter,这将按值为您提供元素。如果您这样做,则会将arity变量移至binary变量之前,因为创建binary变量将取得所有权(移动)data.values

另一种选择是改变self.enum_value_to_binary以引用它的论点。

您也可能认为binary的类型实际上是Vec<Vec<u8>>