我正在尝试在生锈中实施tree fold。我的first attempt按预期编译并运行。
pub enum Tree<T> {
Leaf,
Node(Box<Tree<T>>, T, Box<Tree<T>>)
}
impl<T, U: Copy> Tree<T> {
fn fold(self, f: |l: U, x: T, r: U| -> U, acc: U) -> U {
match self {
Leaf => acc,
Node(box l, x, box r) => {
let l = l.fold(|l,x,r| {f(l,x,r)}, acc);
let r = r.fold(|l,x,r| {f(l,x,r)}, acc);
f(l, x, r)
}
}
}
}
fn main() {
let tl = Node(box Leaf, 1i, box Leaf);
let tr = Node(box Leaf, 2i, box Leaf);
let t = Node(box tl, 3i, box tr);
println!("size(t) == {}", t.fold(|l,_,r|{l + 1i + r}, 0))
}
但是,当我尝试将size
impl
移到pub enum Tree<T> {
Leaf,
Node(Box<Tree<T>>, T, Box<Tree<T>>)
}
impl<T, U: Copy> Tree<T> {
fn fold(self, f: |l: U, x: T, r: U| -> U, acc: U) -> U {
match self {
Leaf => acc,
Node(box l, x, box r) => {
let l = l.fold(|l,x,r| {f(l,x,r)}, acc);
let r = r.fold(|l,x,r| {f(l,x,r)}, acc);
f(l, x, r)
}
}
}
fn size(self) -> uint {
self.fold(|l, _, r| {l + 1u + r}, 0u)
}
}
fn main() {
let tl = Node(box Leaf, 1i, box Leaf);
let tr = Node(box Leaf, 2i, box Leaf);
let t = Node(box tl, 3i, box tr);
println!("size(t) == {}", t.size())
}
块中以使其成为方法时:
<anon>:28:31: 28:39 error: cannot determine a type for this expression: unconstrained type
<anon>:28 println!("size(t) == {}", t.size())
^~~~~~~~
note: in expansion of format_args!
<std macros>:2:23: 2:77 note: expansion site
<std macros>:1:1: 3:2 note: in expansion of println!
<anon>:28:5: 29:2 note: expansion site
error: aborting due to previous error
playpen: application terminated with error code 101
Program ended.
我在防锈围栏中收到以下错误。
{{1}}
我希望有人能说清楚我做错了什么,以及如何解决它。
答案 0 :(得分:4)
你的两件事之间存在着重要的区别。
首先,你有这个:
t.fold(|l,x,r|{l + x + r}, 0)
在第二个中,你有这个(显示self
更改为t
):
t.fold(|l, x, r| {l + 1 + r}, 0)
看到区别? l + 1 + r
不是l + x + r
。
(从那时起,所有案例的大小都变为l + 1 + r
,而不是l + x + r
,总和。)
完成此操作后,您会遇到问题,因为uint
不是int
。您需要整理T
和U
。基本上,您希望l
,x
,r
和0
都属于同一类型,即之前的T
。这需要对T
:
必须Copy
,才能满足U
。
您必须能够T
添加T
并获得T
。这是std::num::Add<T, T>
。
您必须能够获得T
类型的零。这是std::num::Zero
特征和Zero::zero()
方法。
您必须能够获得T
类型的一个。这是std::num::One
特征和One::one()
方法。
虽然我们处于此状态,但U
可能应该是fold
函数的泛型,而不是impl
块,但要么会这样做。
最后,我们最终得到了functioning code:
use std::num::Zero;
pub enum Tree<T> {
Leaf,
Node(Box<Tree<T>>, T, Box<Tree<T>>)
}
impl<T> Tree<T> {
fn fold<U: Copy>(self, f: |l: U, x: T, r: U| -> U, acc: U) -> U {
match self {
Leaf => acc,
Node(box l, x, box r) => {
let l = l.fold(|l, x, r| f(l, x, r), acc);
let r = r.fold(|l, x, r| f(l, x, r), acc);
f(l, x, r)
}
}
}
}
impl<T: Copy + Add<T, T> + Zero + One> Tree<T> {
fn size(self) -> T {
self.fold(|l: T, _: T, r: T| l + One::one() + r, Zero::zero())
}
}
fn main() {
let tl = Node(box Leaf, 1i, box Leaf);
let tr = Node(box Leaf, 2i, box Leaf);
let t = Node(box tl, 3i, box tr);
println!("size(t) == {}", t.size())
}
(注意封闭内容周围的花括号也不是必需的。)