diff --git a/en/src/SUMMARY.md b/en/src/SUMMARY.md index 63dc734..07009db 100644 --- a/en/src/SUMMARY.md +++ b/en/src/SUMMARY.md @@ -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) diff --git a/en/src/compound-types/array.md b/en/src/compound-types/array.md index 92c587c..5dfcc0a 100644 --- a/en/src/compound-types/array.md +++ b/en/src/compound-types/array.md @@ -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, it's safe to use + let name0 = names.get(0).unwrap(); + + // but indexing is not safe + let _name1 = &names[2]; +} + +``` + diff --git a/en/src/compound-types/slice.md b/en/src/compound-types/slice.md index 7d24c91..a732544 100644 --- a/en/src/compound-types/slice.md +++ b/en/src/compound-types/slice.md @@ -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); -``` \ No newline at end of file +``` + diff --git a/zh-CN/src/SUMMARY.md b/zh-CN/src/SUMMARY.md index 08c6871..3586eab 100644 --- a/zh-CN/src/SUMMARY.md +++ b/zh-CN/src/SUMMARY.md @@ -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) diff --git a/zh-CN/src/compound-types/array.md b/zh-CN/src/compound-types/array.md index 92c587c..931fc05 100644 --- a/zh-CN/src/compound-types/array.md +++ b/zh-CN/src/compound-types/array.md @@ -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` 类型,因此它的使用非常安全 + let name0 = names.get(0).unwrap(); + + // 但是下标索引就存在越界的风险了 + let _name1 = &names[2]; +} +``` + diff --git a/zh-CN/src/compound-types/slice.md b/zh-CN/src/compound-types/slice.md new file mode 100644 index 0000000..0a8a037 --- /dev/null +++ b/zh-CN/src/compound-types/slice.md @@ -0,0 +1 @@ +# 切片