Zipper. : , , , .
:
use std::mem;
use std::marker::PhantomData;
pub enum List<T> {
Empty,
Cons { head: T, tail: Box<List<T>> },
}
pub struct Zipper<'a, T: 'a> {
trail: Option<Box<Zipper<'a, T>>>,
focus: *mut List<T>,
_list: PhantomData<&'a mut List<T>>,
}
impl<'a, T: 'a> Zipper<'a, T> {
pub fn new(list: &'a mut List<T>) -> Zipper<'a, T> {
Zipper {
trail: None,
focus: list as *mut List<T>,
_list: PhantomData,
}
}
pub fn down(&mut self) {
unsafe {
match *self.focus {
List::Empty => (),
List::Cons {
tail: ref mut xs, ..
} => {
let old_zipper = mem::replace(
self,
Zipper::new(xs),
);
self.trail = Some(Box::new(old_zipper));
}
}
}
}
}
fn main() {
let mut list = List::Cons { head: 1, tail: Box::new(List::Empty) };
let mut zipper = Zipper::new(&mut list);
zipper.down();
zipper.down();
}
focus Zipper *mut List<T>. , . Zipper::down. _list PhantomData<&'a mut List<T>>. PhantomData - , ", / T, " ". , 'a .
, Zipper::new &'a mut List<T> : Zipper , , List<T>, , , . , Zipper List; List, Zipper List , , List .
, Zipper. , , , , . :
impl<'a, T: 'a> Zipper<'a, T> {
pub fn focus(&mut self) -> &'a mut List<T> {
unsafe { &mut *self.focus }
}
}
a &'a mut List<T>, , . , self, , focus, List<T>. &'a mut List<T> Zipper, , &'a mut List<T> ( unsafe, ). :
impl<'a, T: 'a> Zipper<'a, T> {
pub fn focus(&mut self) -> &mut List<T> {
unsafe { &mut *self.focus }
}
}
, Zipper , &mut List<T>, , focus ( down) , &mut List<T> .