├── .gitignore ├── LICENSE ├── README.md ├── keywords ├── README.md ├── as.md ├── const.md ├── crate.md ├── enum.md ├── extern.md ├── fn.md ├── for.md ├── if.md ├── impl.md ├── let.md ├── loop.md └── struct.md ├── macros ├── README.md └── assert.md ├── modules ├── alloc.md ├── option.md ├── result.md └── thread.md ├── primitive types └── array.md └── wiki.rs /.gitignore: -------------------------------------------------------------------------------- 1 | # Generated by Cargo 2 | # will have compiled files and executables 3 | /target/ 4 | 5 | # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries 6 | # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html 7 | Cargo.lock 8 | 9 | # These are backup files generated by rustfmt 10 | **/*.rs.bk 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # rust-std 2 | 3 | Rust 标准库中文翻译。欢迎大家参与进来,也欢迎大家加入 **RCTT** (Rust Chinese Translation Team),在本仓库提交 issue 即可,我会及时主动邀请你。 4 | 5 | QQ交流群:962057386 6 | 7 | --- 8 | 9 | ## 相关 10 | 11 | 更多请看 [Rust 标准库官方文档](https://doc.rust-lang.org/std/),鉴于译者水平有限,如有疑问欢迎提出^_^ 。 12 | 13 | ## rust 标准库教程 14 | 15 | 本文档致力于指出Rust标准库的显著特性。 16 | 17 | ### 容器与集合类型 18 | 19 | 20 | - [Vec]() - 在堆上分配,运行期间可调整大小的 vector。 21 | - [[T; n]]() - 在编译时具有固定大小的内联数组。 22 | - [[T]]() - 一个动态大小的切片,它可以被分配到任何不同类型的连续存储中,不管是不是在堆上堆分配。 23 | 24 | 切片只能通过某种类型的指针来处理,因此有很多类型,例如: 25 | 26 | - [&[T]]() - 切片引用 27 | - [&mut [T]]() - 可变切片 28 | - [Box<[T]>]() - 拥有的切片 29 | 30 | ### 基本类型 31 | 32 | - [array]() 一个固定大小的数组, 写作 [T; N],表示元素类型 T 和非负编译时常数大小 N。 33 | - [bool]() 布尔类型。 34 | - [char]() 字符类型。 35 | - [f32]() 32 位浮点数。 36 | - [f64]() 64 位浮点数。 37 | - [fn]() 函数指针, 形如 `fn(usize) -> bool`。 38 | - [i8]() 8 位有符号整型。 39 | - [i16]() 16 位有符号整型。 40 | - [i32]() 32 位有符号整型。 41 | - [i64]() 64 位有符号整型。 42 | - [i128]() 128 位有符号整型。 43 | - [isize]() 指针大小的有符号整数类型。 44 | - [pointer]() 裸指针,不安全指针, *const T 和 *mut T. 45 | - [reference]() 引用,包括共享的和可变的。 46 | - [slice]() 连续序列的动态大小视图[T]。 47 | - [str]() 字符串切片。 48 | - [tuple]() 有限非均匀序列(元组), (T, U, ..)。 49 | - [u8]() 8 位无符号整形。 50 | - [u16]() 16 位无符号整型。 51 | - [u32]() 32 位无符号整型。 52 | - [u64]() 64 位无符号整型。 53 | - [u128]() 128 位无符号整型。 54 | - [unit]() () 类型,称作 "unit" 或者 "nil". 55 | - [usize]() 指针大小的无符号整数类型。 56 | - [never]() [Experimental] `!` 类型, 也称作 "never". 57 | 58 | ### 模块 59 | 60 | - [alloc]() 内存分配API。 61 | - [any]() 这个模块实现了`Any trait`,它通过运行时反射支持任何静态类型的动态类型。 62 | - [arch]() SIMD 和 vendor 内部特性模块。 63 | - [ascii]() ASCII 字符串与字符的相关操作符。 64 | - [borrow]() 处理借用数据的模块。 65 | - [boxed]() 在堆上分配的一种指针类型。 66 | - [cell]() 可共享的可变容器。 67 | - [char]() 字符类型。 68 | - [clone]() 无法“隐式复制”类型的 `clone` trait。 69 | - [cmp]() 排序和比较。 70 | - [collections]() 集合类型。 71 | - [convert]() 类型之间转换的特性。 72 | - [default]() 可能有意义的默认值的类型的默认特性。 73 | - [env]() 检查和操作当前进程的环境变量。 74 | - [error]() 用于和错误打交道的特性。 75 | - [f32]() 这个模块提供了 `f32` 浮点数类型特有的常量。 76 | - [f64]() 这个模块提供了 `f64` 浮点数类型特有的常量。 77 | - [ffi]() 与FFI绑定有关实用工具。 78 | - [fmt]() 与格式化和打印字符串有关的实用工具。 79 | - [fs]() 文件系统相关操作。 80 | - [hash]() 泛化的HASH支持。 81 | - [hint]() 提示编译器如何触发或者优化代码的影响。 82 | - [i8]() 8位有符号整数类型。 83 | - [i16]() 16位有符号整数类型。 84 | - [i32]() 32位有符号整数类型。 85 | - [i64]() 64位有符号整数类型。 86 | - [i128]() 128位有符号整数类型。 87 | - [io]() 基础 I/O 功能 包括 特性, 帮助类, 和一些相关类型定义。 88 | - [isize]() 指针大小的有符号整数类型. 89 | - [iter]() 提供能对集合进行外部迭代的特性和结构体。 90 | - [marker]() 用于表示类型基本属性的基础特性,如 Copy。 91 | - [mem]() 用于管理内存的基础函数。 92 | - [net]() 提供 TCP/UDP 基础通信能力的模块。 93 | - [num]() 额外用于数学计算的类型。 94 | - [ops]() 可重载的操作符。 95 | - [option]() 可选的值。 96 | - [os]() 操作系统相关的基础功能。 97 | - [panic]() 标准库中panic的支持模块。 98 | - [path]() 跨平台的路径操作模块。 99 | - [pin]() 用于固定变量到内存地址的模块。 100 | - [prelude]() Rust默认引入的部分。 101 | - [process]() 一个用于处理进程的模块。 102 | - [ptr]() 通过裸指针管理内存。 103 | - [rc]() 在单线程中进行引用计数的指针类型。 'Rc' 表示 'Reference Counted'。 104 | - [result]() 提供在错误处理中使用Result类型的能力。 105 | - [slice]() 访问连续序列的一种视图, 可以使用泛型[T]. 106 | - [str]() Unicode 编码的字符切片。 107 | - [string]() UTF-8编码可持续增长的字符串 108 | - [sync]() 一些有用的进行同步的基础功能。 109 | - [thread]() 系统原生线程管理。 110 | - [time]() 时间计量工具。 111 | - [u8]() 8位无符号整数类型。 112 | - [u16]() 16位无符号整数类型。 113 | - [u32]() 32位无符号整数类型。 114 | - [u64]() 64位无符号整数类型。 115 | - [u128]() 128位无符号整数类型。 116 | - [usize]() 指针大小的无符号整数类型. 117 | - [vec]() 一种在堆上分配空间存储数据的,可持续增长的数组类型, 形如 Vec。 118 | - [future]() [实验性] 一些异步变量. 119 | - [intrinsics]() [实验性] rustc 编译器 内联函数. 120 | - [raw]() [实验性] 包含一些用于定义编译器内建类型的结构体定义。 121 | - [task]() [实验性]用于处理异步任务的一些类型和特性。 122 | 123 | ### 宏 124 | 125 | - [assert]() 该宏确保布尔表达式在运行期始终为true。 126 | - [assert_eq]() 该宏判断两个表达式求值后是否相等 (使用 PartialEq 特性)。 127 | - [assert_ne]() 该宏判断两个表达式求值后是否不相等 (使用 PartialEq 特性)。 128 | - [cfg]() 在编译时期,该宏将配置标记进行布尔表达式求值的宏。 129 | - [column]() 该宏返回当前程序所在的代码行号。 130 | - [compile_error]() 该宏可以在编译时,无条件的导致一个编译错误,并报告其所携带的错误信息。 131 | - [concat]() 该宏将多个字面量值链接成为一个静态的字符串切片。 132 | - [dbg]() 一个用于快速debug,方便检查一个表达式值的宏。 133 | - [debug_assert]() 该宏确保布尔表达式在运行期始终为true。 134 | - [debug_assert_eq]() 该宏判断两个表达式求值后是否相等。 135 | - [debug_assert_ne]() 该宏判断两个表达式求值后是否不相等。 136 | - [env]() 该宏在编译期检查并返回一个环境变量值。 137 | - [eprint]() 使用此宏可以在标准错误输出中打印信息。 138 | - [eprintln]() 使用此宏可以在标准错误输出中打印信息,并在末尾加上 `\newline`。 139 | - [file]() 该宏可以返回当前执行函数所在的文件的文件名。 140 | - [format]() 该宏使用运行期插入的表达式返回一个字符串。 141 | - [format_args]() 该宏用于创建或者输出一个格式化后的字符串。 142 | - [include]() 该宏将一个文件的内容解析并引入到当前的运行上下文中。 143 | - [include_bytes]() 以byte数组的方式对文件进行解析,并实现include。 144 | - [include_str]() 以UTF-8编码字符串的方式对文件进行解析,并实现include。 145 | - [is_x86_feature_detected]() 该宏用于测试一个cpu 特性是否可以用于 x86/x86-64 指令集平台。 146 | - [line]() which 该宏可以返回当前执行程序所在的代码行的行号。 147 | - [module_path]() 该宏返回当前文件所在的模块路径。 148 | - [option_env]() 该宏在编译期,检查一个宏,并返回使用 `Option` 类型包装的环境变量值。 149 | - [panic]() 该宏可以在一个Rust线程内引起线程恐慌。 150 | - [print]() 该宏用于将内容打印到标准输出中。 151 | - [println]() 该宏用于将内容打印到标准输出中,并在末尾加上 `\newline`。 152 | - [stringify]() 该宏可以将他的参数字符串化后返回。 153 | - [thread_local]() 声明一个新的 std::thread::LocalKey 类型变量。 154 | - [try]() 一个用于减少在匹配 Result 类型或当发生向下转型错误时的样板代码的工具宏。 155 | - [unimplemented]() 标记未完成代码的占位宏。 156 | - [unreachable]() 表明不可达代码的通用宏。 157 | - [vec]() 使用参数构建Vec的宏。 158 | - [write]() 使用该宏可以将格式化的数据写入一个buffer中。 159 | - [writeln]() 使用该宏可以将格式化的数据写入到一个buffer中,并在末尾加上 `\newline` 160 | - [await]() [实验性] 一个用于等待异步调用返回的宏。 161 | - [concat_idents]() [实验性] 该宏将多个标识符链接成为一个标识符号。 162 | - [is_aarch64_feature_detected]() [实验性] 在编译目标平台仅为 aarch64 时,被这个宏修饰的代码会被阻止编译。 163 | - [is_arm_feature_detected]() [实验性] 在编译目标平台仅为 ARM 时,被这个宏修饰的代码会被阻止编译。 164 | - [is_mips64_feature_detected]() [实验性] 在编译目标平台仅为 MIPS64 时,被这个宏修饰的代码会被阻止编译。. 165 | - [is_mips_feature_detected]() [实验性] 在编译目标平台仅为 MIPS 时,被这个宏修饰的代码会被阻止编译。 166 | - [is_powerpc64_feature_detected]() [实验性] 在编译目标平台仅为 PowerPC64 时,被这个宏修饰的代码会被阻止编译。 167 | - [is_powerpc_feature_detected]() [实验性] 在编译目标平台仅为 PowerPC 时,被这个宏修饰的代码会被阻止编译 168 | - [select]() [废弃的] [实验性] 该宏用于在一系列事件接受者中选取一个处理当前时间。 169 | 170 | ### 关键字 171 | 172 | - [as]() 用于将一个值转换为类型的关键字。 173 | - [const]() 用于定义常量。 174 | - [crate]() 用于代码库的关键字。 175 | - [enum]() 用于定义枚举。 176 | - [extern]() 用于外部模块导入。 177 | - [fn]() 用于定义函数。 178 | - [for]() for关键字。 179 | - [if]() if语句定义关键字。 180 | - [impl]() 定义特性实现的关键字。 181 | - [let]() 实现变量绑定的关键字。 182 | - [loop]() 用于定义循环的关键字。 183 | - [struct]() 用于定义结构体的关键字。 -------------------------------------------------------------------------------- /keywords/README.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /keywords/as.md: -------------------------------------------------------------------------------- 1 | # `as` -------------------------------------------------------------------------------- /keywords/const.md: -------------------------------------------------------------------------------- 1 | # `const` -------------------------------------------------------------------------------- /keywords/crate.md: -------------------------------------------------------------------------------- 1 | # `crate` -------------------------------------------------------------------------------- /keywords/enum.md: -------------------------------------------------------------------------------- 1 | # `enum` -------------------------------------------------------------------------------- /keywords/extern.md: -------------------------------------------------------------------------------- 1 | # `extern` -------------------------------------------------------------------------------- /keywords/fn.md: -------------------------------------------------------------------------------- 1 | # `fn` -------------------------------------------------------------------------------- /keywords/for.md: -------------------------------------------------------------------------------- 1 | # `for` -------------------------------------------------------------------------------- /keywords/if.md: -------------------------------------------------------------------------------- 1 | # `if` -------------------------------------------------------------------------------- /keywords/impl.md: -------------------------------------------------------------------------------- 1 | # `impl` -------------------------------------------------------------------------------- /keywords/let.md: -------------------------------------------------------------------------------- 1 | # `let` -------------------------------------------------------------------------------- /keywords/loop.md: -------------------------------------------------------------------------------- 1 | # `loop` -------------------------------------------------------------------------------- /keywords/struct.md: -------------------------------------------------------------------------------- 1 | # `struct` -------------------------------------------------------------------------------- /macros/README.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /macros/assert.md: -------------------------------------------------------------------------------- 1 | # `assert` -------------------------------------------------------------------------------- /modules/alloc.md: -------------------------------------------------------------------------------- 1 | # `alloc` -------------------------------------------------------------------------------- /modules/option.md: -------------------------------------------------------------------------------- 1 | ## std::option 2 | 3 | ### Optional values. 4 | 5 | Type Option represents an optional value: every Option is either Some and contains a value, or None, and does not. Option types are very common in Rust code, as they have a number of uses: 6 | 7 | 8 | - Initial values 9 | - Return values for functions that are not defined over their entire input range (partial functions) 10 | - Return value for otherwise reporting simple errors, where None is returned on error 11 | - Optional struct fields 12 | - Struct fields that can be loaned or "taken" 13 | - Optional function arguments 14 | - Nullable pointers 15 | - Swapping things out of difficult situations 16 | 17 | Options are commonly paired with pattern matching to query the presence of a value and take action, always accounting for the None case. 18 | 19 | ```rs 20 | fn divide(numerator: f64, denominator: f64) -> Option { 21 | if denominator == 0.0 { 22 | None 23 | } else { 24 | Some(numerator / denominator) 25 | } 26 | } 27 | 28 | // The return value of the function is an option 29 | let result = divide(2.0, 3.0); 30 | 31 | // Pattern match to retrieve the value 32 | match result { 33 | // The division was valid 34 | Some(x) => println!("Result: {}", x), 35 | // The division was invalid 36 | None => println!("Cannot divide by 0"), 37 | } 38 | ``` 39 | 40 | ### Options and pointers ("nullable" pointers) 41 | Rust's pointer types must always point to a valid location; there are no "null" pointers. Instead, Rust has optional pointers, like the optional owned box, `Option>`. 42 | 43 | The following example uses `Option` to create an optional box of `i32`. Notice that in order to use the inner `i32` value first, the check_optional function needs to use pattern matching to determine whether the box has a value (i.e. it is `Some(...)`) or not (`None`). 44 | 45 | ```rs 46 | let optional = None; 47 | check_optional(optional); 48 | 49 | let optional = Some(Box::new(9000)); 50 | check_optional(optional); 51 | 52 | fn check_optional(optional: Option>) { 53 | match optional { 54 | Some(ref p) => println!("has value {}", p), 55 | None => println!("has no value"), 56 | } 57 | } 58 | ``` 59 | 60 | This usage of Option to create safe nullable pointers is so common that Rust does special optimizations to make the representation of Option> a single pointer. Optional pointers in Rust are stored as efficiently as any other pointer type. 61 | 62 | ### Examples 63 | Basic pattern matching on Option: 64 | 65 | ```rs 66 | let msg = Some("howdy"); 67 | 68 | // Take a reference to the contained string 69 | if let Some(ref m) = msg { 70 | println!("{}", *m); 71 | } 72 | 73 | // Remove the contained string, destroying the Option 74 | let unwrapped_msg = msg.unwrap_or("default message"); 75 | ``` 76 | 77 | Initialize a result to None before a loop: 78 | 79 | ```rs 80 | enum Kingdom { Plant(u32, &'static str), Animal(u32, &'static str) } 81 | 82 | 83 | // A list of data to search through. 84 | let all_the_big_things = [ 85 | Kingdom::Plant(250, "redwood"), 86 | Kingdom::Plant(230, "noble fir"), 87 | Kingdom::Plant(229, "sugar pine"), 88 | Kingdom::Animal(25, "blue whale"), 89 | Kingdom::Animal(19, "fin whale"), 90 | Kingdom::Animal(15, "north pacific right whale"), 91 | ]; 92 | 93 | // We're going to search for the name of the biggest animal, 94 | // but to start with we've just got `None`. 95 | let mut name_of_biggest_animal = None; 96 | let mut size_of_biggest_animal = 0; 97 | for big_thing in &all_the_big_things { 98 | match *big_thing { 99 | Kingdom::Animal(size, name) if size > size_of_biggest_animal => { 100 | // Now we've found the name of some big animal 101 | size_of_biggest_animal = size; 102 | name_of_biggest_animal = Some(name); 103 | } 104 | Kingdom::Animal(..) | Kingdom::Plant(..) => () 105 | } 106 | } 107 | 108 | match name_of_biggest_animal { 109 | Some(name) => println!("the biggest animal is {}", name), 110 | None => println!("there are no animals :("), 111 | } 112 | ``` 113 | 114 | ### Structs 115 | 116 | 117 | - [IntoIter](https://doc.rust-lang.org/std/option/struct.IntoIter.html) An iterator over the value in Some variant of an Option. 118 | - [Iter](https://doc.rust-lang.org/std/option/struct.Iter.html) An iterator over a reference to the Some variant of an Option. 119 | - [IterMut](https://doc.rust-lang.org/std/option/struct.IterMut.html) An iterator over a mutable reference to the Some variant of an Option. 120 | - [NoneError](https://doc.rust-lang.org/std/option/struct.NoneError.html) [Experimental] The error type that results from applying the try operator (?) to a None value. If you wish to allow x? (where x is an Option) to be converted into your error type, you can implement impl From for YourErrorType. In that case, x? within a function that returns Result<_, YourErrorType> will translate a None value into an Err result. 121 | 122 | ### Enums 123 | Option The Option type. See [the module level documentation](https://doc.rust-lang.org/std/option/index.html) for more. 124 | -------------------------------------------------------------------------------- /modules/result.md: -------------------------------------------------------------------------------- 1 | # [std::result](https://doc.rust-lang.org/std/result/index.html) 2 | 3 | ## Error handling with the Result type. 4 | 5 | Result is the type used for returning and propagating errors. It is an enum with the variants, Ok(T), representing success and containing a value, and Err(E), representing error and containing an error value. 6 | 7 | 8 | ```rust 9 | enum Result { 10 | Ok(T), 11 | Err(E), 12 | } 13 | ``` 14 | 15 | Functions return Result whenever errors are expected and recoverable. In the std crate, Result is most prominently used for I/O. 16 | 17 | A simple function returning Result might be defined and used like so: 18 | 19 | 20 | ```rust 21 | #[derive(Debug)] 22 | enum Version { Version1, Version2 } 23 | 24 | fn parse_version(header: &[u8]) -> Result { 25 | match header.get(0) { 26 | None => Err("invalid header length"), 27 | Some(&1) => Ok(Version::Version1), 28 | Some(&2) => Ok(Version::Version2), 29 | Some(_) => Err("invalid version"), 30 | } 31 | } 32 | ``` 33 | 34 | let version = parse_version(&[1, 2, 3, 4]); 35 | match version { 36 | Ok(v) => println!("working with version: {:?}", v), 37 | Err(e) => println!("error parsing header: {:?}", e), 38 | }Run 39 | Pattern matching on Results is clear and straightforward for simple cases, but Result comes with some convenience methods that make working with it more succinct. 40 | 41 | ```rust 42 | let good_result: Result = Ok(10); 43 | let bad_result: Result = Err(10); 44 | 45 | // The `is_ok` and `is_err` methods do what they say. 46 | assert!(good_result.is_ok() && !good_result.is_err()); 47 | assert!(bad_result.is_err() && !bad_result.is_ok()); 48 | 49 | // `map` consumes the `Result` and produces another. 50 | let good_result: Result = good_result.map(|i| i + 1); 51 | let bad_result: Result = bad_result.map(|i| i - 1); 52 | 53 | // Use `and_then` to continue the computation. 54 | let good_result: Result = good_result.and_then(|i| Ok(i == 11)); 55 | 56 | // Use `or_else` to handle the error. 57 | let bad_result: Result = bad_result.or_else(|i| Ok(i + 20)); 58 | 59 | // Consume the result and return the contents with `unwrap`. 60 | let final_awesome_result = good_result.unwrap(); 61 | 62 | ``` 63 | 64 | ## Results must be used 65 | A common problem with using return values to indicate errors is that it is easy to ignore the return value, thus failing to handle the error. Result is annotated with the #[must_use] attribute, which will cause the compiler to issue a warning when a Result value is ignored. This makes Result especially useful with functions that may encounter errors but don't otherwise return a useful value. 66 | 67 | Consider the write_all method defined for I/O types by the Write trait: 68 | 69 | ```rust 70 | use std::io; 71 | 72 | trait Write { 73 | fn write_all(&mut self, bytes: &[u8]) -> Result<(), io::Error>; 74 | } 75 | ``` 76 | 77 | >Note: The actual definition of Write uses io::Result, which is just a synonym for Result. 78 | 79 | This method doesn't produce a value, but the write may fail. It's crucial to handle the error case, and not write something like this: 80 | 81 | ```rust 82 | use std::fs::File; 83 | use std::io::prelude::*; 84 | 85 | let mut file = File::create("valuable_data.txt").unwrap(); 86 | // If `write_all` errors, then we'll never know, because the return 87 | // value is ignored. 88 | file.write_all(b"important message"); 89 | ``` 90 | 91 | 92 | If you do write that in Rust, the compiler will give you a warning (by default, controlled by the unused_must_use lint). 93 | 94 | You might instead, if you don't want to handle the error, simply assert success with expect. This will panic if the write fails, providing a marginally useful message indicating why: 95 | 96 | ```rust 97 | use std::fs::File; 98 | use std::io::prelude::*; 99 | 100 | let mut file = File::create("valuable_data.txt").unwrap(); 101 | file.write_all(b"important message").expect("failed to write message"); 102 | ``` 103 | 104 | You might also simply assert success: 105 | 106 | ```rust 107 | assert!(file.write_all(b"important message").is_ok()); 108 | ``` 109 | 110 | Or propagate the error up the call stack with ?: 111 | 112 | ```rust 113 | fn write_message() -> io::Result<()> { 114 | let mut file = File::create("valuable_data.txt")?; 115 | file.write_all(b"important message")?; 116 | Ok(()) 117 | } 118 | ``` 119 | 120 | 121 | ### The question mark operator, ? 122 | 123 | When writing code that calls many functions that return the Result type, the error handling can be tedious. The question mark operator, ?, hides some of the boilerplate of propagating errors up the call stack. 124 | 125 | It replaces this: 126 | 127 | ```rust 128 | use std::fs::File; 129 | use std::io::prelude::*; 130 | use std::io; 131 | 132 | struct Info { 133 | name: String, 134 | age: i32, 135 | rating: i32, 136 | } 137 | 138 | fn write_info(info: &Info) -> io::Result<()> { 139 | // Early return on error 140 | let mut file = match File::create("my_best_friends.txt") { 141 | Err(e) => return Err(e), 142 | Ok(f) => f, 143 | }; 144 | if let Err(e) = file.write_all(format!("name: {}\n", info.name).as_bytes()) { 145 | return Err(e) 146 | } 147 | if let Err(e) = file.write_all(format!("age: {}\n", info.age).as_bytes()) { 148 | return Err(e) 149 | } 150 | if let Err(e) = file.write_all(format!("rating: {}\n", info.rating).as_bytes()) { 151 | return Err(e) 152 | } 153 | Ok(()) 154 | } 155 | ``` 156 | 157 | With this: 158 | 159 | ```rust 160 | use std::fs::File; 161 | use std::io::prelude::*; 162 | use std::io; 163 | 164 | struct Info { 165 | name: String, 166 | age: i32, 167 | rating: i32, 168 | } 169 | 170 | fn write_info(info: &Info) -> io::Result<()> { 171 | let mut file = File::create("my_best_friends.txt")?; 172 | // Early return on error 173 | file.write_all(format!("name: {}\n", info.name).as_bytes())?; 174 | file.write_all(format!("age: {}\n", info.age).as_bytes())?; 175 | file.write_all(format!("rating: {}\n", info.rating).as_bytes())?; 176 | Ok(()) 177 | } 178 | ``` 179 | 180 | It's much nicer! 181 | 182 | Ending the expression with ? will result in the unwrapped success (Ok) value, unless the result is Err, in which case Err is returned early from the enclosing function. 183 | 184 | ? can only be used in functions that return Result because of the early return of Err that it provides. 185 | -------------------------------------------------------------------------------- /modules/thread.md: -------------------------------------------------------------------------------- 1 | # [std::thread](https://doc.rust-lang.org/std/thread/index.html) 2 | 3 | ## Native threads. 4 | 5 | ### The threading model 6 | 7 | An executing Rust program consists of a collection of native OS threads, each with their own stack and local state. Threads can be named, and provide some built-in support for low-level synchronization. 8 | 9 | Communication between threads can be done through channels, Rust's message-passing types, along with other forms of thread synchronization and shared-memory data structures. In particular, types that are guaranteed to be threadsafe are easily shared between threads using the atomically-reference-counted container, Arc. 10 | 11 | Fatal logic errors in Rust cause thread panic, during which a thread will unwind the stack, running destructors and freeing owned resources. While not meant as a 'try/catch' mechanism, panics in Rust can nonetheless be caught (unless compiling with panic=abort) with catch_unwind and recovered from, or alternatively be resumed with resume_unwind. If the panic is not caught the thread will exit, but the panic may optionally be detected from a different thread with join. If the main thread panics without the panic being caught, the application will exit with a non-zero exit code. 12 | 13 | When the main thread of a Rust program terminates, the entire program shuts down, even if other threads are still running. However, this module provides convenient facilities for automatically waiting for the termination of a child thread (i.e., join). 14 | 15 | Spawning a thread 16 | 17 | ---- 18 | 19 | A new thread can be spawned using the thread::spawn function: 20 | 21 | ```rs 22 | use std::thread; 23 | 24 | thread::spawn(move || { 25 | // some work here 26 | }); 27 | ``` 28 | 29 | In this example, the spawned thread is "detached" from the current thread. This means that it can outlive its parent (the thread that spawned it), unless this parent is the main thread. 30 | 31 | The parent thread can also wait on the completion of the child thread; a call to spawn produces a JoinHandle, which provides a join method for waiting: 32 | 33 | ```rs 34 | use std::thread; 35 | 36 | let child = thread::spawn(move || { 37 | // some work here 38 | }); 39 | 40 | // some work here 41 | let res = child.join(); 42 | ``` 43 | 44 | The join method returns a thread::Result containing Ok of the final value produced by the child thread, or Err of the value given to a call to panic! if the child panicked. 45 | 46 | ### Configuring threads 47 | 48 | A new thread can be configured before it is spawned via the Builder type, which currently allows you to set the name and stack size for the child thread: 49 | 50 | 51 | ```rs 52 | use std::thread; 53 | 54 | thread::Builder::new().name("child1".to_string()).spawn(move || { 55 | println!("Hello, world!"); 56 | }); 57 | ``` 58 | 59 | ### The Thread type 60 | Threads are represented via the Thread type, which you can get in one of two ways: 61 | 62 | - By spawning a new thread, e.g. using the thread::spawn function, and calling thread on the JoinHandle. 63 | - By requesting the current thread, using the thread::current function. 64 | 65 | The thread::current function is available even for threads not spawned by the APIs of this module. 66 | 67 | ### Thread-local storage 68 | 69 | This module also provides an implementation of thread-local storage for Rust programs. Thread-local storage is a method of storing data into a global variable that each thread in the program will have its own copy of. Threads do not share this data, so accesses do not need to be synchronized. 70 | 71 | A thread-local key owns the value it contains and will destroy the value when the thread exits. It is created with the thread_local! macro and can contain any value that is 'static (no borrowed pointers). It provides an accessor function, with, that yields a shared reference to the value to the specified closure. Thread-local keys allow only shared access to values, as there would be no way to guarantee uniqueness if mutable borrows were allowed. Most values will want to make use of some form of interior mutability through the Cell or RefCell types. 72 | 73 | ### Naming threads 74 | Threads are able to have associated names for identification purposes. By default, spawned threads are unnamed. To specify a name for a thread, build the thread with Builder and pass the desired thread name to Builder::name. To retrieve the thread name from within the thread, use Thread::name. A couple examples of where the name of a thread gets used: 75 | 76 | If a panic occurs in a named thread, the thread name will be printed in the panic message. 77 | The thread name is provided to the OS where applicable (e.g. pthread_setname_np in unix-like platforms). 78 | 79 | ### Stack size 80 | 81 | The default stack size for spawned threads is 2 MiB, though this particular stack size is subject to change in the future. There are two ways to manually specify the stack size for spawned threads: 82 | 83 | - Build the thread with Builder and pass the desired stack size to Builder::stack_size. 84 | - Set the RUST_MIN_STACK environment variable to an integer representing the desired stack size (in bytes). Note that setting Builder::stack_size will override this. 85 | 86 | Note that the stack size of the main thread is not determined by Rust. 87 | 88 | ## Structs 89 | [AccessError](https://doc.rust-lang.org/std/thread/struct.AccessError.html) An error returned by LocalKey::try_with. 90 | 91 | [Builder](https://doc.rust-lang.org/std/thread/struct.Builder.html) Thread factory, which can be used in order to configure the properties of a new thread. 92 | 93 | [JoinHandle](https://doc.rust-lang.org/std/thread/struct.LocalKey.html) An owned permission to join on a thread (block on its termination). 94 | 95 | [LocalKey](https://doc.rust-lang.org/std/thread/struct.LocalKey.html) A thread local storage key which owns its contents. 96 | 97 | [Thread](https://doc.rust-lang.org/std/thread/struct.Thread.html) A handle to a thread. 98 | 99 | [ThreadId](https://doc.rust-lang.org/std/thread/struct.ThreadId.html) A unique identifier for a running thread. -------------------------------------------------------------------------------- /primitive types/array.md: -------------------------------------------------------------------------------- 1 | # `array` -------------------------------------------------------------------------------- /wiki.rs: -------------------------------------------------------------------------------- 1 | fn main(){ 2 | println!("{}","Hola"); 3 | } 4 | --------------------------------------------------------------------------------