Rust语言基础
在windows10系统中搭建Rust语言开发环境搭建 参见 https://blog.csdn.net/cnds123/article/details/105770367
Rust语言注释
Rust语言使用双斜杆 “//” 和 “/* */” 作为注释符,双斜杆是行注释符,”/* */“ 是块注释符。
变量和可变性
Rust 语言使用关键字 let 来声明变量,若没有特别 mut 关键字来修饰,那么 let 所声明的变量默认是不可改变值,例如:
fn main() {
let x = 5;
println!(“The value of x is: {}”, x);
x = 6;
println!(“The value of x is: {}”, x);
}
将此代码,D:RustTest中,文件名为testA.rs
使用rustc –out-dir D:RustTest D:RustTesttestA.rs编译, 错如下:
要真正声明为一个在声明之后可以更改其值得变量的声明方式,应当是:lei mut 变量名 = 值 ;将testA.rs代码修改为:
fn main() {
let mut x = 5;
println!(“The value of x is: {}”, x);
x = 6;
println!(“The value of x is: {}”, x);
}
再次使用rustc –out-dir D:RustTest D:RustTesttestA.rs编译通过,可以D:RustTesttestA.exe运行,参见下图:
变量隐藏
在 Rust 语言中,可以定义一个之前变量同名的新变量,而新变量会 隐藏之前的变量;这意味着使用这个变量时会看到第二个值。可以用相同变量名称来隐藏一个变量,以及重复使用 let 关键字来多次隐藏,如下所示:
fn main() {
let x = 5;
let x = x + 1;
let x = x * 2;
println!(“The value of x is: {}”, x); // 输出he value of x is: 12
}
隐藏与将变量标记为 mut 是有区别的:
1)当不小心尝试对变量重新赋值时,如果没有使用 let 关键字,就会导致编译时错误。通过使用 let,我们可以用这个值进行一些计算,不过计算完之后变量仍然是不变的。
2)当再次使用 let 时,实际上创建了一个新变量,我们可以改变值的类型,但复用这个名字。
fn main() {
let s = “abc”; // 此处s是字符串类型
let s = s.len(); //此处s是数字类型
print!(“{}”,s) //输出3
}
隐藏使我们不必使用不同的名字,,我们可以复用s 这个更简单的名字。然而,如果尝试使用 mut,将会得到一个编译时错误,如下所示:
fn main() {
let mut s = “abc”;
let s = s.len();
print!(“{}”,s)
}
将会得到一个编译时错误:
变量和常量的区别
let 关键字声明的变量,在没有 mut 关键字修饰的情况下,自声明后其值是不可变的,但这并不意味这这种声明方式就是在声明常量。
Rust 语言也有声明常量的关键字:const
let 和 const 的区别(变量和常量的区别):
1)首先,不允许对常量使用 mut。常量不光默认不能变,它总是不能变。
2)声明常量使用 const 关键字而不是 let,并且 必须 注明值的类型。
3)常量可以在任何作用域中声明,包括全局作用域,这在一个值需要被很多部分的代码用到时很有用。
4)常量只能被设置为常量表达式,而不能是函数调用的结果,或任何其他只能在运行时计算出的值。
声明常量的例子:
fn main() {
const MAX_POINTS: u32 = 100_000;
}
这是一个声明常量的例子,它的名称是 MAX_POINTS,值是 100,000。(Rust 常量的命名规范是使用下划线分隔的大写字母单词,并且可以在数字字面值中插入下划线来提升可读性)。
数据类型
在 Rust 中,每一个值都属于某一个 数据类型(data type),这告诉 Rust 它被指定为何种数据,以便明确数据处理方式。我们将看到两类数据类型子集:标量(scalar)和复合(compound)。
Rust 是静态类型(statically typed)语言,也就是说在编译时就必须知道所有变量的类型。根据值及其使用方式,编译器通常可以推断出我们想要用的类型。
1、标量类型
标量(scalar)类型代表一个单独的值。Rust 有四种基本的标量类型:整型、浮点型、布尔类型和字符类型。
1.1、整型
整数 是一个没有小数部分的数字。Rust 中的所有数字类型都支持基本数学运算:加法、减法、乘法、除法和取余。
整型按比特位长度和有无符 分为一下种类:
长度 |
有符 |
无符 |
8-bit |
i8 |
u8 |
16-bit |
i16 |
u16 |
32-bit |
i32 |
u32 |
64-bit |
i64 |
u64 |
128-bit |
i128 |
u128 |
arch |
isize |
usize |
整数的表述方法有以下几种:
进制 |
例子 |
Decimal 十进制 |
98_222 |
Hex 十六进制 |
0xff |
Octal 八进制 |
0o77 |
Binary 二进制 |
0b1111_0000 |
Byte (u8 only) 字节(只能表示 u8 型) |
b’A’ |
可以使用表格中的任何一种形式编写数字字面值。注意除 byte 以外的所有数字字面值允许使用类型后缀,例如 57u8,同时也允许使用 _ 做为分隔符以方便读数,例如1_000,这种下划线设计可以让人们在输入一个很大的数字时更容易判断数字的值大概是多少。
1.2、浮点型
Rust 语言也有两个浮点数(floating-point numbers)类型,是带小数点的数字;Rust 的浮点型是 f32 和 f64;默认类型是 f64,因为在现代 CPU 中,它与 f32 速度几乎一样,不过精度更高。
例子:
fn main() {
let x = 2.0; // f64
let y: f32 = 3.0; // f32
print!(“x:{}, y:{}”,x,y);
}
Rust 中的所有数字类型都支持基本数学运算:加法、减法、乘法、除法和取余。
例子:
fn main() {
// 加法
let sum = 5 + 10;
// 减法
let difference = 95.5 – 4.3;
// 乘法
let product = 4 * 30;
// 除法
let quotient = 56.7 / 32.2;
// 取余
let remainder = 43 % 5;
println!(“sum:{}”,sum);
println!(“difference:{}”,difference);
println!(“product:{}”,product);
println!(“quotient:{}”,quotient);
println!(“remainder:{}”,remainder);
}
输出:
sum:15
difference:91.2
product:120
quotient:1.7608695652173911
remainder:3
1.3、布尔型
Rust 语言也有布尔类型,同大多数编程语言一样,Rust 语言的布尔型值也只有 true 和 false。
1.4、字符类型
Rust 语言也有字符类型,Rust 的 char 类型是语言中最原生的字母类型,如下代码展示了如何使用它。(注意 char 由单引 指定,不同于字符串使用双引 。)Rust 的 char 类型代表了一个 Unicode 标量值(Unicode Scalar Value)。
fn char_test() {
let c = ‘z’;
let z = ‘;
let heart_eyed_cat = ‘;
println!(“c:{}”,c);
println!(“z:{}”,z);
println!(“heart_eyed_cat:{}”,heart_eyed_cat);
}
输出:
c:z
z:/p>
heart_eyed_cat:/p>
2、复合类型
复合类型(Compound types)可以将多个值组合成一个类型。Rust 有两个原生的复合类型:元组(tuple)和数组(array)。
2.1、元组类型
元组,是一个将多个其他数据类型的值组合进一个复合类型的主要方式。
用包含在圆括 中的逗 分隔的值列表来创建一个元组。元组中的每一个位置都有一个类型,而且这些不同值的类型也不必是相同的。
示例:
fn main() {
let tup: (i32, f64, u8) = (500, 6.4, 1);
}
tup 变量绑定到整个元组上,因为元组是一个单独的复合元素。为了从元组中获取单个值,可以使用模式匹配(pattern matching)来解构(destructure)元组值,像这样:
fn main() {
let tup = (500, 6.4, 1);
let (x, y, z) = tup;
println!(“The value of y is: {}”, y);
}
程序首先创建了一个元组并绑定到 tup 变量上。接着使用了 let 和一个模式将 tup 分成了三个不同的变量,x、y 和 z。这叫做 解构(destructuring),因为它将一个元组拆成了三个部分。
除了使用模式匹配解构外,也可以使用点 (.)后跟值的索引来直接访问它们。例如:
fn main() {
let x: (i32, f64, u8) = (500, 6.4, 1);
let five_hundred = x.0;
let six_point_four = x.1;
let one = x.2;
}
2.2、数组类型
另一个包含多个值的方式是 数组(array)。与元组不同,数组中的每个元素的类型必须相同。Rust 中的数组与一些其他语言中的数组不同,因为 Rust 中的数组是固定长度的:一旦声明,它们的长度不能增长或缩小。
Rust 中,数组中的值位于中括 内的逗 分隔的列表中:
let a = [1, 2, 3, 4, 5];
let months = [“January”, “February”, “March”, “April”, “May”, “June”, “July”,
“August”, “September”, “October”, “November”, “December”];
数组的类型看起来像 [type; number]。例如:
#![allow(unused_variables)]
fn main() {
let a: [i32; 5] = [1, 2, 3, 4, 5];
}
访问数组元素
数组是一整块分配在栈上的内存。可以使用索引来访问数组的元素,像这样:
fn main() {
let a = [1, 2, 3, 4, 5];
let first = a[0];
let second = a[1];
println!(“The second value of array named a is {}”,second);
}
Rust内置的原生类型 (primitive types) 有以下几类:
- 布尔类型:有两个值true和false。
- 字符类型:表示单个Unicode字符,存储为4个字节。
- 数值类型:分为有符 整数 (i8, i16, i32, i64, isize)、 无符 整数 (u8, u16, u32, u64, usize) 以及浮点数 (f32, f64)。
- 字符串类型:最底层的是不定长类型str,更常用的是字符串切片&str和堆分配字符串String, 其中字符串切片是静态分配的,有固定的大小,并且不可变,而堆分配字符串是可变的。
- 数组:具有固定大小,并且元素都是同种类型,可表示为[T; N]。
- 切片:引用一个数组的部分数据并且不需要拷贝,可表示为&[T]。
- 元组:具有固定大小的有序列表,每个元素都有自己的类型,通过解构或者索引来获得每个元素的值。
- 指针:最底层的是裸指针*const T和*mut T,但解引用它们是不安全的,必须放到unsafe块里。
- 函数:具有函数类型的变量实质上是一个函数指针。
- 元类型:即(),其唯一的值也是()。
有几点是需要特别注意的:
- 数值类型可以使用_分隔符来增加可读性。
- Rust还支持单字节字符b’H’以及单字节字符串b”Hello”,仅限制于ASCII字符。 此外,还可以使用r#”…”#标记来表示原始字符串,不需要对特殊字符进行转义。
- 使用&符 将String类型转换成&str类型很廉价, 但是使用to_string()方法将&str转换到String类型涉及到分配内存, 除非很有必要否则不要这么做。
- 数组的长度是不可变的,动态的数组称为Vec (vector),可以使用宏vec!创建。
- 元组可以使用==和!=运算符来判断是否相同。
- 不多于32个元素的数组和不多于12个元素的元组在值传递时是自动复制的。
- Rust不提供原生类型之间的隐式转换,只能使用as关键字显式转换。
- 可以使用type关键字定义某个类型的别名,并且应该采用驼峰命名法。
附录
Rust 语言基础参见
https://blog.csdn.net/qq_42896653/category_9161457.html
Rust中文文档
https://wiki.jikexueyuan.com/project/rust-primer/1st-glance/README.html
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!