(附註:這會,如果你使用的Result
類型,而不是與裏面的一個boolean元組可能會更好,我會跟你寫的這個答案雖然方式堅持下去。)
錯誤消息表示您不能使用移動的值t1
和t2
,因爲這些值在您取消引用並在它們上進行匹配時已移動。
已存儲在t1
和變量a
,w
t2
現已擁有的信息,並且在比賽中表現的一個分支,t
,所以你必須使用這些。如果我錯了,請糾正我。
所以,你可以去實現讓你的例子,如果,工作行內:
(t, b) => if b { (Term::Plus(t1, Box::new(t)), true) } else { (Term::Plus(t1, t2), false) }
您與Box::new(w)
替換t1
與Box::new(Term::Num(a))
,和t2
。也就是說,有一些的縮進,就是:
(t, b) => if b {
(Term::Plus(Box::new(Term::Num(a)), Box::new(t)), true)
} else {
(Term::Plus(Box::new(Term::Num(a)), Box::new(w)), false)
}
這也失敗,但因爲通話reduceOneStep(w)
注意到w
所有權。這可以是固定的通過使reduceOneStep
借用它的參數,而不是:
fn reduceOneStep(t: &Term) -> (Term, bool) {
match t {
&Term::Num(a) => (*t, false),
&Term::Plus(t1, t2) =>
match (*t1, *t2) {
(Term::Num(a), Term::Num(b)) => (Term::Num(a + b), true),
(Term::Num(a), w) =>
match reduceOneStep(&w) {
(t, b) => if b {
(Term::Plus(Box::new(Term::Num(a)), Box::new(t)), true)
} else {
(Term::Plus(Box::new(Term::Num(a)), Box::new(w)), false)
}
},
_ => (Term::Num(1), false) //ignore .. this is just to satisfy typing and totality
},
x => (Term::Num(1), false) //ignore .. this is just to satisfy typing and totality
}
}
但是,這裏有更多的錯誤,他說cannot move out of borrowed content
,指着它返回*t
。這是因爲它既不能將借款歸還給所有者,又要歸還其中的一部分,因爲可以釋放一部分,而另一部分可以留下。解決這個問題的方法之一是#[derive(Clone)]
爲Term
枚舉,並使用:
fn reduceOneStep(t: &Term) -> (Term, bool) {
match t {
&Term::Num(a) => (t.clone(), false),
&Term::Plus(t1, t2) =>
match (*t1, *t2) {
(Term::Num(a), Term::Num(b)) => (Term::Num(a + b), true),
(Term::Num(a), w) =>
match reduceOneStep(&w) {
(t, b) => if b {
(Term::Plus(Box::new(Term::Num(a)), Box::new(t)), true)
} else {
(Term::Plus(Box::new(Term::Num(a)), Box::new(w.clone())), false)
}
},
_ => (Term::Num(1), false) //ignore .. this is just to satisfy typing and totality
},
x => (Term::Num(1), false) //ignore .. this is just to satisfy typing and totality
}
}
但是,這仍然具有相同的錯誤。呵呵。錯誤消息在它下面有這個提示:help: to prevent the move, use `ref t1` or `ref mut t1` to capture value by reference
。然後固定的一些類型不匹配,並與框擺弄derefs借用和之後,我終於得到這個工作:
fn reduceOneStep(t: &Term) -> (Term, bool) {
match t {
&Term::Num(a) => (t.clone(), false),
&Term::Plus(ref t1, ref t2) =>
match (&**t1, &**t2) {
(&Term::Num(a), &Term::Num(b)) => (Term::Num(a + b), true),
(&Term::Num(a), w) =>
match reduceOneStep(&w) {
(t, b) => if b {
(Term::Plus(Box::new(Term::Num(a)), Box::new(t)), true)
} else {
(Term::Plus(Box::new(Term::Num(a)), Box::new(w.clone())), false)
}
},
_ => (Term::Num(1), false) //ignore .. this is just to satisfy typing and totality
},
x => (Term::Num(1), false) //ignore .. this is just to satisfy typing and totality
}
}
我和防鏽一個初學者,現在,如果有人能幫助我理解爲什麼這個工程,我我會非常感激。
是的,枚舉是Rust實現ADT的方式。 –
@Shepmaster:對不起,我很困惑。我的第一個「問題」並不是真正的問題。這是修辭,我的解釋是我試圖反映一段Haskell代碼。但是,我是這種語言的新手,所以如果有人對我的數據類型有什麼建議,我很樂意聽到這個消息,這似乎是合理的。我改變了這個問題來反映這一點。 –