文章目录
本文转载改编自:https://www.runoob.com/rust/rust-tutorial.html
注释
rust
// 这是第一种注释方式
/* 这是第二种注释方式 */
/*
* 多行注释
* 多行注释
* 多行注释
*/
/// 说明文档的注释
基本输出
Rust 中格式字符串中的占位符不是 "% + 字母" 的形式,而是一对 {}
。
rust
println!("a is {0}, a again is {0}", a);
在 {} 之间可以放一个数字,它将把之后的可变参数当作一个数组来访问,下标从 0 开始。
rust
println!("a is {}", a);
输出 {}
{``{
和 }}
其他常用转义字符与 C 语言里的转义字符一样,都是反斜杠开头的形式。
rust
println!("{{}}");
变量
Rust 是强类型语言,但可以自动判断变量类型。
声明变量,使用 let 关键字。
rust
// 声明为 不可变变量,被判断为有符号 32 位整型变量
let a = 123;
let a = 456; // 变量未被使用,会有警告 但不报错
// a = "abc"; // 非法,
// a = 4.56; // 非法,
// 可变
let mut b = 123;
b = 456;
// 申明为常量
const a: i32 = 123;
let a = 456;
重影(Shadowing)
重影:重新绑定,指变量的名称 可以被 重新使用的机制
重影与 可变变量的赋值 不是一个概念,重影是指 用同一个名字 重新代表 另一个变量实体,其类型、可变属性和值都可以变化。但可变变量赋值仅能发生值的变化。
rust
let x = 5;
let x = x + 1;
let x = x * 2;
println!("The value of x is: {}", x); // 12
let mut s = "123";
// s = s.len(); // 会出错:不能给字符串变量赋整型值
数据类型
整数型(Integer)
整数型简称 整型
,按照 比特位长度 和 有无符号 分为以下种类:
位长度 | 有符号 | 无符号 |
---|---|---|
8-bit | i8 | u8 |
16-bit | i16 | u16 |
32-bit | i32 | u32 |
64-bit | i64 | u64 |
128-bit | i128 | u128 |
arch | isize | usize |
isize 和 usize 两种整数类型是用来衡量数据大小的,它们的位长度取决于所运行的目标平台,如果是 32 位架构的处理器将使用 32 位位长度整型。
整数的表述方法有以下几种:
进制 | 例 |
---|---|
十进制 | 98_222 |
十六进制 | 0xff |
八进制 | 0o77 |
二进制 | 0b1111_0000 |
字节(只能表示 u8 型) | b'A' |
很显然,有的整数中间存在一个下划线,这种设计可以让人们在 输入一个很大的数字时,更容易判断数字的值大概是多少。
浮点数型(Floating-Point) f32、f64
Rust 与其它语言一样支持 32 位浮点数(f32
)和 64 位浮点数(f64
)。
默认情况下,64.0 将表示 64 位浮点数,因为现代计算机处理器对两种浮点数计算的速度几乎相同,但 64 位浮点数精度更高。
rust
let x = 2.0; // f64
let y: f32 = 3.0; // f32
数学计算
rust
let sum = 5 + 10; // 加
let difference = 95.5 - 4.3; // 减
let product = 4 * 30; // 乘
let quotient = 56.7 / 32.2; // 除
let remainder = 43 % 5; // 求余
// 自运算
sum += 1 // 等同于 sum = sum + 1
Rust 不支持 ++
和 --
布尔型 bool
布尔型用 bool 表示,值只能为 true 或 false。
字符型 char
用 char 表示,大小为 4 个字节,代表 Unicode标量值,这意味着它可以支持中文,日文和韩文字符等非英文字符,甚至 表情符号 和 零宽度空格 在 Rust 中都是有效的 char 值。
Unicode 值的范围从 U+0000 到 U+D7FF 和 U+E000 到 U+10FFFF (包括两端)。 但是,"字符"这个概念并不存在于 Unicode 中,因此您对"字符"是什么的直觉可能与Rust中的字符概念不匹配。所以一般推荐使用字符串储存 UTF-8 文字(非英文字符尽可能地出现在字符串中)。
**注意:**由于中文文字编码有两种(GBK 和 UTF-8),所以编程中使用中文字符串有可能导致乱码的出现,这是因为源程序与命令行的文字编码不一致,所以在 Rust 中字符串和字符都必须使用 UTF-8 编码,否则编译器会报错。
rust
元组 ()
用一对 ( ) 包括的一组数据,可以包含不同种类的数据:
rust
let tup: (i32, f64, u8) = (500, 6.4, 1);
// tup.0 等于 500
// tup.1 等于 6.4
// tup.2 等于 1
let (x, y, z) = tup; // y 等于 6.4
数组 []
rust
// a 是一个长度为 5 的整型数组
let a = [1, 2, 3, 4, 5];
// b 是一个长度为 3 的字符串数组
let b = ["January", "February", "March"];
// c 是一个长度为 5 的 i32 数组
let c: [i32; 5] = [1, 2, 3, 4, 5];
let d = [3; 5]; // 等同于 let d = [3, 3, 3, 3, 3];
// 数组访问
let first = a[0];
let second = a[1];
a[0] = 123; // 错误:数组 a 不可变
let mut a = [1, 2, 3];
a[0] = 4; // 正确
... 表示范围
..y
等价于0..y
x..
等价于位置 x 到数据结束..
等价于位置 0 到结束x..y
表示[x, y)
切片 slice
rust
// 字符串切片
let s = String::from("broadcast");
let part1 = &s[0..5];
let part2 = &s[5..9];
println!("{}={}+{}", s, part1, part2); // broadcast=broad+cast
let arr = [1, 3, 5, 7, 9];
let part = &arr[0..3];
for i in part.iter() {
println!("{}", i);
}
- str 是 Rust 核心语言类型,就是这里的 字符串切片(String Slice),常常以引用的形式出现(&str)。
- 用双引号包括的字符串常量整体的类型性质都是 &str :
let s = "hello";
- 切片结果必须是引用类型,但开发者必须自己明示这一点
- String 转换成 &str
rust
let s1 = String::from("hello");
let s2 = &s1[..];
结构体
- Rust 里 struct 语句仅用来定义,不能声明实例;
- 结尾不需要
;
符号 ,且每个字段定义之后用 , 分隔
rust
// 定义
struct Site {
domain: String,
name: String,
nation: String,
found: u32
}
// 实例化 - 用 JSON 对象的 key: value 语法
let runoob = Site {
domain: String::from("www.runoob.com"), // 字段名 : 字段值,
name: String::from("RUNOOB"),
nation: String::from("China"),
found: 2013
};
// 简化 - 现存变量名称 和 结构体字段名称 一样
let domain = String::from("www.runoob.com");
let name = String::from("RUNOOB");
let runoob2 = Site {
domain, // 等同于 domain : domain,
name, // 等同于 name : name,
nation: String::from("China"),
traffic: 2013
};
// 现有结构体基础上,新建结构体;不能一成不变
let site = Site {
domain: String::from("www.runoob.com"),
name: String::from("RUNOOB"),
..runoob // 后面不可以有逗号
};
// 元组结构体 - 有名字和固定的类型格式,简单数据
struct Color(u8, u8, u8);
struct Point(f64, f64);
let black = Color(0, 0, 0);
let origin = Point(0.0, 0.0);
println!("black = ({}, {}, {})", black.0, black.1, black.2); // black = (0, 0, 0)
println!("origin = ({}, {})", origin.0, origin.1); // origin = (0, 0)
枚举
rust
enum Book {
Papery, Electronic
}
let book = Book::Papery;
println!("{:?}", book);
// 描述属性
enum Book2 {
Papery(u32),
Electronic(String),
}
let book = Book2::Papery(1001);
let ebook = Book2::Electronic(String::from("url://..."));
// 为属性命名 - 可以用结构体语法
enum Book3 {
Papery { index: u32 },
Electronic { url: String },
}
let book = Book3::Papery{index: 1001};
match 处理分支
rust
let book = Book3::Papery{index: 1001};
match book {
Book::Papery { index } => {
println!("Papery book {}", index);
},
Book::Electronic { url } => {
println!("E-book {}", url);
}
}
// -> Papery book 1001
match book {
Book::Papery(i) => { // 分类1 => 返回值表达式,
println!("{}", i);
},
Book::Electronic { url } => {
println!("{}", url);
}
}
let t = "abc";
match t {
"abc" => println!("Yes"),
_ => {},
}
Option 枚举类
rust
enum Option<T> {
Some(T),
None,
}
// 定义一个可以为空值的类
let opt = Option::Some("Hello");
// 对 opt 执行某些操作,必须先判断它是否是 Option::None:
let opt = Option::Some("Hello");
match opt {
Option::Some(something) => {
println!("{}", something);
},
Option::None => {
println!("opt is nothing");
}
}
集合
向量
表示:Vec<T>
,使用方式类似于列表(List)
rust
let vector: Vec<i32> = Vec::new(); // 创建类型为 i32 的空向量
let vector = vec![1, 2, 4, 8]; // 通过数组创建向量
// 追加单个元素
vector.push(16);
vector.push(32);
vector.push(64);
println!("{:?}", vector); // [1, 2, 4, 8, 16, 32, 64]
// append 拼接两个向量
let mut v1: Vec<i32> = vec![1, 2, 4, 8];
let mut v2: Vec<i32> = vec![16, 32, 64];
v1.append(&mut v2);
println!("{:?}", v1); // [1, 2, 4, 8, 16, 32, 64]
// get 取值 - 向量的长度无法从逻辑上推断,get 无法保证一定取到值,返回值是 Option 枚举类,有可能为空。
println!("{}", match v1.get(0) {
Some(value) => value.to_string(),
None => "None".to_string()
});
// -> 1
println!("{}", v[1]); // 2
// 遍历
for i in &v {
println!("{}", i);
}
// 遍历中修改
let mut v = vec![100, 32, 57];
for i in &mut v {
*i += 50;
}
字符串
rust
// 新建
let string = String::new();
// 基础类型转换成字符串:
let one = 1.to_string(); // 整数到字符串
let float = 1.3.to_string(); // 浮点数到字符串
let slice = "slice".to_string(); // 字符串切片到字符串
// 包含 UTF-8 字符的字符串:
let hello = String::from("שָׁלוֹם");
let hello = String::from("नमस्ते");
// 追加
let mut s = String::from("run");
s.push_str("oob"); // 追加字符串切片
s.push('!'); // 追加字符
// + 拼接字符串:
let s1 = String::from("Hello, ");
let s2 = String::from("world!");
let s3 = s1 + &s2;
// 这个语法也可以包含字符串切片:
let s1 = String::from("tic");
let s2 = String::from("tac");
let s3 = String::from("toe");
let s = s1 + "-" + &s2 + "-" + &s3;
// 使用 format! 宏:
let s1 = String::from("tic");
let s2 = String::from("tac");
let s3 = String::from("toe");
let s = format!("{}-{}-{}", s1, s2, s3);
// 字符串长度:
let s = "hello";
let len = s.len(); // 5
let s = "你好";
let len = s.len(); // 6 - UTF-8 编码的,每个字符长 3 字节
let s = "hello你好";
let len = s.chars().count(); // 7 - 获得 字符集合
// 获取单个字符
let s = String::from("EN中文");
let a = s.chars().nth(2); // nth 从迭代器中取出某值;不要在遍历中这样使用,因为 UTF-8 每个字符的长度不一定相等
println!("{:?}", a); // Some('中')
let sub = &s[0..2];
println!("{}", sub); // EN
let sub = &s[0..3]; // 报错 - 肢解了字符串
映射表 Map
rust
use std::collections::HashMap;
fn main() {
let mut map = HashMap::new();
// 插入元素
map.insert("color", "red");
map.insert("size", "10 m^2");
println!("{}", map.get("color").unwrap()); // red
// 遍历
for p in map.iter() {
println!("{:?}", p); // ("color", "red")
}
// 安全插入,不覆盖原来的值;如有 就跳过。
map.entry("color").or_insert("red");
// 更快
map.insert(1, "a");
if let Some(x) = map.get_mut(&1) {
*x = "b";
}
}
函数
语法:
fn <函数名> ( <参数> ) <函数体>
- 函数名称的命名风格:小写字母 以 下划线分割
- 不在乎 在哪里 定义函数
rust
fn main() {
println!("Hello, world!");
another_function();
another_function2(5, 6);
let a = add(15, 8);
}
fn another_function() {
println!("Hello, runoob!");
}
// 声明参数名称和类型
fn another_function2(x: i32, y: i32) {
println!("x 的值为 : {}", x);
println!("y 的值为 : {}", y);
}
// 有返回值
fn add(a: i32, b: i32) -> i32 {
return a + b;
}
函数体表达式
Rust 中可以在一个用 {}
包括的块里 编写一个较为复杂的表达式:
rust
fn main() {
let x = 5;
let y = {
let x = 3;
x + 1 // 最后一个步骤 的这个表达式,它的结果值,是 整个表达快 代表的值;注:没有分号,否则它将变成一条语句。
};
println!("x 的值为 : {}", x); // 5
println!("y 的值为 : {}", y); // 4
}
函数定义可以嵌套:
rust
fn main() {
fn five() -> i32 {
5
}
println!("five() 的值为: {}", five());
}
条件语句
if
rust
let number = 3;
if number < 5 {
println!("条件为 true");
} else {
println!("条件为 false");
}
// else if
let a = 12;
let b;
if a > 0 {
b = 1;
} else if a < 0 {
b = -1;
} else {
b = 0;
}
println!("b is {}", b); // 1
// 三元
let a = 3;
let number = if a > 0 { 1 } else { -1 }; // 1
- 条件表达式 number < 5 不需要用小括号包括(注意,并非不允许)
- 条件表达式必须是 bool 类型。如
if 1
非法。
循环
while
rust
let mut number = 1;
while number != 4 {
println!("{}", number);
number += 1;
}
println!("EXIT");
let mut i = 0;
while i < 10 {
// 循环体
i += 1;
}
- 目前没有
do-while
,for-i
for-in
rust
let a = [10, 20, 30, 40, 50];
for i in a.iter() {
println!("值为 : {}", i);
}
for i in 0..5 {
println!("a[{}] = {}", i, a[i]);
}
loop
类似于 while (true)
rust
let s = ['R', 'U', 'N', 'O', 'O', 'B'];
let mut i = 0;
loop {
let ch = s[i];
if ch == 'O' {
break;
}
println!("\'{}\'", ch);
i += 1;
}
// 当作查找工具,将结果交出去
let location = loop {
let ch = s[i];
if ch == 'O' {
break i;
}
i += 1;
};
println!(" \'O\' 的索引为 {}", location); // 3
伊织 2024-05-08(三)
https://music.163.com/#/song?id=2072541999