From bfc30e2024f6024d7b03859e7607a5a28fb32d0b Mon Sep 17 00:00:00 2001 From: sunface Date: Fri, 25 Feb 2022 22:57:13 +0800 Subject: [PATCH] add reference and borrowing --- en/src/ownership/borrowing.md | 165 ++++++++++++++++++++++++++++++ zh-CN/src/ownership/borrowing.md | 167 ++++++++++++++++++++++++++++++- 2 files changed, 331 insertions(+), 1 deletion(-) diff --git a/en/src/ownership/borrowing.md b/en/src/ownership/borrowing.md index 9ce0535..86ec6e4 100644 --- a/en/src/ownership/borrowing.md +++ b/en/src/ownership/borrowing.md @@ -1 +1,166 @@ # Reference and Borrowing + +### Reference +🌟 +```rust,editable + +fn main() { + let x = 5; + // fill the blank + let p = __; + + println!("the memory address of x is {:p}", p); // output: 0x16fa3ac84 +} +``` + +🌟 +```rust,editable + +fn main() { + let x = 5; + let y = &x; + + // modify this line only + assert_eq!(5, y); +} +``` + +🌟 +```rust,editable + +// fix error +fn main() { + let mut s = String::from("hello, "); + + borrow_object(s) +} + +fn borrow_object(s: &String) {} +``` + +🌟 +```rust,editable + +// fix error +fn main() { + let mut s = String::from("hello, "); + + borrow_object(&s) +} + +fn borrow_object(s: &mut String) {} +``` + +🌟🌟 +```rust,editable + +fn main() { + let mut s = String::from("hello, "); + + // fill the blank to make it work + let p = __; + + p.push_str("world"); +} +``` + +#### ref +`ref` can be used to take references to a value, similar to `&`. + +🌟🌟🌟 +```rust,editable + +fn main() { + let c = '中'; + + let r1 = &c; + // fill the blank,dont change other code + let __ r2 = c; + + assert_eq!(*r1, *r2); + + // check the equality of the two address strings + assert_eq!(get_addr(r1),get_addr(r2)); +} + +// get memory address string +fn get_addr(r: &char) -> String { + format!("{:p}", r) +} +``` + +### Borrowing rules +🌟 +```rust,editable + +// remove something to make it work +// don't remove a whole line ! +fn main() { + let mut s = String::from("hello"); + + let r1 = &mut s; + let r2 = &mut s; + + println!("{}, {}", r1, r2); +} +``` + +#### Mutablity +🌟 Error: Borrow a immutable object as mutable +```rust,editable + +fn main() { + //fix error by modifying this line + let s = String::from("hello, "); + + borrow_object(&mut s) +} + +fn borrow_object(s: &mut String) {} +``` + +🌟🌟 Ok: Borrow a mutable object as immutable +```rust,editable + +// this code has no errors! +fn main() { + let mut s = String::from("hello, "); + + borrow_object(&s); + + s.push_str("world"); +} + +fn borrow_object(s: &String) {} +``` + +### NLL +🌟🌟 +```rust,editable + +// comment one line to make it work +fn main() { + let mut s = String::from("hello, "); + + let r1 = &mut s; + r1.push_str("world"); + let r2 = &mut s; + r2.push_str("!"); + + println!("{}",r1); +} +``` + +🌟🌟🌟 +```rust,editable + +fn main() { + let mut s = String::from("hello, "); + + let r1 = &mut s; + let r2 = &mut s; + + // add one line below to make a compiler error: cannot borrow `s` as mutable more than once at a time + // you can't use r1 and r2 at the same time +} +``` \ No newline at end of file diff --git a/zh-CN/src/ownership/borrowing.md b/zh-CN/src/ownership/borrowing.md index 9ce0535..f78c2be 100644 --- a/zh-CN/src/ownership/borrowing.md +++ b/zh-CN/src/ownership/borrowing.md @@ -1 +1,166 @@ -# Reference and Borrowing +# 引用和借用 + +### 引用 +🌟 +```rust,editable + +fn main() { + let x = 5; + // 填写空白处 + let p = __; + + println!("x 的内存地址是 {:p}", p); // output: 0x16fa3ac84 +} +``` + +🌟 +```rust,editable + +fn main() { + let x = 5; + let y = &x; + + // 只能修改以下行 + assert_eq!(5, y); +} +``` + +🌟 +```rust,editable + +// 修复错误 +fn main() { + let mut s = String::from("hello, "); + + borrow_object(s) +} + +fn borrow_object(s: &String) {} +``` + +🌟 +```rust,editable + +// 修复错误 +fn main() { + let mut s = String::from("hello, "); + + borrow_object(&s) +} + +fn borrow_object(s: &mut String) {} +``` + +🌟🌟 +```rust,editable + +fn main() { + let mut s = String::from("hello, "); + + // 填写空白处,让代码工作 + let p = __; + + p.push_str("world"); +} +``` + +#### ref +`ref` 与 `&` 类似,可以用来获取一个值的引用,但是它们的用法有所不同。 + +🌟🌟🌟 +```rust,editable + +fn main() { + let c = '中'; + + let r1 = &c; + // 填写空白处,但是不要修改其它行的代码 + let __ r2 = c; + + assert_eq!(*r1, *r2); + + // 判断两个内存地址的字符串是否相等 + assert_eq!(get_addr(r1),get_addr(r2)); +} + +// 获取传入引用的内存地址的字符串形式 +fn get_addr(r: &char) -> String { + format!("{:p}", r) +} +``` + +### 借用规则 +🌟 +```rust,editable + +// 移除代码某个部分,让它工作 +// 你不能移除整行的代码! +fn main() { + let mut s = String::from("hello"); + + let r1 = &mut s; + let r2 = &mut s; + + println!("{}, {}", r1, r2); +} +``` + +#### 可变性 +🌟 错误: 从可不用对象借用可用 +```rust,editable + +fn main() { + // 通过修改下面一行代码来修复错误 + let s = String::from("hello, "); + + borrow_object(&mut s) +} + +fn borrow_object(s: &mut String) {} +``` + +🌟🌟 Ok: 从可变对象借用不可变 +```rust,editable + +// 下面的代码没有任何错误 +fn main() { + let mut s = String::from("hello, "); + + borrow_object(&s); + + s.push_str("world"); +} + +fn borrow_object(s: &String) {} +``` + +### NLL +🌟🌟 +```rust,editable + +// 注释掉一行代码让它工作 +fn main() { + let mut s = String::from("hello, "); + + let r1 = &mut s; + r1.push_str("world"); + let r2 = &mut s; + r2.push_str("!"); + + println!("{}",r1); +} +``` + +🌟🌟🌟 +```rust,editable + +fn main() { + let mut s = String::from("hello, "); + + let r1 = &mut s; + let r2 = &mut s; + + // 在下面增加一行代码人为制造编译错误:cannot borrow `s` as mutable more than once at a time + // 你不能同时使用 r1 和 r2 +} +``` \ No newline at end of file