【发布时间】:2017-03-30 08:32:27
【问题描述】:
我正在用 Rust 磨牙,我正在尝试实现一个通用类型的链表。到目前为止,我的 cons 和 len 函数可以正常工作,但 map 有问题,我无法弄清楚。
use std::fmt;
#[derive(Debug)]
enum List<A> {
Empty,
Cons(A, Box<List<A>>),
}
fn cons<A>(x: A, xs: List<A>) -> List<A> {
return List::Cons(x, Box::new(xs));
}
fn len<A>(xs: List<A>) -> i32 {
match xs {
List::Empty => 0,
List::Cons(_, xs) => 1 + len(*xs),
}
}
fn map<A, B>(f: &Fn(A) -> B, xs: List<A>) -> List<B> {
match xs {
List::Empty => List::Empty,
List::Cons(x, xs) => cons(f(x), map(f, *xs)),
}
}
fn main() {
let xs = cons(1, cons(2, cons(3, List::Empty)));
println!("{:?}", xs);
println!("{:?}", len(xs));
let f = |x: i32| x * x;
println!("{:?})", map(f, xs));
}
错误
error[E0308]: mismatched types
--> src/main.rs:32:27
|
32 | println!("{:?})", map(f, xs));
| ^ expected reference, found closure
|
= note: expected type `&std::ops::Fn(_) -> _`
found type `[closure@src/main.rs:31:13: 31:27]`
预期输出
Cons(1, Cons(2, Cons(3, Empty)))
3
Cons(1, Cons(4, Cons(9, Empty)))
我的特殊问题是
println!("{:?})", map(f, xs));
如果我将该行注释掉,则输出的前两行是正确的。我不确定我的map 电话有什么问题
更新
aochagavia 帮助我理解了函数引用问题和第一个所有权问题(显然是很多问题!) - 我在使用 len 和 map 中使用的相同技术时遇到了问题,并遇到了一个新错误
我更新后的map 函数如下所示
fn map<A, B>(f: &Fn(A) -> B, xs: &List<A>) -> List<B> {
match *xs {
List::Empty => List::Empty,
List::Cons(x, ref xs) => cons(f(x), map(f, xs)),
}
}
我正在尝试这个
let f = |x: i32| x * x;
let ys = map(&f, &xs);
let zs = map(&f, &xs);
println!("{:?})", ys);
println!("{:?})", zs);
新的错误是这样的
error[E0009]: cannot bind by-move and by-ref in the same pattern
--> src/main.rs:23:20
|
23 | List::Cons(x, ref xs) => cons(f(x), map(f, xs)),
| ^ ------ both by-ref and by-move used
| |
| by-move pattern here
【问题讨论】:
-
我正在用 Rust 磨牙 => 祝你好运 :) 一开始可能需要一些工作来解决所有权/借款问题,但我保证前进变得更容易!当您遇到问题时,请不要犹豫仔细阅读 SO,如果您需要一些不适合此处的讨论/建议,您可以加入 IRC (chat.mibbit.com/…)、reddit (reddit.com/r/rust) 或用户论坛 ( users.rust-lang.org).
-
@MatthieuM.谢谢您的热烈欢迎。到目前为止,我发现 Rust 非常有趣,但是是的,其中一些事情真的让我陷入了困境。到目前为止,我使用过的任何语言都没有可比性(据我所知)。
标签: generics polymorphism rust