📔 简约我流语法笔记
常规
- 没有
i++
之类。 - 没有三目运算符。
- 代码命名规范使用
snake case
,全小写并使用_
作分隔。 - 没有用到却要留在代码里的变量加前缀
_
,例:_member
。
类型
名称 | 标志 | 备注 |
---|---|---|
布尔 | bool | |
字符 | char | 定义用单引号 |
整形 | i*(带符号),u*(无符号) | *可以是 8,16,32,64,128,size(依赖于运行程序的电脑架构) |
浮点 | f* | *为 32 或 64 |
元组 | (<类型>,<类型>) | 组合不同类型的变量 |
数组 | [<类型>;<个数>] | 可以使用 [<值>;<个数>] 来初始化数组 |
关于字符串:通常创建的硬编码字符串属于&str
,而创建可变字符串需要使用String
。
String
是以字节向量 (Vec<u8>
) 的方法存储的,始终是有效的 UTF-8 序列,分配在堆上,长度可变且不以 null 结尾。str
是始终指向有效的 UTF-8 序列的片段 (&[u8]
)。
特殊字符使用\
转义,需要\
时则使用\\
。
let a = "string";
let b = String::from("string");
Raw String
: 原始字符串,不处理文本里的任何转义。以r
开头,后面可以跟着一个或多个#
或"
。
let a = r"foo"; //foo
let b = r#""foo""#; // "foo"
元组
元组是将多种类型的多个值组合为一个复合类型的一般方法。它的长度是固定的。
fn main(){
let tup:(i32,String) = (12, "abc");
}
取出元组中的物品需要解构或者用.
取值。
fn main() {
let tup: (i32, &str) = (12, "abc");
let (x, y) = tup;
let z = tup.0;
println!("first value:{} {}", x, z);
//first value:12 12
}
数组
Rust 中的数组是定长的,不定长的使用向量。建立数组可以用通常的方括号法:
let arr: [i32; 3] = [1,2,3];
或者用同一值初始化:
let arr = [1;3]; //[1, 1, 1]
用于循环的快速索引:
for i in 0..4 {
println!("{}", i); //0 1 2 3
}
数组取值方法:
fn main() {
let arr: [i32; 3] = [1,2,3];
let first = arr[0];
}
基础类型转换
数字类型:
let a:f32 = 1.2345;
let b:i32 = a as i32; // b = 1
//如果想要其他的转换方式:
let b2: i32 = a.ceil() as i32; //b2 = 2
方法 | 作用 | 输入 1.45 | 输入 -1.45 |
---|---|---|---|
round | 四舍五入 | 1 | -1 |
trunc | 返回数字的整数部分 | 1 | -1 |
ceil | 返回大于自身的最小整数 | 2 | -1 |
floor | 返回小于自身的最大整数 | 1 | -2 |
数字与字符串互转:
let a: f32 = -1.45;
let s: String = a.to_string();
let a2: f32 = s.parse::<f32>().unwrap();
String
与&str
互转:
let s1: &str = "str";
let s2: String = s1.to_string();
let s3: &str = s2.as_str();
基础语法
变量和常量
变量使用 let
定义。默认不可变,如果需要可变则加上mut
标志。
用let
定义同名变量将覆盖原先变量(这和可变变量不一样)。
let x = 2;
let mut y = 3;
let x = 3; //x 最终等于 3,let 不能丢
y = 5;
常量使用const
定义,并必须声明类型。常量一定是不可变的,所以不用mut
。
const c:u32 = 99
函数
函数用fn
关键字定义。
fn main(){
let result = add(1,3);
println!("value:{}",result);
}
fn add(a:i64,b:i64) -> i64{
a+b
}
函数的返回值与大括号内最后的表达式同值。注意,表达式最后不带分号,带分号的属于声明(statement)。
借用使用&<变量>
。可变借用使用&mut <变量>
。同时使用的借用变量只能有一个可变借用或者多个不变借用。
注释
单行注释 //
,多行注释 /**/
。
流程
条件
使用 if <exp> {<then>} else if <exp> {<then>} else {<then>}
。
Rust 在碰到第一个满足条件的块就执行并返回,不检查后面的内容。
循环
三种循环方法:loop
、while
和for
。
fn main(){
let lo = loop {
println!("loop!");
break "loop"; //通过 break 终止循环并返回 "loop"
};
println!("loop:{}",lo);
let mut n = 3;
while n > 0 {
println!("while:{}",n);
n -= 1;
}
let list = ["a","b","c","d"];
for i in list.iter(){ //iter()
println!("for:{}",i);
}
for i in 1..6 {
println!("for:{}",i); //打印出的是 1-5
}
}
切片
数组和字符串的分割都是其一部分的引用,示例如下:
//数组
let a = [1, 2, 3, 4, 5];
let slice = &a[1..4]; //[2, 3, 4]
切片的数字是从 开始
到 结束 +1
。如果是从第一个索引开始,0 可以省略 ([..2]
)。
字符串切片:对于字符串位置的引用(所以没有对应的所有权概念)
let str = String::from("Hello");
let he = &str[0..2];
println!("{}",he);//He
//or
let he = &str[..2]; //开始为 0 可以忽略
println!("{}",he);//He
let lo = &str[3..]; //结尾为最后也可以忽略
println!("{}",lo);//lo
结构体
struct Person{
name:String,
age: u64,
}
struct Member{
id: u64,
..Person //使用 person 内的定义
}
struct Point(i32,i32) //元组结构
初始化
let p = Person {
name: String::from("Robert"),
age: 8,
};
let pt = Point(33,33);
//如果需要一个新结构体和现存的某个结构体一样,但修改部分数据
let p1 = Person {
name: String::from("Alice"),
..p
};
定义用于结构体的方法:往往在定义结构体的上下文,用self
指代结构体。
fn main(){
struct Point(i32,i32);
impl Point{
fn print(&self){
let Point(x,y) = self;
println!("(x:{},y:{})",x,y)
}
}
let pt = Point(33,33);
pt.print();
}
impl
代表 implementations , 用于定义类型的实现。
- 主要是 《The Book》 的读书笔记。
- Rustlings 的做题感想
- Strings - Rust By Example
- 封面图片:Photo by Mae Mu on Unsplash