add array.md

This commit is contained in:
sunface 2022-02-27 20:26:37 +08:00
parent 072de76808
commit 17f94a2a22
6 changed files with 199 additions and 9 deletions

View File

@ -12,7 +12,7 @@
- [Reference and Borrowing](ownership/borrowing.md)
- [Compound Types doing](compound-types/intro.md)
- [string](compound-types/string.md)
- [array todo](compound-types/array.md)
- [array](compound-types/array.md)
- [slice todo](compound-types/slice.md)
- [tuple todo](compound-types/tuple.md)
- [struct todo](compound-types/struct.md)

View File

@ -1 +1,89 @@
# array
# Array
The type of array is `[T; Lengh]`, as you can see, array's lengh is part of their type signature. So their length must be known at compile time.
For example, you cant initialized an array as below:
```rust
fn init_arr(n: i32) {
let arr = [1; n];
}
```
This will cause an error, because the compile have no idea of the exact size of the array in compile time.
🌟
```rust,editable
fn main() {
// fill the blank with proper array type
let arr: __ = [1, 2, 3, 4, 5];
// modify below to make it work
assert!(arr.len() == 4);
}
```
🌟🌟
```rust,editable
fn main() {
// we can ignore parts of the array type or even the whole type, let the compiler infer it for us
let arr0 = [1, 2, 3];
let arr: [_; 3] = ['a', 'b', 'c'];
// fill the blank
// Arrays are stack allocated, `std::mem::size_of_val` return the bytes which array occupies
// A char takes 4 byte in Rust: Unicode char
assert!(std::mem::size_of_val(&arr) == __);
}
```
🌟 All elements in an array can be initialized to the same value at once.
```rust,editable
fn main() {
// fill the blank
let list: [i32; 100] = __ ;
assert!(list[0] == 1);
assert!(list.len() == 100);
}
```
🌟 All elements in an array must be of the same type
```rust,editable
fn main() {
// fix the error
let _arr = [1, 2, '3'];
}
```
🌟 Indexing starts at 0.
```rust,editable
fn main() {
let arr = ['a', 'b', 'c'];
let ele = arr[1]; // only modify this line to make the code work!
assert!(ele == 'a');
}
```
🌟 Out of bounds indexing causes `panic`.
```rust,editable
// fix the error
fn main() {
let names = [String::from("Sunfei"), "Sunface".to_string()];
// `get` returns an Option<T>, it's safe to use
let name0 = names.get(0).unwrap();
// but indexing is not safe
let _name1 = &names[2];
}
```

View File

@ -1,10 +1,27 @@
# slice todo
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].
```rust,editable
fn main() {
// we can ignore the array type, let the compiler infer it for us
let arr: [_; 3] = ['a', 'b', 'c'];
let arr1 = &arr[..2];
// Arrays are stack allocated
// A char takes 4 byte in Rust: Unicode char
println!("array occupies {} bytes", std::mem::size_of_val(&arr1));
}
```
```rust,editable
// The trimmed string is a slice to the original string, hence no new
// allocation is performed
let chars_to_trim: &[char] = &[' ', ','];
let trimmed_str: &str = string.trim_matches(chars_to_trim);
println!("Used characters: {}", trimmed_str);
```
```

View File

@ -10,13 +10,13 @@
- [所有权和借用](ownership/intro.md)
- [所有权](ownership/ownership.md)
- [引用和借用](ownership/borrowing.md)
- [复合类型 todo](compound-types/intro.md)
- [复合类型 doing](compound-types/intro.md)
- [字符串](compound-types/string.md)
- [数组](compound-types/array.md)
- [切片](compound-types/slice.md)
- [元组](compound-types/tuple.md)
- [结构体](compound-types/struct.md)
- [枚举](compound-types/enum.md)
- [切片 undo](compound-types/slice.md)
- [元组 undo](compound-types/tuple.md)
- [结构体 undo](compound-types/struct.md)
- [枚举 undo](compound-types/enum.md)
- [流程控制 todo](flow-control.md)
- [模式匹配 todo](pattern-match/intro.md)
- [match 和 if let](pattern-match/match-iflet.md)

View File

@ -1 +1,85 @@
# array
# 数组
数组的类型是 `[T; Lengh]`, 就如你所看到的,数组的长度是类型签名的一部分,因此数组的长度必须在编译期就已知,例如你不能使用以下方式来声明一个数组:
```rust
fn create_arr(n: i32) {
let arr = [1; n];
}
```
以上函数将报错,因为编译器无法在编译期知道 `n` 的具体大小。
🌟
```rust,editable
fn main() {
// 使用合适的类型填空
let arr: __ = [1, 2, 3, 4, 5];
// 修改以下代码,让它顺利运行
assert!(arr.len() == 4);
}
```
🌟🌟
```rust,editable
fn main() {
// 很多时候,我们可以忽略数组的部分类型,也可以忽略全部类型,让编译器帮助我们推导
let arr0 = [1, 2, 3];
let arr: [_; 3] = ['a', 'b', 'c'];
// 填空
// 数组分配在栈上, `std::mem::size_of_val` 函数会返回整个数组占用的内存空间
// 数组中的每个 char 元素占用 4 字节的内存空间,因为在 Rust 中, char 是 Unicode 字符
assert!(std::mem::size_of_val(&arr) == __);
}
```
🌟 数组中的所有元素可以一起初始化为同一个值
```rust,editable
fn main() {
// 填空
let list: [i32; 100] = __ ;
assert!(list[0] == 1);
assert!(list.len() == 100);
}
```
🌟 数组中的所有元素必须是同一类型
```rust,editable
fn main() {
// 修复错误
let _arr = [1, 2, '3'];
}
```
🌟 数组的下标索引从 0 开始.
```rust,editable
fn main() {
let arr = ['a', 'b', 'c'];
let ele = arr[1]; // 只修改此行来让代码工作
assert!(ele == 'a');
}
```
🌟 越界索引会导致代码的 `panic`.
```rust,editable
// 修复代码中的错误
fn main() {
let names = [String::from("Sunfei"), "Sunface".to_string()];
// `get` 返回 `Option<T>` 类型,因此它的使用非常安全
let name0 = names.get(0).unwrap();
// 但是下标索引就存在越界的风险了
let _name1 = &names[2];
}
```

View File

@ -0,0 +1 @@
# 切片