Rust中的只读取消引用

时间:2017-01-03 05:55:43

标签: rust

我试图在两个链接列表中逐个添加数字:

use List::*;

enum List {
    Cons(i32, Box<List>),
    Nil,
}

impl List {
    fn stringify(&self) -> String {
        match *self {
            Cons(a, ref tail) => format!("{}, {}", a, tail.stringify()),
            Nil => format!("Nil")
        }
    }
}

fn dissolve_number(num: i32) -> List {
    match num {
        0 => Nil,
        n => Cons(n % 10, Box::new(dissolve_number(n / 10)))
    }
}

fn add_with_inc(a: &List, b: &List, inc: bool) -> List {
    match (*a, *b, inc) {
        (Nil, Nil, false) => Nil,
        (Nil, Nil, true) => Cons(1, Box::new(Nil)),
        (Nil, Cons(j, ref btail), false) => Cons(j, Box::new(add_with_inc(&Nil, btail, false))),
        (Nil, Cons(j, ref btail), true) => Cons((j + 1) % 10, Box::new(add_with_inc(&Nil, btail, (j + 1) >= 10))),
        (Cons(i, ref atail), Nil, false) => Cons(i, Box::new(add_with_inc(atail, &Nil, false))),
        (Cons(i, ref atail), Nil, true) => Cons((i + 1) % 10, Box::new(add_with_inc(atail, &Nil, (i + 1) >= 10))),
        (Cons(i, ref atail), Cons(j, ref btail), false) => Cons((i + j) % 10, Box::new(add_with_inc(atail, btail, (i + j) >= 10))),
        (Cons(i, ref atail), Cons(j, ref btail), true) => Cons((i + j + 1) % 10, Box::new(add_with_inc(atail, btail, (i + j + 1) >= 10)))
    }
}

fn add(a: &List, b: &List) -> List {
    add_with_inc(a, b, false)
}

fn main() {
    let (la, lb) = (dissolve_number(123), dissolve_number(223));
    let lsum = add(&la, &lb);
    println!("{}", lsum.stringify());
}

编译器抱怨:

error[E0507]: cannot move out of borrowed content
  --> add_two_numbers.rs:25:12
   |
25 |     match (*a, *b, inc) {
   |            ^^ cannot move out of borrowed content

error[E0507]: cannot move out of borrowed content
  --> add_two_numbers.rs:25:16
   |
25 |     match (*a, *b, inc) {
   |                ^^ cannot move out of borrowed content

搜索之后,我发现错误是由于解除引用的变量引起的。有没有办法从参考中获取List的只读副本?

我修改了一些代码,但我仍然无法使其正常工作......

fn add_with_inc(a: &List, b: &List, inc: bool) -> List {
    match (a, b, inc) {
        (ref Nil, ref Nil, false) => Nil,
        (ref Nil, ref Nil, true) => Cons(1, Box::new(Nil)),
        (ref Nil, ref Cons(j, ref btail), false) => Cons(j, Box::new(add_with_inc(&Nil, btail, false))),
        (ref Nil, ref Cons(j, ref btail), true) => Cons((j + 1) % 10, Box::new(add_with_inc(&Nil, btail, (j + 1) >= 10))),
        (ref Cons(i, ref atail), ref Nil, false) => Cons(i, Box::new(add_with_inc(atail, &Nil, false))),
        (ref Cons(i, ref atail), ref Nil, true) => Cons((i + 1) % 10, Box::new(add_with_inc(atail, &Nil, (i + 1) >= 10))),
        (ref Cons(i, ref atail), ref Cons(j, ref btail), false) => Cons((i + j) % 10, Box::new(add_with_inc(atail, btail, (i + j) >= 10))),
        (ref Cons(i, ref atail), ref Cons(j, ref btail), true) => Cons((i + j + 1) % 10, Box::new(add_with_inc(atail, btail, (i + j + 1) >= 10)))
    }
}

1 个答案:

答案 0 :(得分:1)

使用ref替换&无法解除引用。

use List::*;

enum List {
    Cons(i32, Box<List>),
    Nil,
}

impl List {
    fn stringify(&self) -> String {
        match *self {
            Cons(a, ref tail) => format!("{}, {}", a, tail.stringify()),
            Nil => format!("Nil")
        }
    }
}

fn dissolve_number(num: i32) -> List {
    match num {
        0 => Nil,
        n => Cons(n % 10, Box::new(dissolve_number(n / 10)))
    }
}

fn add_with_inc(a: &List, b: &List, inc: bool) -> List {
    match (a, b, inc) {
        (&Nil, &Nil, false) => Nil,
        (&Nil, &Nil, true) => Cons(1, Box::new(Nil)),
        (&Nil, &Cons(j, ref btail), false) => Cons(j, Box::new(add_with_inc(&Nil, btail, false))),
        (&Nil, &Cons(j, ref btail), true) => Cons((j + 1) % 10, Box::new(add_with_inc(&Nil, btail, (j + 1) >= 10))),
        (&Cons(i, ref atail), &Nil, false) => Cons(i, Box::new(add_with_inc(atail, &Nil, false))),
        (&Cons(i, ref atail), &Nil, true) => Cons((i + 1) % 10, Box::new(add_with_inc(atail, &Nil, (i + 1) >= 10))),
        (&Cons(i, ref atail), &Cons(j, ref btail), false) => Cons((i + j) % 10, Box::new(add_with_inc(atail, btail, (i + j) >= 10))),
        (&Cons(i, ref atail), &Cons(j, ref btail), true) => Cons((i + j + 1) % 10, Box::new(add_with_inc(atail, btail, (i + j + 1) >= 10)))
    }
}

fn add(a: &List, b: &List) -> List {
    add_with_inc(a, b, false)
}

fn main() {
    let (la, lb) = (dissolve_number(123), dissolve_number(223));
    let lsum = add(&la, &lb);
    println!("{}", lsum.stringify());
}