借用检查练习瑜伽:在自己的类型中包装std :: vec :: Vec并调整iter_mut

时间:2018-02-19 10:40:49

标签: iterator rust

为了实现二维矢量类型,我尝试将std::vec::Vec包装在我自己的结构中并实现一个二维可变迭代器。我知道,由于this,这在安全的Rust中是不可能的。

如何安全地防止不安全生锈?

以下示例是基本的最小示例:

struct TwoDimVector<T> where T : Default + Clone {
    vector : std::vec::Vec<T>,
    x_dim : u32,
    y_dim : u32
} 

impl<T> TwoDimVector<T> where T : Default + Clone {
    fn new(x_dim : u32, y_dim : u32) -> TwoDimVector<T> {
       let vector = std::vec::Vec::new();
       vector.resize((x_dim * y_dim) as usize, T::default());
       TwoDimVector { vector, x_dim, y_dim } 
    }
    fn get_mut(&mut self, (x,y) : (u32, u32)) -> Option<&mut T> { 
        self.vector.get_mut((y * self.x_dim + x) as usize) 
    } 
    fn iter_mut<'a>(&'a mut self, start : (u32, u32), end : (u32, u32)) -> 
        TwoDimVectorIterMut<'a, T> {
        TwoDimVectorIterMut::new(self, start, end, self.x_dim, self.y_dim)
    } 
} 

pub struct TwoDimVectorIterMut<'a, T : 'a> where T : Default + Clone {
    vector : &'a mut TwoDimVector<T>,
    start : (u32, u32),
    end : (u32, u32),
    current : (u32, u32),
    invalid : bool
}  

impl<'a, T> TwoDimVectorIterMut<'a, T> where T : 'a + Default + Clone {
    fn new(vector : &'a mut TwoDimVector<T>, start : (u32, u32), end : (u32, 
        u32), x_dim : u32, y_dim : u32) -> TwoDimVectorIterMut<'a, T> {
        use std::cmp::{min, max};
        let start : (u32, u32) = start.into();
        let end : (u32, u32) = end.into();
        TwoDimVectorIterMut { 
            start : (min(start.0, max(x_dim, 1) - 1), 
                     min(start.1, max(y_dim, 1) - 1)), 
            end :  (min(end.0, max(x_dim, 1) - 1), 
                    min(end.1, max(y_dim, 1) - 1)),
            current : (start.0, start.1 ),  
            invalid : x_dim == 0 || y_dim == 0,
            vector : vector
        }
    }
    fn advance(&mut self) -> Option<(u32, u32)> {
        let current = self.current;
        if self.invalid || current.0 > self.end.0 || current.1 > self.end.1 {
            return None
        }
        if self.current.0 == self.end.0 {
            self.current.0 = self.start.0;
            self.current.1 += 1; 
        } else {
            self.current.0 += 1;
        }    
        return Some(current);
    } 
}

impl<'a, T> Iterator for TwoDimVectorIterMut<'a, T> where T : Default + Clone 
{
    type Item = &'a mut T;

    fn next(&mut self) -> Option<Self::Item> {
        let point = self.advance();
        if let Some(point) = point {
            unsafe {
              self.vector.get_mut(point) // what to write here??
            }
        } else {
            None
        }
    }
}    

链接到Rust playground

0 个答案:

没有答案