我有以下代码,它从传递的枚举值向量生成一个字节向量:
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`.
解决此问题?
答案 0 :(得分:2)
问题在于enum_value_to_binary
为Vec<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>>
。