java autoreference_为什么通过auto-deref访问的引用变量被移动了?

你正在做的是在指针上进行字段访问 .

如果点左侧的表达式类型是指针,则会根据需要自动解除引用,以使字段访问成为可能

Rust如何评估借用内容上的字段访问表达式的示例:

let d = Data { /*input*/}

let body = (&d).body // -> (*&d).body -> d.body

let ref_body = &(&d).body // -> &(*&).body -> &d.body -> &(d.body)

注意:d仍然是借来的内容,只需要auto deref来访问这些字段 .

为什么要搬家?

考虑以下代码:

struct Data {

body: Vec,

id: i32,

}

fn p(mut d: &Data) {

let id = d.id;

}

此代码将按预期工作,此处不会有任何移动,因此您可以重用 d.id . 在这种情况下:

Rust将尝试复制 d.id 的值 . 由于 d.id 是 i32 并实现 Copy 特征,因此它会将值复制到 id .

考虑以下代码:

fn p(mut d: &Data) {

let id = d.id; // works

let body = d.body; // fails

}

此代码无效,因为:

Rust将尝试复制 d.body ,但 Vec 没有 Copy 特征的实现 .

Rust将尝试从 d 移动 body ,您将收到"cannot move out of borrowed content"错误 .

这对循环有何影响?

for表达式是一个语法结构,用于循环由std :: iter :: IntoIterator的实现提供的元素.for循环等效于以下块表达式 . 'label:用于iter_expr中的PATTERN {

/ 循环体 /

}

相当于{

let result = match IntoIterator :: into_iter(iter_expr){

mut iter =>'label:loop {

下一步让mut;

匹配Iterator :: next(&mut iter){

Option :: Some(val)=> next = val,

选项::无=>休息,

};

让PAT =下一个;

let()= {/ * loop body * /};

},

};

结果

}

这意味着您的向量必须具有 IntoIterator 的实现,因为 IntoIterator::into_iter(self) 期望 self 作为参数 . 幸运的是,两个impl IntoIterator for Vec,另一个是impl IntoIterator for &'a Vec存在 .

为什么会这样?

只是:

当您使用 &d.body 时,您的循环使用 IntoIterator 的 &Vec 实现 .

此实现返回一个指向矢量切片的迭代器 . 这意味着你将从你的向量中获得 reference of elements .

当您使用 d.body 时,您的循环使用 Vec 的 Vec 实现 .

此实现返回一个迭代器,它是一个消耗迭代器 . 这意味着你的循环将具有 ownership of actual elements ,而不是它们的引用 . 对于消费部分,此实现需要实际向量而不是引用,因此移动发生 .

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值