add string.md
This commit is contained in:
parent
2a8e014329
commit
7969fe6441
|
@ -0,0 +1,114 @@
|
||||||
|
1.
|
||||||
|
```rust
|
||||||
|
fn main() {
|
||||||
|
let mut s: String = String::from("hello, ");
|
||||||
|
s.push_str("world");
|
||||||
|
s.push('!');
|
||||||
|
|
||||||
|
move_ownership(s.clone());
|
||||||
|
|
||||||
|
assert_eq!(s, "hello, world!");
|
||||||
|
|
||||||
|
println!("Success!")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn move_ownership(s: String) {
|
||||||
|
println!("ownership of \"{}\" is moved here!", s)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```rust
|
||||||
|
fn main() {
|
||||||
|
let mut s: String = String::from("hello, ");
|
||||||
|
s.push_str("world");
|
||||||
|
s.push('!');
|
||||||
|
|
||||||
|
borrow_string(&s);
|
||||||
|
|
||||||
|
assert_eq!(s, "hello, world!");
|
||||||
|
|
||||||
|
println!("Success!")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn borrow_string(s: &str) {
|
||||||
|
println!("ownership of \"{}\" is moved here!", s)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
2.
|
||||||
|
```rust
|
||||||
|
// FILL in the blanks
|
||||||
|
fn main() {
|
||||||
|
// get a slice of String with reference: String -> &str
|
||||||
|
let mut s = String::from("hello, world");
|
||||||
|
|
||||||
|
let slice1: &str = &s; // in two ways
|
||||||
|
assert_eq!(slice1, "hello, world");
|
||||||
|
|
||||||
|
let slice2 = &s[0..5];
|
||||||
|
assert_eq!(slice2, "hello");
|
||||||
|
|
||||||
|
//Note! The type here cant be `&mut str` due to `push` is ONLY defined on String type and its mut reference: `&mut String` !
|
||||||
|
// So you can't use `s.as_mut_str()`
|
||||||
|
let slice3: &mut String = &mut s;
|
||||||
|
slice3.push('!');
|
||||||
|
assert_eq!(slice3, "hello, world!");
|
||||||
|
|
||||||
|
println!("Success!")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```rust
|
||||||
|
fn main() {
|
||||||
|
let mut s = String::from("hello, world");
|
||||||
|
|
||||||
|
let slice1: &str = s.as_str();
|
||||||
|
assert_eq!(slice1, "hello, world");
|
||||||
|
|
||||||
|
let slice2 = &s[0..5];
|
||||||
|
assert_eq!(slice2, "hello");
|
||||||
|
|
||||||
|
//Note! The type here cant be `&mut str` due to `push` is ONLY defined on String type and its mut reference: `&mut String` !
|
||||||
|
// So you can't use `s.as_mut_str()`
|
||||||
|
let slice3: &mut String = &mut s;
|
||||||
|
slice3.push('!');
|
||||||
|
assert_eq!(slice3, "hello, world!");
|
||||||
|
|
||||||
|
println!("Success!")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
2.
|
||||||
|
```rust
|
||||||
|
fn main() {
|
||||||
|
let s = String::from("hello, 世界");
|
||||||
|
let slice1 = &s[0..1]; //modify this line to fix the error, tips: `h` only takes 1 byte in UTF8 format
|
||||||
|
assert_eq!(slice1, "h");
|
||||||
|
|
||||||
|
let slice2 = &s[7..10];//modify this line to fix the error, tips: `中` takes 3 bytes in UTF8 format
|
||||||
|
assert_eq!(slice2, "世");
|
||||||
|
|
||||||
|
println!("Success!")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
3.
|
||||||
|
```rust
|
||||||
|
// FILL in the blanks
|
||||||
|
fn main() {
|
||||||
|
let mut s = String::new();
|
||||||
|
s.push_str("hello");
|
||||||
|
|
||||||
|
// some bytes, in a vector
|
||||||
|
let v = vec![104, 101, 108, 108, 111];
|
||||||
|
|
||||||
|
// Turn a bytes vector into a String
|
||||||
|
// We know these bytes are valid, so we'll use `unwrap()`.
|
||||||
|
let s1 = String::from_utf8(v).unwrap();
|
||||||
|
|
||||||
|
|
||||||
|
assert_eq!(s, s1);
|
||||||
|
|
||||||
|
println!("Success!")
|
||||||
|
}
|
||||||
|
```
|
|
@ -28,10 +28,10 @@
|
||||||
- [Traits](generics-traits/traits.md)
|
- [Traits](generics-traits/traits.md)
|
||||||
- [Trait Object](generics-traits/trait-object.md)
|
- [Trait Object](generics-traits/trait-object.md)
|
||||||
- [Advanced Traits](generics-traits/advanced-traits.md)
|
- [Advanced Traits](generics-traits/advanced-traits.md)
|
||||||
- [Collection Types todo](collections/intro.md)
|
- [Collection Types](collections/intro.md)
|
||||||
- [String](collections/string.md)
|
- [String](collections/string.md)
|
||||||
- [Vector](collections/vector.md)
|
- [Vector todo](collections/vector.md)
|
||||||
- [HashMap](collections/hashmap.md)
|
- [HashMap todo](collections/hashmap.md)
|
||||||
- [Type Conversion todo](type-conversion.md)
|
- [Type Conversion todo](type-conversion.md)
|
||||||
- [Result and panic todo](result-panic/intro.md)
|
- [Result and panic todo](result-panic/intro.md)
|
||||||
- [panic!](result-panic/panic.md)
|
- [panic!](result-panic/panic.md)
|
||||||
|
|
|
@ -1 +1,6 @@
|
||||||
# Collection Types
|
# Collection Types
|
||||||
|
Learning resources:
|
||||||
|
- English: [Rust Book Chapter 8](https://doc.rust-lang.org/book/ch08-00-common-collections.html)
|
||||||
|
- 简体中文: [Rust语言圣经 - 集合类型](https://course.rs/basic/collections/intro.html)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1 +1,111 @@
|
||||||
# String
|
# String
|
||||||
|
`std::string::String` is a UTF-8 encoded, growable string. It is the most common string type we used in daily dev, it also has ownership over the string contents.
|
||||||
|
|
||||||
|
### Basic operations
|
||||||
|
1. 🌟🌟
|
||||||
|
```rust,editable
|
||||||
|
|
||||||
|
// FILL in the blanks and FIX errors
|
||||||
|
// 1. Don't use `to_string()`
|
||||||
|
// 2. Dont't add/remove any code line
|
||||||
|
fn main() {
|
||||||
|
let mut s: String = "hello, ";
|
||||||
|
s.push_str("world".to_string());
|
||||||
|
s.push(__);
|
||||||
|
|
||||||
|
move_ownership(s);
|
||||||
|
|
||||||
|
assert_eq!(s, "hello, world!");
|
||||||
|
|
||||||
|
println!("Success!")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn move_ownership(s: String) {
|
||||||
|
println!("ownership of \"{}\" is moved here!", s)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### String and &str
|
||||||
|
A `String` is stored as a vector of bytes (`Vec<u8>`), but guaranteed to always be a valid UTF-8 sequence. `String` is heap allocated, growable and not null terminated.
|
||||||
|
|
||||||
|
`&str` is a slice (`&[u8]`) that always points to a valid UTF-8 sequence, and can be used to view into a String, just like `&[T]` is a view into `Vec<T>`.
|
||||||
|
|
||||||
|
2. 🌟🌟
|
||||||
|
```rust,editable
|
||||||
|
// FILL in the blanks
|
||||||
|
fn main() {
|
||||||
|
// get a slice of String with reference: String -> &str
|
||||||
|
let mut s = String::from("hello, world");
|
||||||
|
|
||||||
|
let slice1: &str = __; // in two ways
|
||||||
|
assert_eq!(slice1, "hello, world");
|
||||||
|
|
||||||
|
let slice2 = __;
|
||||||
|
assert_eq!(slice2, "hello");
|
||||||
|
|
||||||
|
let slice3: __ = __;
|
||||||
|
slice3.push('!');
|
||||||
|
assert_eq!(slice3, "hello, world!");
|
||||||
|
|
||||||
|
println!("Success!")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### UTF-8 & Indexing
|
||||||
|
Strings are always valid UTF-8. This has a few implications:
|
||||||
|
|
||||||
|
- the first of which is that if you need a non-UTF-8 string, consider [OsString](https://doc.rust-lang.org/stable/std/ffi/struct.OsString.html). It is similar, but without the UTF-8 constraint.
|
||||||
|
- The second implication is that you cannot index into a String
|
||||||
|
|
||||||
|
Indexing is intended to be a constant-time operation, but UTF-8 encoding does not allow us to do this. Furthermore, it’s not clear what sort of thing the index should return: a byte, a codepoint, or a grapheme cluster. The bytes and chars methods return iterators over the first two, respectively.
|
||||||
|
|
||||||
|
2. 🌟🌟🌟 You can't use index to access a char in a string, but you can use slice `&s1[start..end]`.
|
||||||
|
|
||||||
|
```rust,editable
|
||||||
|
|
||||||
|
// FIX errors
|
||||||
|
fn main() {
|
||||||
|
let s = String::from("hello, 世界");
|
||||||
|
let slice1 = s[0]; //tips: `h` only takes 1 byte in UTF8 format
|
||||||
|
assert_eq!(slice1, "h");
|
||||||
|
|
||||||
|
let slice2 = &s[3..5];// tips: `中` takes 3 bytes in UTF8 format
|
||||||
|
assert_eq!(slice2, "世");
|
||||||
|
|
||||||
|
println!("Success!")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
3. 🌟🌟🌟
|
||||||
|
> Tips: maybe you need `from_utf8` method
|
||||||
|
|
||||||
|
```rust,editable
|
||||||
|
|
||||||
|
// FILL in the blanks
|
||||||
|
fn main() {
|
||||||
|
let mut s = String::new();
|
||||||
|
__;
|
||||||
|
|
||||||
|
// some bytes, in a vector
|
||||||
|
let v = vec![104, 101, 108, 108, 111];
|
||||||
|
|
||||||
|
// Turn a bytes vector into a String
|
||||||
|
// We know these bytes are valid, so we'll use `unwrap()`.
|
||||||
|
let s1 = __;
|
||||||
|
|
||||||
|
|
||||||
|
assert_eq!(s, s1);
|
||||||
|
|
||||||
|
println!("Success!")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Representation
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Common methods
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue