如果看到了版本号,一切 OK!如果出现一个类似“command not found”的错误,那么你应该查看安装方式的文档来确定如何单独安装 Cargo。
diff --git a/docs/ch04-01-what-is-ownership.html b/docs/ch04-01-what-is-ownership.html
index 9d29f78..4a5c37b 100644
--- a/docs/ch04-01-what-is-ownership.html
+++ b/docs/ch04-01-what-is-ownership.html
@@ -229,7 +229,116 @@ which does not implement the `Copy` trait
fn main() {
+ let s1 = gives_ownership(); // gives_ownership moves its return
+ // value into s1.
+
+ let s2 = String::from("hello"); // s2 comes into scope.
+
+ let s3 = takes_and_gives_back(s2); // s2 is moved into
+ // takes_and_gives_back, which also
+ // moves its return value into s3.
+} // Here, s3 goes out of scope and is dropped. s2 goes out of scope but was
+ // moved, so nothing happens. s1 goes out of scope and is dropped.
+
+fn gives_ownership() -> String { // gives_ownership will move its
+ // return value into the function
+ // that calls it.
+
+ let some_string = String::from("hello"); // some_string comes into scope.
+
+ some_string // some_string is returned and
+ // moves out to the calling
+ // function.
+}
+
+// takes_and_gives_back will take a String and return one.
+fn takes_and_gives_back(a_string: String) -> String { // a_string comes into
+ // scope.
+
+ a_string // a_string is returned and moves out to the calling function.
+}
+
fn calculate_length(s: &String) -> usize { // s is a reference to a String
+ s.len()
+} // Here, s goes out of scope. But because it does not have ownership of what
+ // it refers to, nothing happens.
+
let mut s = String::from("hello");
+
+let r1 = &mut s;
+let r2 = &mut s;
+
+
具体错误如下:
+
error[E0499]: cannot borrow `s` as mutable more than once at a time
+ --> borrow_twice.rs:5:19
+ |
+4 | let r1 = &mut s;
+ | - first mutable borrow occurs here
+5 | let r2 = &mut s;
+ | ^ second mutable borrow occurs here
+6 | }
+ | - first borrow ends here
+
let mut s = String::from("hello");
+
+{
+ let r1 = &mut s;
+
+} // r1 goes out of scope here, so we can make a new reference with no problems.
+
+let r2 = &mut s;
+
+
当结合可变和不可变引用时有一个类似的规则存在。这些代码会导致一个错误:
+
let mut s = String::from("hello");
+
+let r1 = &s; // no problem
+let r2 = &s; // no problem
+let r3 = &mut s; // BIG PROBLEM
+
+
错误如下:
+
error[E0502]: cannot borrow `s` as mutable because it is also borrowed as
+immutable
+ --> borrow_thrice.rs:6:19
+ |
+4 | let r1 = &s; // no problem
+ | - immutable borrow occurs here
+5 | let r2 = &s; // no problem
+6 | let r3 = &mut s; // BIG PROBLEM
+ | ^ mutable borrow occurs here
+7 | }
+ | - immutable borrow ends here
+
fn main() {
+ let reference_to_nothing = dangle();
+}
+
+fn dangle() -> &String {
+ let s = String::from("hello");
+
+ &s
+}
+
+
这里是错误:
+
error[E0106]: missing lifetime specifier
+ --> dangle.rs:5:16
+ |
+5 | fn dangle() -> &String {
+ | ^^^^^^^
+ |
+ = help: this function's return type contains a borrowed value, but there is no
+ value for it to be borrowed from
+ = help: consider giving it a 'static lifetime
+
+error: aborting due to previous error
+
this function's return type contains a borrowed value, but there is no value
+for it to be borrowed from.
+
+
让我们仔细看看我们的dangle代码的每一步到底放生了什么:
+
fn dangle() -> &String { // dangle returns a reference to a String
+
+ let s = String::from("hello"); // s is a new String
+
+ &s // we return a reference to the String, s
+} // Here, s goes out of scope, and is dropped. Its memory goes away.
+ // Danger!
+
fn main() {
+ let mut s = String::from("hello world");
+
+ let word = first_word(&s);
+
+ s.clear(); // Error!
+}
+
+
这里是编译错误:
+
17:6 error: cannot borrow `s` as mutable because it is also borrowed as
+ immutable [E0502]
+ s.clear(); // Error!
+ ^
+15:29 note: previous borrow of `s` occurs here; the immutable borrow prevents
+ subsequent moves or mutable borrows of `s` until the borrow ends
+ let word = first_word(&s);
+ ^
+18:2 note: previous borrow ends here
+fn main() {
+
+}
+^
+
+
回忆一下借用规则,当拥有某值的不可变引用时。不能再获取一个可变引用。因为clear需要清空String,它尝试获取一个可变引用,它失败了。Rust 不仅使得我们的 API 简单易用,也在编译时就消除了一整个错误类型!
如果有一个字符串 slice,可以直接传递它。如果有一个String,则可以传递整个String的 slice。定义一个获取字符串 slice 而不是字符串引用的函数使得我们的 API 更加通用并且不会丢失任何功能:
+
Filename: src/main.rs
+
# fn first_word(s: &str) -> &str {
+# let bytes = s.as_bytes();
+#
+# for (i, &item) in bytes.iter().enumerate() {
+# if item == b' ' {
+# return &s[0..i];
+# }
+# }
+#
+# &s[..]
+# }
+fn main() {
+ let my_string = String::from("hello world");
+
+ // first_word works on slices of `String`s
+ let word = first_word(&my_string[..]);
+
+ let my_string_literal = "hello world";
+
+ // first_word works on slices of string literals
+ let word = first_word(&my_string_literal[..]);
+
+ // since string literals *are* string slices already,
+ // this works too, without the slice syntax!
+ let word = first_word(my_string_literal);
+}
+
fn main() {
+ let s1 = gives_ownership(); // gives_ownership moves its return
+ // value into s1.
+
+ let s2 = String::from("hello"); // s2 comes into scope.
+
+ let s3 = takes_and_gives_back(s2); // s2 is moved into
+ // takes_and_gives_back, which also
+ // moves its return value into s3.
+} // Here, s3 goes out of scope and is dropped. s2 goes out of scope but was
+ // moved, so nothing happens. s1 goes out of scope and is dropped.
+
+fn gives_ownership() -> String { // gives_ownership will move its
+ // return value into the function
+ // that calls it.
+
+ let some_string = String::from("hello"); // some_string comes into scope.
+
+ some_string // some_string is returned and
+ // moves out to the calling
+ // function.
+}
+
+// takes_and_gives_back will take a String and return one.
+fn takes_and_gives_back(a_string: String) -> String { // a_string comes into
+ // scope.
+
+ a_string // a_string is returned and moves out to the calling function.
+}
+
fn calculate_length(s: &String) -> usize { // s is a reference to a String
+ s.len()
+} // Here, s goes out of scope. But because it does not have ownership of what
+ // it refers to, nothing happens.
+
let mut s = String::from("hello");
+
+let r1 = &mut s;
+let r2 = &mut s;
+
+
具体错误如下:
+
error[E0499]: cannot borrow `s` as mutable more than once at a time
+ --> borrow_twice.rs:5:19
+ |
+4 | let r1 = &mut s;
+ | - first mutable borrow occurs here
+5 | let r2 = &mut s;
+ | ^ second mutable borrow occurs here
+6 | }
+ | - first borrow ends here
+
let mut s = String::from("hello");
+
+{
+ let r1 = &mut s;
+
+} // r1 goes out of scope here, so we can make a new reference with no problems.
+
+let r2 = &mut s;
+
+
当结合可变和不可变引用时有一个类似的规则存在。这些代码会导致一个错误:
+
let mut s = String::from("hello");
+
+let r1 = &s; // no problem
+let r2 = &s; // no problem
+let r3 = &mut s; // BIG PROBLEM
+
+
错误如下:
+
error[E0502]: cannot borrow `s` as mutable because it is also borrowed as
+immutable
+ --> borrow_thrice.rs:6:19
+ |
+4 | let r1 = &s; // no problem
+ | - immutable borrow occurs here
+5 | let r2 = &s; // no problem
+6 | let r3 = &mut s; // BIG PROBLEM
+ | ^ mutable borrow occurs here
+7 | }
+ | - immutable borrow ends here
+
fn main() {
+ let reference_to_nothing = dangle();
+}
+
+fn dangle() -> &String {
+ let s = String::from("hello");
+
+ &s
+}
+
+
这里是错误:
+
error[E0106]: missing lifetime specifier
+ --> dangle.rs:5:16
+ |
+5 | fn dangle() -> &String {
+ | ^^^^^^^
+ |
+ = help: this function's return type contains a borrowed value, but there is no
+ value for it to be borrowed from
+ = help: consider giving it a 'static lifetime
+
+error: aborting due to previous error
+
this function's return type contains a borrowed value, but there is no value
+for it to be borrowed from.
+
+
让我们仔细看看我们的dangle代码的每一步到底放生了什么:
+
fn dangle() -> &String { // dangle returns a reference to a String
+
+ let s = String::from("hello"); // s is a new String
+
+ &s // we return a reference to the String, s
+} // Here, s goes out of scope, and is dropped. Its memory goes away.
+ // Danger!
+
fn main() {
+ let mut s = String::from("hello world");
+
+ let word = first_word(&s);
+
+ s.clear(); // Error!
+}
+
+
这里是编译错误:
+
17:6 error: cannot borrow `s` as mutable because it is also borrowed as
+ immutable [E0502]
+ s.clear(); // Error!
+ ^
+15:29 note: previous borrow of `s` occurs here; the immutable borrow prevents
+ subsequent moves or mutable borrows of `s` until the borrow ends
+ let word = first_word(&s);
+ ^
+18:2 note: previous borrow ends here
+fn main() {
+
+}
+^
+
+
回忆一下借用规则,当拥有某值的不可变引用时。不能再获取一个可变引用。因为clear需要清空String,它尝试获取一个可变引用,它失败了。Rust 不仅使得我们的 API 简单易用,也在编译时就消除了一整个错误类型!
如果有一个字符串 slice,可以直接传递它。如果有一个String,则可以传递整个String的 slice。定义一个获取字符串 slice 而不是字符串引用的函数使得我们的 API 更加通用并且不会丢失任何功能:
+
Filename: src/main.rs
+
# fn first_word(s: &str) -> &str {
+# let bytes = s.as_bytes();
+#
+# for (i, &item) in bytes.iter().enumerate() {
+# if item == b' ' {
+# return &s[0..i];
+# }
+# }
+#
+# &s[..]
+# }
+fn main() {
+ let my_string = String::from("hello world");
+
+ // first_word works on slices of `String`s
+ let word = first_word(&my_string[..]);
+
+ let my_string_literal = "hello world";
+
+ // first_word works on slices of string literals
+ let word = first_word(&my_string_literal[..]);
+
+ // since string literals *are* string slices already,
+ // this works too, without the slice syntax!
+ let word = first_word(my_string_literal);
+}
+