Pointers 如何使用Rust编写正确的映射函数?

Pointers 如何使用Rust编写正确的映射函数?,pointers,rust,Pointers,Rust,使用以下链接列表定义: enum List<T> { Nil, Cons(T, ~List<T>) } fn map<T1, T2>(f: |T1| -> T2, xs: &List<T1>) -> ~List<T2> { ... } 显然,在进行模式匹配时,内部模式必须具有相同的移动语义,没有混合和匹配。让我们尝试在x模式之前添加ref: fn map<T1, T2>(f: |T1|

使用以下链接列表定义:

enum List<T> {
    Nil,
    Cons(T, ~List<T>)
}
fn map<T1, T2>(f: |T1| -> T2, xs: &List<T1>) -> ~List<T2> { ... }
显然,在进行模式匹配时,内部模式必须具有相同的移动语义,没有混合和匹配。让我们尝试在
x
模式之前添加
ref

fn map<T1, T2>(f: |T1| -> T2, xs: &List<T1>) -> ~List<T2> {
    match xs {
        &Nil => ~Nil,
        &Cons(ref x, ~ref rest) => ~Cons(f(x), map(f, rest))
    }
}

demo.rs:25:44: 25:45 error: mismatched types: expected `T1` but found `&T1` (expected type parameter but found &-ptr)
demo.rs:25         &Cons(ref x, ~ref rest) => ~Cons(f(x), map(f, rest))
                                                      ^
error: aborting due to previous error
最后,这个版本起作用了


有谁能告诉我这张地图在《铁锈》中应该是什么样子吗

这是一张可以接受的地图,但我有几点意见

首先,仅从
map()
的类型签名就可以知道
f
需要使用
&T1
而不是
T1
。这是因为获取
T1
意味着它必须将值移动到闭包中,但它在借用的
列表上操作,因此无法移动它

其次,您的映射不需要返回
~List
,它可以只返回
List
,您可以自己将递归调用包装在
~
指针中。这看起来像

fn映射(f:|&T:>U,xs:&List)->List{
匹配*xs{
零=>零,
Cons(ref x,~ref rest)=>Cons(f(x),~map(f,rest))
}
}
第三,实现这一点的最佳方法不是编写
map()
,而是编写
iter()
,这将生成一个实现
迭代器的类型。迭代器隐式支持映射。然后,您还需要从迭代器实现
以允许您将映射结果转换回
列表


下面是迭代器的实现和示例用法:

#[派生(显示)]
发布枚举列表{
无
反对者(T,~List)
}
impl列表{
国际热核实验堆项目{
列表:&'
}
项目的impl{
匹配*self.list{
无=>无,
Cons(参考x,~ref rest)=>{
self.list=rest;
一些(x)
}
}
}
}
列表的impl FromIterator{
fn来自_iter(mut迭代器:T)->List{
匹配迭代器{
无=>无,
Some(x)=>Cons(x,~fromtiterator::from_iter(iterator))
}
}
}
fn main(){
设x=Cons(1u,~Cons(2u,~Cons(3u,~Nil));
println!(“{}”,x);
//打印错误(1,错误(2,错误(3,无)))
设y:List=x.iter().map(|&x | x*2).collect();
println!(“{}”,y);
//打印错误(2,错误(4,错误(6,无)))
}

感谢您的详尽回答;我最感兴趣的是Rust如何处理所有权,而不是实际实现map,但希望您回答的第二部分将来对我有用。干杯
demo.rs:25:15: 25:16 error: cannot bind by-move and by-ref in the same pattern
demo.rs:25         &Cons(x, ~ref rest) => ~Cons(f(x), map(f, rest))
                         ^
demo.rs:25:19: 25:27 note: by-ref binding occurs here
demo.rs:25         &Cons(x, ~ref rest) => ~Cons(f(x), map(f, rest))
                             ^~~~~~~~
error: aborting due to previous error
fn map<T1, T2>(f: |T1| -> T2, xs: &List<T1>) -> ~List<T2> {
    match xs {
        &Nil => ~Nil,
        &Cons(ref x, ~ref rest) => ~Cons(f(x), map(f, rest))
    }
}

demo.rs:25:44: 25:45 error: mismatched types: expected `T1` but found `&T1` (expected type parameter but found &-ptr)
demo.rs:25         &Cons(ref x, ~ref rest) => ~Cons(f(x), map(f, rest))
                                                      ^
error: aborting due to previous error
fn map<T1, T2>(f: |&T1| -> T2, xs: &List<T1>) -> ~List<T2> {
    match xs {
        &Nil => ~Nil,
        &Cons(ref x, ~ref rest) => ~Cons(f(x), map(f, rest))
    }
}