听闻rust大名已久,正巧赶上2023 秋冬季开源操作系统训练营,就来学习啦。
1 | fn main() { |
从最经典的打印hello world开始,可以看到和c语言比较像,都是在main函数中执行,不同的是不需要头文件,而且打印方法非常的多元。
println!
这样,从这个方法,可以看出 {} 相当于c语言中的占位符 %d。
1 | fn main() { |
这样
1 | fn main() { |
都是可以正常打印出Hello world
的。
这里提一嘴rust的编译,非常的简单,在终端源码目录下运行,即可得到一个可执行文件
1 | rustc main.rs |
变量与可变性
!!!Rust的变量是默认不可变的 这就非常的反直觉,不过这会使得程序变得更加安全,变量用let来声明
1 | let x=5 |
下面两条试图改变变量x的语句都是不合法的,要想使变量真正可变,需要在创建时加上一个mut (mutable,可变的)
1 | let mut x =5; |
常量
常量总是不可变的,使用const而不是let声明
1 | const CON: u32=3; |
在这条语句中,const表示声明一个常量,CON是名称,u32是常量的类型即无符号32位整数,常量必须是在编译阶段已经确定的
1 | const CON: u32=3+3+3 ; //编译通过 |
常量的命名规则,单词全大写并且用_连接。
基本数据类型
元组
和c语言的结构体很像,可以存储不同类型的值,引用方面比较奇怪。
元组的引用方法
方法一
1 | fn main(){ |
方法二 索引
1 | fn main(){ |
数组
1 | let a:[i32;5]={1,2,3,4,5}; //a是名字,[]里是类型 有符号32位整数 分号后面的5表示长度为5 |
输出数组,通过这个输出可以看出print之后是默认换行的
1 | fn main(){ |
函数
命名规则单词全部小写,函数的声明可以在程序的任何位置
1 | fn main(){ |
含有参数的函数
1 | fn main(){ |
含有返回值的函数,返回值需要显示地表示出来
1 | fn main(){ |
对,我没有写错,最后一行6的后面就是没有分号,我们可以这样理解:最后一行6
是一个常量表达式,它的值等于整数6
。在这个函数中,它被用作返回值。
- 表达式:先这么记,代码没有分号则是一个表达式,表达式会返回值,可以用来赋值
- 语句
let 1:i32=5
; 这就是一个语句,无返回值。
if
需要注意的是if后面的判断表达式返回值必须是bool值。
loop
就然还有loop,我只在汇编中接触过loop,可以从loop中返回一个值。
1 | fn main(){ |
loop中break和continue的用法和c语言类似。
嵌套循环
作用是精确的退出多层循环。
while和for循环
所有权概念
这里存在疑问!!!!!!!!!!!!!!!!!!
1 | fn main(){ |
按照对所有权的介绍,打印x的时候x应该已经弃用了。
变量作用域与变量隐藏
**{}**是作用域,
1 | fn main(){ |
引用与借用
s和s1的关系如下图所示。&是引用符号
首先s不是指向hello字符串的,所以不存在与s1竞争所有权的问题,其次离开s的作用域后s丢弃,s1以及hello字符串不受影响。
rustlings记录
关于if
1 | pub fn bigger(a: i32, b: i32) -> i32 { |
if语句必须跟一个else语句
slice 切片
1 | fn slice_out_of_array() { |
clone和借用
clone
1 | let s1 = String::from("Hello"); |
clone
是用于创建数据的完全拷贝,包括堆上的数据。它会复制原始数据,生成一个新的独立副本,两者之间没有关联。clone
适用于需要独立拥有数据的情况,确保对数据的修改不会影响原始数据。
借用
1 | fn print_length(s: &str) { |
借用(borrowing
)则是一种不拥有数据但可以临时访问的机制。通过借用,可以将数据的引用传递给其他代码,而无需转移所有权。在使用借用时,原始数据保持不变,可以有多个不可变引用同时存在,但只能有一个可变引用。这样可以在编译时避免数据竞争和并发问题。