citahub/cita_trie

Remove unnecessarily `clone`

yangby-cryptape opened this issue · 2 comments

u2 commented

Self is a mutable reference, so the root has to be cloned.

My Opinion

Self is a mutable reference, so the root has to be cloned.

No! The clone is not required.

I think I can write a version without clone. (trying ...; it is really simple, but it is too difficult to modify this without some prerequisites.)

An Example

An example to show how I plan to rewrite it:

#[derive(Debug)]
pub struct A {
    inner: B,
}

impl A {
    // Minus `n` for all nodes, if `result < 0`, replace it by Null.
    pub fn minus(&mut self, n: usize) {
        self.inner.minus(n)
    }
    
    pub fn not_null(&self) -> bool {
        !self.inner.is_null()
    }
}

#[derive(Debug, PartialEq)]
pub enum B {
    Null,
    Ref([Box<B>; 2]),
    Val(usize),
}

impl B {
    pub fn is_null(&self) -> bool {
        *self == B::Null    
    }
    
    pub fn minus(&mut self, n: usize) {
        let be_null = match self {
            B::Val(ref mut v) => {
                if *v >= n {
                    *v -= n;
                    false
                } else {
                    true 
                }
            }
            B::Ref([x, y]) => {
                x.minus(n);
                y.minus(n);
                x.is_null() && y.is_null()
            }
            B::Null => false,
        };
        if be_null {
            *self = B::Null
        }
    }
}

fn main() {
    let inner = {
        let b1 = B::Val(1);
        let b2 = B::Val(2);
        let b3 = B::Val(3);
        let b4 = B::Val(4);
        let bn = B::Null;

        let b5 = B::Ref([Box::new(b2), Box::new(b3)]);
        let b6 = B::Ref([Box::new(bn), Box::new(b1)]);
        let b7 = B::Ref([Box::new(b5), Box::new(b4)]);

        B::Ref([Box::new(b6), Box::new(b7)])
    };

    let mut a = A { inner };
    
    while a.not_null() {
        println!("A = {:?}", a);
        a.minus(1);
    }
}