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

 

 

第二个例子:

  1. Rs

fn main(){

  Let x:i32 = 60; //定义x为i32类型赋值为60

  Println!(“{}”,x);

}

Rustc编译后将会输出:60

 

第三个例子:

  1. Rs

Fn main(){

  Let x=10;

   { //定义了一个块

      Y=60;

      Println!(“我能访问x和y”);

}

 

Println!(“我只能访问x”);

}

 

第三个例子告诉了我,{}定义一个块。所以这个块里的东西只有{里面才能访问到}。第二个prinln!访问不y的原因是因为是在第二个块之外访问的。

 

 

第四个例子:

  1. 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作为他们的分类,而有符号类型使用ii代表“integer”。所以u8是一个 8 位无符号数字,而i8是一个 8 位有符号数字。

固定大小类型

固定大小类型在其表现中有特定数量的位。有效的位大小是8163264。那么,u32是无符号的,32 位整型,而i64是有符号,64 位整型。

可变大小类型

Rust 也提供了依赖底层机器指针大小的类型。这些类型拥有“size”分类,并有有符号和无符号变体。它有两个类型:isizeusize

浮点类型

Rust 也有两个浮点类型:f32f64。它们对应 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数组14的值为");

  println!("切片之后的值还剩13.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);

}

 

你可以通过一个解构letdestructuring 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; //kk减去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,ab)

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使用教程

  1. Cargo --version 查看Cargo版本
  2. Cargo new 项目名称 --bin 创建一个新的项目

新建的项目会有一个Cargo.toml 里面是项目信息和一个src文件夹。标准的项目格式是,src放源码。项目的根目录放与源码无关的信息

例子:

[package]

name = "hello_cargo" 项目名称

version = "0.1.0" 版本

authors = ["Your Name <you@example.com>"] 作者信息

[dependencies]

 

  1. 进入项目目录里执行cargo build 编译项目,会生成一个taget/debug文件夹里面是一些编译好的信息与编译好的可执行文件

 

  1. Cargo check 用于检查代码是否正确。一般先检查代码是否正确在进行build编译

运行项目:Cargo run 运行项目

  1. 优化项目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); //输出

}

posted on 2018-07-18 11:21  东京$  阅读(1162)  评论(0编辑  收藏  举报

导航