rust-by-practice/en/src/compound-types/slice.md

100 lines
2.6 KiB
Markdown
Raw Normal View History

2022-02-27 07:14:53 -06:00
# Slice
Slices are similar to arrays, but their length is not known at compile time, so you can't use slice directly.
2022-02-26 23:01:40 -06:00
2022-03-02 07:11:58 -06:00
1. ๐ŸŒŸ๐ŸŒŸ 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`.
2022-02-27 07:14:53 -06:00
```rust,editable
// fix the errors, DON'T add new lines!
fn main() {
let arr = [1, 2, 3];
let s1: [i32] = arr[0..2];
2022-02-26 23:01:40 -06:00
2022-02-27 07:14:53 -06:00
let s2: str = "hello, world" as str;
println!("Success!")
2022-02-27 07:14:53 -06:00
}
```
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]`.
2022-03-02 07:11:58 -06:00
2. ๐ŸŒŸ๐ŸŒŸ๐ŸŒŸ
2022-02-27 06:26:37 -06:00
```rust,editable
2022-02-27 07:14:53 -06:00
2022-02-27 06:26:37 -06:00
fn main() {
2022-02-27 07:14:53 -06:00
let arr: [char; 3] = ['ไธญ', 'ๅ›ฝ', 'ไบบ'];
2022-02-27 06:26:37 -06:00
2022-02-27 07:14:53 -06:00
let slice = &arr[..2];
2022-02-27 06:26:37 -06:00
2022-02-27 07:14:53 -06:00
// 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);
println!("Success!")
2022-02-27 07:14:53 -06:00
}
```
2022-02-27 06:26:37 -06:00
2022-03-02 07:11:58 -06:00
3. ๐ŸŒŸ๐ŸŒŸ
2022-02-27 07:14:53 -06:00
```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]);
println!("Success!")
2022-02-27 06:26:37 -06:00
}
```
2022-02-27 07:14:53 -06:00
### string slices
2022-03-02 07:11:58 -06:00
4. ๐ŸŒŸ
2022-02-26 23:01:40 -06:00
```rust,editable
2022-02-27 07:14:53 -06:00
fn main() {
let s = String::from("hello");
let slice1 = &s[0..2];
2022-03-02 07:11:58 -06:00
// fill the blank to make the code work, DON'T USE 0..2 again
2022-02-27 07:14:53 -06:00
let slice2 = &s[__];
assert_eq!(slice1, slice2);
println!("Success!")
2022-02-27 07:14:53 -06:00
}
2022-02-27 06:26:37 -06:00
```
2022-03-02 07:11:58 -06:00
5. ๐ŸŒŸ
2022-02-27 07:14:53 -06:00
```rust,editable
fn main() {
let s = "ไฝ ๅฅฝ๏ผŒไธ–็•Œ";
// modify this line to make the code work
let slice = &s[0..2];
assert!(slice == "ไฝ ");
println!("Success!")
2022-02-27 07:14:53 -06:00
}
```
2022-03-02 07:11:58 -06:00
6. ๐ŸŒŸ๐ŸŒŸ `&String` can be implicitly converted into `&str`.
2022-02-27 07:14:53 -06:00
```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.
2022-03-02 07:11:58 -06:00
// it works because `&String` can be implicitly converted to `&str, If you want know more ,this is called `Deref`
2022-02-27 07:14:53 -06:00
let word = first_word(&s);
s.clear(); // error!
println!("the first word is: {}", word);
}
fn first_word(s: &str) -> &str {
&s[..1]
}
```
2022-03-01 08:06:38 -06:00
> You can find the solutions [here](https://github.com/sunface/rust-by-practice)(under the solutions path), but only use it when you need it