loops - 有没有办法告诉编译器我正在循环管理变量的所有权?
问题描述
我试图将变量的所有权赋予循环中的函数,并且我有自己的布尔值以确保它只发生一次,但是编译器告诉我该值在上一次迭代中被移动。
这是一个例子:
fn take_ownership(a: String) {
println!("{}", a);
}
fn main() {
let mut a = true;
let hello = "Hello".to_string();
for _ in 0..5 {
if a {
a = false;
take_ownership(hello);
}
}
}
使用此代码,编译器会告诉我:
error[E0382]: use of moved value: `hello`
--> src/main.rs:12:28
|
12 | take_ownership(hello);
| ^^^^^ value moved here in previous iteration of loop
有没有办法告诉编译器“没关系,我会处理它”?我不想使用引用(&
)。
解决方案
告诉编译器“没关系,我会处理它”的常用方法是使用unsafe
. 你可以在这里使用unsafe
一些深奥的ptr
魔法,但这会非常脆弱并且很难证明是正确的。
然而,这是一个安全且简单的事情Option
:
let mut a = Some("Hello".to_string());
for _ in 0..5 {
if let Some(hello) = a.take() {
take_ownership(hello);
}
}
a
在原始版本中, and之间没有类型级别的关系hello
,因此编译器无法确定hello
它只移动了一次。Option
将不变的“这里可能有东西,或者它可能已经消失”编码到类型中,因此编译器可以知道take_ownership
只有在有东西要传递给它时才调用它。
.take()
是一个用 替换的方法a
,None
返回内容(如果有的话)。因为这个方法不消耗Option
,所以可以循环调用多次。尝试转移所有权时无法移出借用内容是一个相关问题。
推荐阅读
- angular - 以角材料调用 Dialog 组件内的组件
- java - springboott 没有选择自定义注释
- javascript - 无法让 Twitter 与 firebaseUI web 一起使用
- ios - iOS 12 - IPA 大小显着减小
- python - 升级 Ipython 时出现问题(prompt_toolkit 不兼容)
- centos - gnome 禁用“以其他用户身份登录”链接
- php - 如何使用查询从 MySQL 数据库中删除 id
- ssl - 如何从不使用默认 WLAN 代理设置的 apk 捕获和解码 ssl 流量
- javascript - 如何使用ajax一起发送模态表单和普通表单
- database - 如何对该模式进行分类?