The Slice Type

Concept A partial reference of a contiguous sequence of elements in a collection. contiguous a data type that does not have ownership Usage String Slices let s = String::from("hello world"); let hello = &s[0..5]; let world = &s[6..11]; Like others languages, we can simpify the syntax if we want to start at the first index(zero) or include the last byte of String #![allow(unused)] fn main() { let s = String::from("hello"); let slice = &s[0..2]; let slice = &s[..2]; } #![allow(unused)] fn main() { let s = String::from("hello"); let len = s.len(); let slice = &s[3..len]; let slice = &s[3..]; } #![allow(unused)] fn main() { let s = String::from("hello"); let len = s.len(); let slice = &s[0..len]; let slice = &s[..]; } Attention String slice range indices must occur at valid UTF-8 character boundaries. String literals are slices Using string slices as parameters usually make our API more general and useful without losing any functionality.

March 15, 2021 · 1 min · ChaosNyaruko

References

References Something like &String, the concept is similar to a Pointer in C/C++/Golang/… It will not take the ownership, thus we can drop some tuple code to make it simpler. Borrowing having references as function parameters Scope A reference’s scope starts from where it is introduced and continues through the last time that reference is used. let mut s = String::from("hello"); let r1 = &s; // no problem let r2 = &s; // no problem println!("{} and {}", r1, r2); // r1 and r2 are no longer used after this point let r3 = &mut s; // no problem println!("{}", r3); Recapitulation At any given time, you can have either one mutable or any number of immutable references. References must always be valid. (Dangling references will not be allowed in Rust by compiler)

March 5, 2021 · 1 min · ChaosNyaruko

Rust中的核心概念之一-Ownership

什么是Ownership Ownership是Rust中的一个核心特点,可以理解成是Rust做到内存安全的重要手段。不同于带GC的语言或是C/C++这样显式管理内存的语言,ownership系统实现了在编译期管理内存(但又不需要程序员过分手动介入)从而避免了GC开销。 硬要说的话个人感觉像是C++中的RAII,但是由于带有编译器级别的检查,比C++更不容易出错。 Ownership的规则 Rust中所有的值(value)都有一个作为所有者(owner)的变量(variable) (一个值)同时只能有一个owner(参考Rust中赋值的Move语义和在内存管理中起到的作用) 当owner离开作用域(scope)时,其对应的值(value)就会被释放(dropped)(无论是堆上还是栈上的) 解释 Variable Scope 和其他语言类似,变量离开作用域后,就失效了。当一个变量离开作用域时,Rust会自动调用drop 函数,释放内存 Heap and Stack 和C/C++一样,Rust的内存管理也分为堆和栈,栈上内存由操作系统自动管理,堆上内存需要程序员手动管理(Rust中通过Ownership规则和编译器自动插入释放内存的语句,避免像C/C++那样的显式管理) Move Rust中的简单赋值=大多类似于其他语言中的浅拷贝,仅拷贝栈上内容。在Rust中,这种变量和数据交互(interact)的方式称为Move。当发生Move(我理解为“实际”所有权的转移)后,原变量在离开作用域后,编译器不会插入drop,从而避免内存的重复释放 这里还引出Rust的另一个设计思想:Rust永远不会“自动”(automatically)去“深拷贝”数据。因此,默认赋值行为的运行时代价都可以认为是比较低的 String结构示例 let s1 = String::from("hello") let s2 = s1 Clone 那么如果我们真的需要深拷贝一块数据需要怎么做呢,在Rust中需要显式调用clone。这实际上也是显式提醒程序员,这里有一段特殊的代码要执行,有可能消耗会比较大 fn main() { let s1 = String::from("hello"); let s2 = s1.clone(); println!("s1 = {}, s2 = {}", s1, s2); } Another wrinkle: Stack-Only Data 一些简单数据类型,像整型,我们不调用clone,也不是Move语义,原因在于,这些简单类型在编译期就能确定大小,并且完全存储于栈上,所以拷贝比较快。 Rust中有一种特殊的注解(annotation) Copytrait, 实现了这个trait类型的变量在赋值后依然可以使用。但如果实现了Droptrait,Copy就无法使用 什么样的类型可以实现Copytrait呢?可以参考官方文档,通常来说,没有需要分配资源的类型可以实现。以下是一些实现了Copy的类型 所有整型,如u32 Boolean类型,bool 浮点型, 如f64 字符类型,char 元组(Tuples),当然只能包含同样实现Copy的类型,如(i32, i32)实现了,但(i32, String)没有 Functions 函数中传参和返回值也一样有ownership的转移问题,传参即赋值,返回值会将ownship move到调用它的函数 ...

February 22, 2021 · 2 min · ChaosNyaruko

Rust Common Programming Concepts

介绍一些Rust的基本语法概念,这些概念在很多别的语言中找到类似的表示,有相同也有区分。 Variable and Mutability Rust中的变量默认是不可变的(immutable), Rust的安全性和易写并发的推手(nudge)之一 不可变变量并不等于常量(constants) 始终不可变,并且总是需要[annotate] 可以在任何范围内声明,包括全局(global) 只能用一个常量表达式(constant expression)赋值 const MAX_POINTS: u32 = 100_000; Shadowing 和mut不同 同一个名字可以成为不同的类型 Data Types Rust是静态类型语言(statically typed) 当有多种可能性编译器无法直接推导(infer)出来时,要使用类型注解(type annotation) let guess: u32 = "42".parse().expect("Not a number!"); Scalar Types integers i/u 区分有无符号 有明确大小(an explicit size) 也可以使用isize/usize表示架构相关大小(64/32) 对于原始数值类型(primitive numeric types),可以使用标准库的特定想法处理overflow, wrapping_*, checked_*, overflowing_*, saturating_* floating-point numbers f32, f64, 默认为f64 Booleans bool true/false characters char single quotes 4bytes, represents a Unicode Scalar Value(U+0000U+D7FF, U+E000U+10FFFF) Compound Types tuples fixed length the types of the different value in the tuple don’t have to be the same optional type annotations use pattern matching to destructure a tuple value x.0/x.1/….is also available arrays also fixed length(use vector if the size needs to be growed or shrinked) every element must have the same type data allocated on the stack rather than the heap optional type annotation: [type; size] [value:size]: a more concise way to initialize an array with the same value using indexing, e.g.[], to access array elements Functions ...

February 20, 2021 · 2 min · ChaosNyaruko

初识Rust

Rust简要概括 Rust是一门编译型语言 rustup是Rust工具链管理工具 rustc是Rust的编译器 cargo是Rust的高级构建工具和包管理工具 rustc可用于简单文件编译,但更建议使用cargo来进行工程化的管理,可适用于更复杂的工程 带!的“函数”是Rust中的Macro,具体见官方教程19章 可使用cargo build –release构建用于发布的应用程序 Cargo.toml可用于依赖管理, Cargo.lock具体跟踪了工程中的版本依赖(不手动修改) 参考资料 Rust官方文档rust offical docs

February 19, 2021 · 1 min · ChaosNyaruko