mirror of
https://github.com/sunface/rust-by-practice.git
synced 2025-06-23 12:39:42 +00:00
add en/slice.md
This commit is contained in:
@ -12,11 +12,11 @@
|
|||||||
- [Reference and Borrowing](ownership/borrowing.md)
|
- [Reference and Borrowing](ownership/borrowing.md)
|
||||||
- [Compound Types doing](compound-types/intro.md)
|
- [Compound Types doing](compound-types/intro.md)
|
||||||
- [string](compound-types/string.md)
|
- [string](compound-types/string.md)
|
||||||
- [array](compound-types/array.md)
|
- [Array](compound-types/array.md)
|
||||||
- [slice](compound-types/slice.md)
|
- [Slice](compound-types/slice.md)
|
||||||
- [tuple todo](compound-types/tuple.md)
|
- [Tuple todo](compound-types/tuple.md)
|
||||||
- [struct todo](compound-types/struct.md)
|
- [Struct todo](compound-types/struct.md)
|
||||||
- [enum todo](compound-types/enum.md)
|
- [Enum todo](compound-types/enum.md)
|
||||||
- [Flow Control todo](flow-control.md)
|
- [Flow Control todo](flow-control.md)
|
||||||
- [Pattern Match todo](pattern-match/intro.md)
|
- [Pattern Match todo](pattern-match/intro.md)
|
||||||
- [match, if let](pattern-match/match-iflet.md)
|
- [match, if let](pattern-match/match-iflet.md)
|
||||||
|
@ -1,27 +1,88 @@
|
|||||||
# slice todo
|
# Slice
|
||||||
Slices are similar to arrays, but their length is not known at compile time. Instead, a slice is a two-word object, the first word is a pointer to the data, and the second word is the length of the slice. The word size is the same as usize, determined by the processor architecture eg 64 bits on an x86-64. Slices can be used to borrow a section of an array, and have the type signature &[T].
|
Slices are similar to arrays, but their length is not known at compile time, so you can't use slice directly.
|
||||||
|
|
||||||
|
|
||||||
|
🌟🌟 Here, both `[i32]` and `str` are slice types, but directly using it will cause errors. You have to use the reference of the slice instead: `&[i32]`, `&str`.
|
||||||
```rust,editable
|
```rust,editable
|
||||||
|
|
||||||
|
// fix the errors, DON'T add new lines!
|
||||||
fn main() {
|
fn main() {
|
||||||
// we can ignore the array type, let the compiler infer it for us
|
let arr = [1, 2, 3];
|
||||||
let arr: [_; 3] = ['a', 'b', 'c'];
|
let s1: [i32] = arr[0..2];
|
||||||
|
|
||||||
let arr1 = &arr[..2];
|
let s2: str = "hello, world" as str;
|
||||||
|
|
||||||
// Arrays are stack allocated
|
|
||||||
// A char takes 4 byte in Rust: Unicode char
|
|
||||||
println!("array occupies {} bytes", std::mem::size_of_val(&arr1));
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
A slice reference is a two-word object, for simplicity reasons, from now on we will use slice instead of `slice reference`. The first word is a pointer to the data, and the second word is the length of the slice. The word size is the same as usize, determined by the processor architecture eg 64 bits on an x86-64. Slices can be used to borrow a section of an array, and have the type signature `&[T]`.
|
||||||
|
|
||||||
|
🌟🌟🌟
|
||||||
```rust,editable
|
```rust,editable
|
||||||
// The trimmed string is a slice to the original string, hence no new
|
|
||||||
// allocation is performed
|
fn main() {
|
||||||
let chars_to_trim: &[char] = &[' ', ','];
|
let arr: [char; 3] = ['中', '国', '人'];
|
||||||
let trimmed_str: &str = string.trim_matches(chars_to_trim);
|
|
||||||
println!("Used characters: {}", trimmed_str);
|
let slice = &arr[..2];
|
||||||
|
|
||||||
|
// modify '6' to make it work
|
||||||
|
// TIPS: slice( reference ) IS NOT an array, if it is an array, then `assert!` will passed: each of the two UTF-8 chars '中' and '国' occupies 3 bytes, 2 * 3 = 6
|
||||||
|
assert!(std::mem::size_of_val(&slice) == 6);
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
🌟🌟
|
||||||
|
```rust,editable
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let arr: [i32; 5] = [1, 2, 3, 4, 5];
|
||||||
|
// fill the blanks to make the code work
|
||||||
|
let slice: __ = __;
|
||||||
|
assert_eq!(slice, &[2, 3, 4]);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### string slices
|
||||||
|
🌟
|
||||||
|
```rust,editable
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let s = String::from("hello");
|
||||||
|
|
||||||
|
let slice1 = &s[0..2];
|
||||||
|
// fill the blank to make the code work
|
||||||
|
let slice2 = &s[__];
|
||||||
|
|
||||||
|
assert_eq!(slice1, slice2);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
🌟
|
||||||
|
```rust,editable
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let s = "你好,世界";
|
||||||
|
// modify this line to make the code work
|
||||||
|
let slice = &s[0..2];
|
||||||
|
|
||||||
|
assert!(slice == "你");
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
🌟🌟 `&String` can be implicitly converted into `&str`.
|
||||||
|
```rust,editable
|
||||||
|
|
||||||
|
// fix errors
|
||||||
|
fn main() {
|
||||||
|
let mut s = String::from("hello world");
|
||||||
|
|
||||||
|
// here, &s is `&String` type, but `first_word` need a `&str` type.
|
||||||
|
// it works because `&String` implicitly be converted to `&str, If you want know more ,this is called `Deref`
|
||||||
|
let word = first_word(&s);
|
||||||
|
|
||||||
|
s.clear(); // error!
|
||||||
|
|
||||||
|
println!("the first word is: {}", word);
|
||||||
|
}
|
||||||
|
fn first_word(s: &str) -> &str {
|
||||||
|
&s[..1]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
@ -1 +1,88 @@
|
|||||||
# 切片
|
# 切片
|
||||||
|
Slices are similar to arrays, but their length is not known at compile time, so you can't use slice directly.
|
||||||
|
|
||||||
|
🌟🌟 Here, both `[i32]` and `str` are slice types, but directly using it will cause errors. You have to use the reference of the slice instead: `&[i32]`, `&str`.
|
||||||
|
```rust,editable
|
||||||
|
|
||||||
|
// fix the errors, DON'T add new lines!
|
||||||
|
fn main() {
|
||||||
|
let arr = [1, 2, 3];
|
||||||
|
let s1: [i32] = arr[0..2];
|
||||||
|
|
||||||
|
let s2: str = "hello, world" as str;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
A slice reference is a two-word object, for simplicity reasons, from now on we will use slice instead of `slice reference`. The first word is a pointer to the data, and the second word is the length of the slice. The word size is the same as usize, determined by the processor architecture eg 64 bits on an x86-64. Slices can be used to borrow a section of an array, and have the type signature `&[T]`.
|
||||||
|
|
||||||
|
🌟🌟🌟
|
||||||
|
```rust,editable
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let arr: [char; 3] = ['中', '国', '人'];
|
||||||
|
|
||||||
|
let slice = &arr[..2];
|
||||||
|
|
||||||
|
// modify '6' to make it work
|
||||||
|
// TIPS: slice( reference ) IS NOT an array, if it is an array, then `assert!` will passed: each of the two UTF-8 chars '中' and '国' occupies 3 bytes, 2 * 3 = 6
|
||||||
|
assert!(std::mem::size_of_val(&slice) == 6);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
🌟🌟
|
||||||
|
```rust,editable
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let arr: [i32; 5] = [1, 2, 3, 4, 5];
|
||||||
|
// fill the blanks to make the code work
|
||||||
|
let slice: __ = __;
|
||||||
|
assert_eq!(slice, &[2, 3, 4]);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### string slices
|
||||||
|
🌟
|
||||||
|
```rust,editable
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let s = String::from("hello");
|
||||||
|
|
||||||
|
let slice1 = &s[0..2];
|
||||||
|
// fill the blank to make the code work
|
||||||
|
let slice2 = &s[__];
|
||||||
|
|
||||||
|
assert_eq!(slice1, slice2);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
🌟
|
||||||
|
```rust,editable
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let s = "你好,世界";
|
||||||
|
// modify this line to make the code work
|
||||||
|
let slice = &s[0..2];
|
||||||
|
|
||||||
|
assert!(slice == "你");
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
🌟🌟 `&String` can be implicitly converted into `&str`.
|
||||||
|
```rust,editable
|
||||||
|
|
||||||
|
// fix errors
|
||||||
|
fn main() {
|
||||||
|
let mut s = String::from("hello world");
|
||||||
|
|
||||||
|
// here, &s is `&String` type, but `first_word` need a `&str` type.
|
||||||
|
// it works because `&String` implicitly be converted to `&str, If you want know more ,this is called `Deref`
|
||||||
|
let word = first_word(&s);
|
||||||
|
|
||||||
|
s.clear(); // error!
|
||||||
|
|
||||||
|
println!("the first word is: {}", word);
|
||||||
|
}
|
||||||
|
fn first_word(s: &str) -> &str {
|
||||||
|
&s[..1]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Reference in New Issue
Block a user