Rust笔记
前言:
学了有段时间了,现在同步到博客园、
正文:
Rust语言介绍
l Rust由js之父开发的新型语言,打破了传统的难以接触底层的局面。这是个有C++开发的语言。拥有C的血统
l Rust必须严格区分大小写,不然会造成很麻烦的错误。
Rust基础语法
Rust声明变量:let 例子:let x=10; //x被赋值为10
Let x:i32 = 10; //x被定义为i32类型,并赋值为10
let (x,y)=(10,20); //x被给予值为10 y被给予值为20
Let注意事项:let x:i32 后面必须有值,否则会报错
let赋值不可变,如果想要可变得在let后面加上mut,或者用let重新赋值。
例子:let mut x=10; x=20; let y=20; let y=30;
Rust第一个例子:
Helo.rs
Fn main() { //fn声明了一个局部变量
Println!(“Hello word”); //println!用于输出
}
此时用rustc hello.rs
会在同一目录编译出hello,运行方式为:./hello
第二个例子:
- Rs
fn main(){
Let x:i32 = 60; //定义x为i32类型赋值为60
Println!(“{}”,x);
}
被Rustc编译后将会输出:60
第三个例子:
- Rs
Fn main(){
Let x=10;
{ //定义了一个块
Y=60;
Println!(“我能访问x和y”);
}
Println!(“我只能访问x”);
}
第三个例子告诉了我,{}定义一个块。所以这个块里的东西只有{里面才能访问到}。第二个prinln!访问不y的原因是因为是在第二个块之外访问的。
第四个例子:
- rs
Fn main(){
Let x=10; //x赋值为10
{
Println!(“我是第一个{}”,x); //输出x为10
Let x=15; //x被重新赋值为15
Println!(“我是二个{}”,x); //输出x为15
}
Println!(“我是末{}”,x);//输出x为10 因为不在第二个块里面所以重新赋值的都无效
}
第四个例子告诉我,在同一个块里,重新定义赋值是有效的。不在同一个块里里是无效的。
第五个例子:
4.rs
Fn main(){
Let X=10;
{
Let x=20;
Let mut x=”HAq”;
X=x;
Println!(“{}”,x);
}
}
第五个例子最后面会输出HAQ因为x给重新赋值了
Rust函数例子:fn 函数名(){}
例子:fn foo(){ //声明了一个foo函数
}
函数里面带参数例子:
Fn main(){
Print_number(10); //定义一个有参数的函数
}
Fn print_number(x:i32){ //调用上面所定义的函数
Println!(“This is x:{}”,x); //输出为10
}
另一个例子:
Fn main(){
Fuck(5); //定义一个有参数的函数为fuck
}
Fn fuck(x:i32){ //调用函数
Println!(“{}”,x);
}
注意事项:调用函数的时候必须在里面声明参数的类型
其他两类函数风格:
我这里只写一个,剩下那个我认为太糟糕了
Let f:fn(i32)->i32; //f是指向一个获取i32类型并返回i32类型的参数
例子:# fn plus_one(i: i32) -> i32 { i + 1 } //plus_one是指向一个获取i32类型并返回i32类型的参数,i+1
# let f = plus_one; //f等于这个函数
let six = f(5); //调用这个函数
创建函数的例子:
Fn main(){
Println!(“我是主函数”);
Foo();
}
Fn foo(){
Println!(“我是foo函数”);
}
原生类型
布尔值:let x:bool=true; let y=false; //布尔型为true或false。真或假
有符号和无符号
整型有两种变体:有符号和无符号。为了理解它们的区别,让我们考虑一个 4 比特大小的数字。一个有符号,4 比特数字你可以储存-8到+7的数字。有符号数采用“二进制补码”表示。一个无符号 4 比特的数字,因为它不需要储存负数,可以出储存0到+15的数字。
无符号类型使用u作为他们的分类,而有符号类型使用i。i代表“integer”。所以u8是一个 8 位无符号数字,而i8是一个 8 位有符号数字。
固定大小类型
固定大小类型在其表现中有特定数量的位。有效的位大小是8,16,32和64。那么,u32是无符号的,32 位整型,而i64是有符号,64 位整型。
可变大小类型
Rust 也提供了依赖底层机器指针大小的类型。这些类型拥有“size”分类,并有有符号和无符号变体。它有两个类型:isize和usize。
浮点类型
Rust 也有两个浮点类型:f32和f64。它们对应 IEEE-754 单精度和双精度浮点数。
强制转换类型: let x&str=10; //&类型 强制性转换
数组:
Let x=[80,60,70,80,90,100]
取值:x[0]这样
例子:
fn main(){
let a=[10,20,23,60,65];
println!("a长度为:{}",a.len());
println!("a的第一个数值为:{}",a[0]);
println!("a的最后一个值为:{}",a[4]);
let p=&a[1..3];
println!("a数组1到4的值为");
println!("切片之后的值还剩1和3.1的值为:{},2的值为:{}.",p[0],p[1]);
}
切片:&a[开始..结尾]
&a[1..3] //a切片之后就是20-60,等于一个新的数组了。
例子:
fn main(){
println!("数组与元组");
sz();
}
fn sz(){
let livs=["Englin","Chinse","WTF"];
println!("livs 0的值为{}",livs[0]);
println!("livs 1的值为{}",livs[1]);
println!("livs 2的值为{}",livs[2]);
println!("livs的长度为{}",livs.len());
let bs=&livs[1..2];
println!("bs是被切片出来的数组");
println!("bs 0的值是{}",bs[0]);
let g=&livs[0..1];
println!("g又被我切片出来的新数组{}",g[0]);
}
元组
定义元组为:let x=(‘haq’,’flask’); 这样
取值 x.0 //取出开的是haq
例子:
fn main(){
println!("数组与元组");
sz(); //创建一个sz的函数
yz(); //创建一个yz的函数
}
fn sz(){
let livs=["Englin","Chinse","WTF"]; //定义一个数组
println!("livs 0的值为{}",livs[0]); //取值
println!("livs 1的值为{}",livs[1]);
println!("livs 2的值为{}",livs[2]);
println!("livs的长度为{}",livs.len());
let bs=&livs[1..2]; //切片,成为一个新的数组
println!("bs是被切片出来的数组");
println!("bs 0的值是{}",bs[0]);
let g=&livs[0..1]; //切片成为一个新的数组
println!("g又被我切片出来的新数组{}",g[0]);
}
fn yz(){
let x=(1,"value"); //元组
let p:(i32,&str)=(10,"麦克雷->午时已到");
let t=(10,20,30);
let v=("何安圻","何韵欣","黎颖希");
println!("x 0:{},x 1:{}",x.0,x.1);//取值
println!("p 0:{},p 1{}",p.0,p.1);
println!("{},{},{}",v.0,v.1,v.2);
}
你可以通过一个解构let(destructuring let)访问元组中的字段。下面是一个例子:
let (x, y, z) = (1, 2, 3);
println!("x is {}", x);
判断
判断语句if
写法有js的影子。
Let x=10;
If x==10{
Println!(“x等于10”);
}Else if x==100{
Println!(“x为100”);
}else{
Println!(“x不等于10”);
}
例子:
fn main(){
rsd(); //创建了一个函数
}
fn rsd(){
let u=300; //u赋值为300
let x=[100,200]; //x赋值了一个数组
if u==x[0]{ //判断u是否等于x数组的0元素
println!("u不等等于100"); //输出
}else if u==x[1]{ //判断u是否等于x数组的1元素
println!("u等于200")
}else{ //如果都不是则判断
println!("u什么也不是");//输出
let f=(100,2000); //创建一个元组
println!("u为{},但是现在为{}",u,f.1); //输出元祖1元素
}
}
循环
Rust也有循环,有三种循环。分别为:Loop循环,while循环,for循环
Loop循环: //变相死循环
Fn main(){
Let x=1;
Loop{ //loop循环,一直循环下去直到遇见停止语句
Println!(“{}”,x);
}
}
While循环:
Fn main(){
Foo();
}
Fn foo(){
Let mut x=6; //将x定义为可以变量,赋值为6
Let mut done=false; //将done定义为可变变量,赋值为false
While !Done{ //如果条件为假,则开始循环
X+=x-3 //x加x减去3
If x%3==0{ //如果x除于3等于0
Done=true; //将done值设置为true
}
}
}
一个完整的例子:
fn main(){
foo(); //创建了一个函数
}
fn foo(){
let mut p=10; //p定义一个可变变量赋值为10
let mut done=false; //done定义为一个可变变量,赋值为布尔值的false
while !done{ //如果条件为false
p+=p-3; //p加p减去3
println!("p value:{}",p); //输出
if p%5==1{ //p%5(余数计算),当等于1的时候将done赋值为true
done=true;
}else{
println!("[-] p value {}",p); //不为if结果时输出
}
}
}
For循环:
Fn main(){
For x in 0..10{ //循环0到10
Println!(“{}”,x);
}
}
对于范围当你需要记录你已经循环了多少次了的时候,你可以使用.enumerate()函数
Enumerate用法
Fn main(){
For (key,value) in (0..10).enumerate(){ //固定范围不能大于5和大于10
Println!(“key:{},value:{}”,key,value); //输出
}
}
迭代器:
例子:
Fn main(){
Let x=”username\nadmin”.lines() //lines()用于识别\n
For (x,line) in x.enumerate(){
Println!(“{}:{}”,lines,x); //line代表循环的次数
}
}
让代码跳出循环或者重新循环
fn main(){
poos(); //定义一个poos函数
}
fn poos(){
let mut k=10; //将k赋值为10
for i in 1..10{ //循环1-9次
k+=k-3; //k加k减去3
println!("page is :{}",i); //输出循环的次数
println!("k value {}",k); //输出k的值
if k/3==1{ //如果k除于3等于1
break; //跳出循环
}
}
}
整体思路就是:
如果在这1-9次循环中,k加上k减去3。等到的结果在除于3,如果等于1则跳出循环。
fn main(){
poos();
}
fn poos(){
let mut k=5;
for i in 1..2{
k+=k-3; //如果k加上k减去3
println!("page is :{}",i);
println!("k value {}",k);
if k+1==8{ //k在加1等于8
println!("[+]k==8 continue"); //进行下一次迭代
continue;
}
}
}
Vectors
“Vector”是一个动态或“可增长”的数组,被实现为标准库类型Vec<T>(其中<T>是一个泛型语句)。vector 总是在堆上分配数据。vector 与切片就像String与&str一样。你可以使用vec!宏来创建它:
Fn main(){
bz();
}
Fn bz(){
Let h=vec![0,10,20]; //创建一个可增长数组
For c in &h{ //遍历数组
Println!(“{}”,c);
}
}
变量数组:
Let a=[10,20,30];
For i in &a{ //遍历a数组
Println!(“a value is your {}”,i);
}
权限移动:
Fn main(){
Fdr();
}
Fn wds(){
Let y=[10,11,12];
Let h=v; //权限移动,此时v数组已经移动给h。在调用y就会报错
For y in &h{
Println!(“y in {}”,y);
}
}
所有权之外(More than ownership)
当然,如果我们不得不在每个我们写的函数中交还所有权:
fn foo(v: Vec<i32>) -> Vec<i32> {
// Do stuff with `v`.
// // Hand back ownership.
v
}
这将会变得烦人。它在我们获取更多变量的所有权时变得更糟:
fn foo(v1: Vec<i32>, v2: Vec<i32>) -> (Vec<i32>, Vec<i32>, i32) {
// Do stuff with `v1` and `v2`.
// Hand back ownership, and the result of our function.
(v1, v2, 42)
}
let v1 = vec![1, 2, 3];let v2 = vec![1, 2, 3];
let (v1, v2, answer) = foo(v1, v2);
额!返回值,返回的代码行(上面的最后一行),和函数调用都变得更复杂了。
记录几个函数值:
Let v=[];
V.push(10); //push添加
Iter 外部迭代
Fold() 累加器,用一个类型闭包返回给迭代器的所有元素,得到单一的一个值
例子:
Let mut i=(0..10).fold(0,|a,b|a+b); // fold(第一个定义了0,|创建a变量对应就是值是0,创建b变量等于i,a加b)
Println!(“此时会输出{}”,i);
此时会输出:45
fn main(){
fn sum(v:&Vec<i32>)->i32{ //定义一个sum函数
return v.iter().fold(0,|a,&b|a+b); //返回迭代与一个累加器
}
let v1=vec![10,20,30]; //创建一个数组
let awser=sum(&v1); //函数引用数组
println!("v1:{}",awser); //输出
}
&mut引用
例子:
Fn main(){
Let mut p=123; //创建一个p可变变量
{
Let x=&mut p; //引用mut p
*x+=1; //x+1 此时x等于p
Println!(“{}”,x); //输出124
}
}
CarGo使用教程
- Cargo --version 查看Cargo版本
- Cargo new 项目名称 --bin 创建一个新的项目
新建的项目会有一个Cargo.toml 里面是项目信息和一个src文件夹。标准的项目格式是,src放源码。项目的根目录放与源码无关的信息
例子:
[package]
name = "hello_cargo" 项目名称
version = "0.1.0" 版本
authors = ["Your Name <you@example.com>"] 作者信息
[dependencies]
- 进入项目目录里执行cargo build 编译项目,会生成一个taget/debug文件夹里面是一些编译好的信息与编译好的可执行文件
- Cargo check 用于检查代码是否正确。一般先检查代码是否正确在进行build编译
运行项目:Cargo run 运行项目
- 优化项目Cargo build --release 用于优化项目。使代码运行起来的速度大大提高。编译的时间也会相应变长。编译好的项目不是放在target/debug里而是放在target/release
一个例子,让用户输入的项目:
Use std::io; //从std模块导出功能
Fn main(){
Println!(“这是一个让用户输入数字的例子”);
Println!(“请输入”);
Let mut gess=String::new(); //创建一个空的存储
Dk=io::stding:().read_line(&mut gess).expect(“Error”); //读取gess,如果报错则输出Error
Println!(“The gess:{}”,gess);// 输出gess
}
更新cargo.toml安装新的模块
[package]
name = "hello_cargo" 项目名称
version = "0.1.1" 版本
authors = ["Your Name <you@example.com>"] 作者信息
[dependencies]
Rnad=”0.3.14”
在dependencies下面添加要安装的模块与版本
执行cargo build更新Cargo.toml
更新让用户输入的例子项目:
Extern crate rand; //声明引用外部的rand模块
Use std::io; //导出std模块中的io功能
Use rand::Rng; //导出rand模块中的Rng功能
Fn main(){
Println!(“这里更新随机数字”);
Let sce=rand::thread_rang().gen_range(1,101); //随机数字设置
Println!(“set number sce:{}”,sce); //输出
Let mut gess=String::new(); //创建一个空的
Io:stdin().read_line(& mut gess).expect(“Error”); //读取
Println!(“gess:{}”,gess); //输出
}