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))
}
}