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
下的值的所有权。例如: 这仅适用于复制类型,尽管这与x=*y中的不完全相同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