rust - 如何在可变借用后打印出一个值?
问题描述
我构造了一个字符串,然后借用它进行一些更改。然后我想看看字符串是如何更改的,但我无法打印出该值:
let mut s1 = String::from("hello");
let s2 = &mut s1;
s2.truncate(2);
print!("{}", s1);
println!("{}", s2);
error[E0502]: cannot borrow `s1` as immutable because it is also borrowed as mutable
--> src/lib.rs:5:18
|
3 | let s2 = &mut s1;
| ------- mutable borrow occurs here
4 | s2.truncate(2);
5 | print!("{}", s1);
| ^^ immutable borrow occurs here
6 | println!("{}", s2);
| -- mutable borrow later used here
我认为 Rust 中的借用类似于 C++,因此何时s1
更改s2
会相应更改。
解决方案
Rust 的引用不像在 C/C++/Java 等其他语言中那样工作。Rust 编译器在编译时确保内存安全,它通过使用“借用检查器”来做到这一点。借用检查器遵守一组规则,而您发布的代码违反了其中一个规则。
这是 Rust 书中的直接引述,它解决了这种确切情况:
- 在任何给定时间,您都可以拥有一个可变引用或任意数量的不可变引用。
首先,您创建一个可变变量s1
,并将其作为不可变的 via 借用s2
。这很好,只要您不同时使用它们。问题不会出现在这里,因为您还没有真正对引用做任何事情。当您强制这两个引用同时处于活动状态时,就会出现问题。当您访问s1
之前s2
超出范围时会发生这种情况(那将是在它最后一次使用之后)。看看这个:
let mut s1 = String::from("hello"); // -- Start of s1 scope --
let s2 = &mut s1; // -- Start of s2 scope --
s2.truncate(2); // s1 may not be used here as
// that breaks the rules
print!("{}", s1); // -- End of s1 scope --
println!("{}", s2); // -- End of s2 scope --
如您所见,由于代码的结构方式,范围s1
和s2
必须同时处于活动状态。如果要交换最后两行代码,请将代码更改为:
let mut s1 = String::from("hello"); // -- Start of s1 scope --
let s2 = &mut s1; // -- Start of s2 scope --
s2.truncate(2); // s1 may not be used here as
// that breaks the rules
println!("{}", s2); // -- End of s2 scope --
print!("{}", s1); // -- End of s1 scope --
然后您的代码将按预期编译和运行。原因是虽然s2
' 的范围是活动的,但你根本没有使用s1
。换句话说,这些事情发生在上述代码的每一行:
s1
拥有新创建的String
s2
可变地借用String
s2
用于截断String
s2
用于打印String
. 由于这是最后一次使用s2
,在这条线的所有权String
归回之后s1
。s1
用于打印String
.
我希望这可以为您澄清情况。
我建议您花点时间在此处查看 Rust 书籍的“了解所有权”一章。我的建议是从头开始阅读整本书。它会让你很好地理解 Rust 作为一门语言及其生态系统。
推荐阅读
- asp.net-core - IdentityServer 跨浏览器选项卡的不同租户/用户
- html - 调整图像大小的最佳方法,% 与最大宽度
- python - 熊猫:按年爆发,然后填补空白
- sed - 在 tcl 文件中使用 sed
- java - 在 JPA 查询中使用 CAST 或 CONVERT 将精度为 2 的 BigDecimal 与精度为 3 的数据进行比较
- python - 通过按钮打开另一个窗口并使用 Tkinter,Python 返回一个空窗口
- mysql - Mysql 表修复失败:“无法创建新的临时文件”
- c++ - 依赖注入和所有权问题
- sql - 超链接 - 给出运行时错误 5“无效的过程调用或参数”
- python - 如何从 CSV 文件中排除列表中的一项并在单独的文件中打印行的其余部分?