Rust 对闭包中的ref关键字用法感到困惑

Rust 对闭包中的ref关键字用法感到困惑,rust,Rust,我试图理解&和ref是如何对应的。下面是一个例子,我认为它们是等效的,但一个有效,另一个无效: fn main(){ 让t=” aoeu aoeu aoeu a”; 设ls=t.line(); dbg!(ls.clone().map(|l |&l[…]).collect::().join(“\n”);//works dbg!(ls.clone().map(| ref l | l[…]).collect::().join(“\n”);//不起作用 dbg!(ls.clone().map(| ref

我试图理解
&
ref
是如何对应的。下面是一个例子,我认为它们是等效的,但一个有效,另一个无效:

fn main(){
让t=”
aoeu
aoeu
aoeu
a”;
设ls=t.line();
dbg!(ls.clone().map(|l |&l[…]).collect::().join(“\n”);//works
dbg!(ls.clone().map(| ref l | l[…]).collect::().join(“\n”);//不起作用
dbg!(ls.clone().map(| ref l |&l[…]).collect::().join(“\n”);//再次工作!
}
从:

//赋值左侧的'ref'借用相当于
//右边的`&`借来的。
设ref_c1=c;
设ref_c2=&c;
普林顿!(“ref_c1等于ref_c2:{},*ref_c1==*ref_c2);

|ref l |
对应的
|l | l[…]
是什么?它与文档中的赋值示例如何对应?

查看文档页面(用于从
str
生成行的迭代器适配器),我们可以看到它生成的是:

type Item = &'a str;
因此,尝试执行“不工作”版本时会发生以下情况:

dbg!(ls.clone().map(| ref l | l[…])。collect::()。join(“\n”);#不起作用
//可以成为:
设温度=ls
.clone()
.地图(|参考l | l[…])
收集::()
.加入(“\n”);
普林顿!(“{}”,临时);
在这里,我们可以看到一个关键问题。因此,索引到它将创建一个
str
,它没有大小,因此不能在某种类型的指针之外


现在,进入您想要学习的真实内容:
ref
模式的作用:

其作用如下:

  • 当我们有
    let ref x=y
    时,我们引用
    y
  • 当对某个对象进行模式匹配时(比如在您展示的闭包参数中),我们有一个稍微不同的效果:引用下的值被移动到范围中,然后被引用,同时公开了获取引用下的值的方法。例如:

    这是有效的,因为基本上正在做的是:

    fn foo(x: String) {
       let x: &String = &x;
    }
    
    因此,
    ref x
    所做的就是获得
    x
    的所有权并生成对它的引用

另一方面

  • 当我们有
    let&x=y
    时,我们将一个值移出
    y
  • 这与
    ref
    相反,因为如果可以,我们拥有
    y
    下的值的所有权。例如: 这仅适用于复制类型,尽管这与x=*y中的不完全相同

fn foo(x: String) {
   let x: &String = &x;
}
let x = 2;
let y = &x;
let &z = y; //Ok, we're moving a `Copy` type