问题描述
让我们假设我们有一个点的向量,这些点被写成平坦的整数序列。向量的大小是精确的,我们希望将其转换为Point
结构的向量。所以我的转换目前看起来像这样。
#[derive(Debug)]
struct Point {
x: i32,y: i32,}
impl Point {
fn new(x: i32,y : i32) -> Point {
Point{x,y}
}
}
impl From<Point> for String {
fn from(point: Point) -> String {
format!("({},{})",point.x,point.y)
}
}
fn main() {
let vec = vec![2,1,4,3,6,5]; // We want convert that
let even = vec.iter().step_by(2);
let odd = vec.iter().skip(1).step_by(2);
let points: Vec<Point>
= even.zip(odd)
.map(|(x,y)|Point::new(*x,*y))
.collect();
println!("{:?}",points);
}
工作就像一个咒语,直到我们想要添加z
组件,并每个周期窥探三个元素。我没有从docs中找到任何合适的方法。因此,是否已有一种通用方法可以遍历vector上某个大小的切片并将其解压缩到我的struct中,或者没有这种方法,我应该自己实现这种迭代器?使用诸如serde
之类的较重的机器是否有信号。
解决方法
使用chunks_exact在std中轻松进行切片。
#[derive(Debug)]
struct Point {
x: i32,y: i32,z: i32,}
impl Point {
fn new(x: i32,y : i32,z: i32) -> Point {
Point{x,y,z}
}
}
fn main() {
let vec = vec![2,1,4,3,6,5];
let points: Vec<Point>
= vec.chunks_exact(3)
.map(|chunk|Point::new(chunk[0],chunk[1],chunk[2]))
.collect();
println!("{:?}",points);
}
,
我认为没有预先完成的方法,但是您可以轻松编写可快速调整以包含第三个z
组件的代码,类似于此(Playground ):
#[derive(Debug,Default)]
struct PointBuilder {
x: Option<i32>,y: Option<i32>,// add a z here
}
impl PointBuilder {
fn add(&mut self,value: i32) {
if self.x.is_none() {
self.x = Some(value);
} else if self.y.is_none() {
self.y = Some(value);
}
// add a z here
}
fn try_build(&self) -> Option<Point> {
// and one last z in this match expression
match (self.x,self.y) {
(Some(x),Some(y)) => Some(Point::new(x,y)),_ => None,}
}
}
fn convert_to_points(data: impl IntoIterator<Item = i32>) -> Vec<Point> {
data.into_iter()
.fold((PointBuilder::default(),Vec::<Point>::new()),|(mut builder,mut points),value| {
builder.add(value);
if let Some(point) = builder.try_build() {
points.push(point);
(PointBuilder::default(),points)
} else {
(builder,points)
}
})
.1
}
fn main() {
let vec = vec![2,5]; // We want convert that
let points = convert_to_points(vec);
println!("{:?}",points);
}
如果您需要数十个结构,当然可以将其作为proc-macro-derived代码生成器来完成,但是我不知道已经实现了此功能的任何库,因此,这取决于您的用例值得付出努力。