===^^===
《榴芒客服系统》是我们工作室开发的在线客服系统,欢迎下载试用:
《榴芒客服系统》
https://blog.csdn.net/look4liming/article/details/164755808
与动态语言相比,Rust中必须明确写出各个函数参数和返回值的类型、结构体字段以及一些其它结构体。
基于已明确写出的类型,Rust的类型推断会帮你推断出剩下的大部分类型。Rust允许你省略一些类型。
类型推断让Rust具备了与动态类型语言相近的易读性,并且仍然能在编译期捕获类型错误。
函数可以使泛型的,Rust的泛型函数为语言提供了一定程序的灵活性,并仍然能在编译期捕获所有的类型错误。
虽然泛型函数更灵活,但其效率仍然与非泛型函数一样高。
Rust要求数组索引是usize值。用于表示数组或向量大小或某些数据结构中元素数量的值通常也是usize类型。
Rust中的整数字面量可以带上后缀来指示它们的类型:42u8是u8类型,1729isize是isize类型。
前缀0x、0o和0b分别表示十六进制字面量、八进制字面量和二进制字面量。
为了让长数值更易读,可以在数字之间任意插入下划线。
b'X'表示以字符X的ASCII码作为u8值。例如,由于A的ASCII码是65,因此字面量b'A'和65u8完全等效。
使用as运算符可以将一种整型转换为另一种整型:10_i8 as u16。
方法调用的优先级高于一元前缀运算符,例如,-4_i32.abs()会先针对正值4调用abs方法,生成正值4,再根据负号取负,得到-4。
当整型运算溢出时,Rust在调试构建中会出现panic,而在发布构建中回绕(取模)。
Rust几乎不会执行任何隐式的数值转换,如果函数需要f64参数,则传入i32型参数是错误的。Rust甚至不会隐式地将i16值转换为i32值。
Rust的布尔类型具有两个值true和false。
像if这样的控制结构,Rust要求它的条件必须是布尔表达式,所以可以写成这样:
if x != 0 { ... }
而不能只写成:
if x { ... }
布尔值可以转换成整型:false as i32。
但是,Rust不允许把数值类型转换成布尔类型!
char以32位值表示单个Unicode字符。
Rust对单独的字符使用char类型,但字符串和文本流使用UTF-8编码,所以,String内部存储的是UTF-8序列,而不是char数组。
u8是唯一能通过as运算符转换成char的类型。
("ABC", 123456)是一个元组,它的类型是(&str, i32)。
给定元素t,可以通过t.0、t.1等访问其元素。
元组类似于数组,但是,元组的元素可以不同的类型。
零元组也叫单元类型,它只有一个值,写作()。
不返回值的函数的返回类型为()。
元组最后一个元素的后面可以加逗号:
("ABC", 123456,)
("ABC",)是包含单个元素的元组,"ABC"后面的逗号是必需的,它可以用于区分单值元组和简单的括号表达式。
Rust旨在节省内存,值((0, 0), (1440, 900))会存储为4个相邻的整数。如果将它存储在局部变量中,则会得到4倍于整数宽度的局部变量,堆中没有分配任何内容。
&String类型的值是对String值的引用,&i32是对i32的引用,以此类推。
表达式&x会生成对x的引用,它借用了对x的引用。给定引用r,表达式*r会引用r指向的值。
Rust的引用永远不会为空,因为在Rust中没有办法生成空引用。Rust会跟踪值的所有权和生命周期,因此,在编译期就排除了悬空指针、双重释放和指针失效等错误。
Rust中,引用有两种形式:
&T
不可变共享引用。可以同时拥有多个对给定值的共享引用,但它们都是只读的
&mut T
可变的、独占的引用。可以读取和修改它指向的值。只要该引用还存在,就不能对该值有任何类型的其它引用。
在堆中分配值的最简单方式是使用Box::new。在堆中分配元素:
let t = (12, "eggs");
let b = Box::new(t);
Rust中也有裸指针类型*mut T和*const T,使用裸指针是不安全的,因为Rust不会跟踪它指向的内容。
只能在unsafe块中对裸指针解引用。
类型T; N表示有N个值的数组,每个值的类型为T。
类型Vec<T>成为T的向量,它是动态分配的,且可以增长,存在于堆中。
类型&T和&mut T成为T的共享切片和T的可变切片。
上面这3种类型中任意一种类型的值v,表达式v.len()都会给出v中的元素数,vi引用的是v的第i个元素。
创建数组:
let a: u32, 6 = 1, 2, 3, 4, 5, 6;
let b = "x", "y", "z";
数组的长度是其类型的一部分,会在编译期固定下来,想创建动态数组,需要使用向量。
向量是大小可变的数组,分配在堆上。
创建向量:
let mut primes = vec!1, 2, 3;
vec!宏相当于调用Vec::new来创建空向量,然后将元素压入其中。
从迭代器生成的值构建向量:
let v: Vec<i32> = (0..5).collect();
Vec是Rust的基本数据类型!
切片是数组或向量中的一个区域。它不能直接存储在变量中或作为函数参数进行传递,切片通过引用传递。
对切片的引用是胖指针,这个指针占用双字,包括指向切片的第一个元素的指针和切片中元素的数量。
let v: Vec<f64> = vec!1.1, 2.1, 3.1;
let a: f64; 4 = 1.1, 2.1, 3.1;
let sv: &64 = &v;
let sa: &64 = &a;
上面代码的后两行,Rust自动把&Vec<f64>的引用和&f64; 4的引用转换成了直接指向数据的切片引用。
如果函数以切片引用作为参数,可以给它传入向量或数组。
属于向量或数组的许多方法其实是在切片上定义的。
可以使用范围对数组或向量进行索引,以获得切片的引用:
print(&v0...2);
字符串可以跨越多行:
println("hello
world");
上面的字符串,换行符是字符串的一部分,第二行开头的空格也是。
如果字符串的一行以反斜杠结尾,就会丢弃其后的换行符和前导空格:
println("hello \
world");
原始字符串,用小写字母r进行标记,原始字符串不识别任何转义序列:
let s = r"ABC";
想给字符串添加双引号,在双引号前面放置反斜杠是行不通的,因为它不识别转义序列,这时,需要在原始字符串的开头和结尾添加#标记:
println(r###"
ABC"DEF
"###);
带有b前缀的字符串,是u8值的切片,而不是Unicode文本。
let method = b"GET";
method的类型是&u8; 3,它是对3字节数组的引用。
字符串不能包含任意Unicode字符,它们只能使用ASCII和\xHH转义序列。
Rust字符串使用UTF-8编码,字符串中的每个ASCII字符都会存储在单字节中,其它更大的字符会占用更多字节。
String底层的缓冲区可以调整大小,缓冲区是在堆上分配的,
可以将String视为Vec<u8>。
&str是对别人拥有的一系列UTF-8文本的引用,即它借用了这个文本。&str也是胖指针,包含实际数据的地址及长度。可以认为&str就是&u8。
字符串字面量是预分配文本的&str,和机器码一起存储在只读内存区中。
String和&str的len方法返回其长度,该长度值以字节而不是以字符为单位。
在运行期创建新字符串,使用String。
.toString()方法会将&str转换成String,这会复制此字符串。
&str可以引用任意字符串的任意切片,无论它是字符串字面量(存储在可执行文件中)还是String(在运行期分配和释放)。
字符串支持==运算符和!=运算符,如果两个字符串以相同的顺序包含相同的字符,则认为它们是相等的。
type关键字可以为现有类型声明新名称:
type Bytes = Vec<u8>;
fn decode(data: &Bytes) { ... }
===^^===
《榴芒客服系统》是我们工作室开发的在线客服系统,欢迎下载试用:
《榴芒客服系统》
https://blog.csdn.net/look4liming/article/details/164755808