Rust基础学习笔记(零):复习基本知识

因为一个学期没有碰Rust,相关知识殆已忘尽。最近各课逐渐停授,余出时间来从基础重温这些知识,也算是对没有写的基础知识的补充。另外此次复习主要参照了Youtube上的Crush Course视频,两个小时的视频一气看下来仍是很累的啊。原视频连接小程序

下载Rust,并在VSCode环境下使用

首先打开Rust官网,点击Get Started,下载对应的64位版本。运行下载程序并启用默认设置就能够。个人电脑里已经有旧版本,故只进行了更新操做。而后找到下载的bin文件夹路径添加环境变量便可,这个路径通常在users/YourName/.cargo/bin数组

而后在VSCode的插件里搜索Rust,安装列表第一个插件便可。下面运行第一个小程序。闭包

  1. 打开任意文件夹,建立一个文件Hello.rs,在里面输入以下代码:
fn main(){
      println!("Hello, World!");
}
  1. 在终端中输入rustc "Hello.rs",正常编译后会在相同路径下出现对应的Hello.exe,运行时即在终端输出
> Hello, World!

删除这些文件,在一个空文件夹里新建一个空工程。在终端输入以下指令:cargo init函数

Rust会为你自动生成一个完备的工程文件,包含一个Hello World程序。编译正常运行,到此基本配置已经结束。接下来就是Rust的一些基础使用方法。不过要指出的是这些内容并无涉及到Rust的核心,也就是说几乎只是一个套皮的C、Python、Java或者其余语言的另外一种写法。关于Rust的独到之处,还要进一步复习。在此只是记录备忘。oop

基本输出

把内容和参数打印到屏幕上多是学习每门语言最早接触的东西了。Rust输出参数的时候会用到{},是在哪里见过呢……学习

//原始形态
    println!("Hello, world!");
    //参数用{}标记
    println!("Number: {}",1+2);
    //{}中可加入指示位置的数字
    println!("{1},{0},{2},{0}",
                "Alice","Bob","Eve");
    //{}中可加入参数名,不过要在参数列表处加以说明
    println!("{name} stands by {num}",
            name = "Bob",num = 1);
    //格式化输出
    println!("Binary:{:b} Hex:{:x} Oct:{:o}",10,10,10);
    //{:?}能够输出元组,准确的说能够打印任何类型的具体信息。好像能够用来debug?
    println!("{:?}",(12,true,"Hello"));
    //参数列表能够进行简单的数学运算,这一点与C/C++等多数语言相同,再也不赘述

定义变量

Rust中定义变量通常不需指明类型,并且默认是不能够改变其中的值的。要想改变须要额外添加mut字段。spa

let name = "Brad";
    let age_1 = 20;
    //age_1 = 21;                 //这里会报错,由于默认age_1是不能够改变的
    let mut age = 20;
    println!("I am {}",age);      //输出20
    age = 21;
    println!("I am now {}", age); //输出21
    println!("My name is {}", name);
    //也能够定义常量
    const ID:i32 = 001;           //在变量名后面添加 :类型名 来指定类型
    println!("My ID: {}",ID);
    //能够一次定义多个变量
    let (my_name, my_age) = ("Bob", 20);
    println!("{} is {}", my_name, my_age);

基本类型

Rust中的一些基本类型见下:插件

  • 整形用i/u + 数字(8/16/32/64/128) 表示 如u8,i64
  • 浮点型有f32和f64两个类型
  • 布尔型 bool
  • 字符类型 Char
  • Tuples和Arrays
//普通整型默认为 "i32"类型
    let x = 1;
    //普通浮点数默认为"f64"类型
    let y = 1.2;
    //显式定义类型
    let y:i64 = 123456789;
    //显示Max size
    println!("Max i32: {}", std::i32::MAX);
    println!("Max i64: {}", std::i64::MAX);
    //定义布尔值
    let is_Act = true;
    println!("{:?}",(x,y,is_Act));
    //也能够从表达式得到bool值,不赘述*
    //甚至能够用unicode保存emoji,格式为"\u{codeX}"
    let face = '\u{1f600}';
    println!("{}",face);

字符串类型

类似,不赘述debug

let mut hello = String::from("Hello!");      //声明一个可变字符串变量
    println!("{}",hello);
    //有判空、得到长度、得到占用空间、接续字符/字符串等类方法
    println!("Length: {}",hello.len());
    hello.push('!');
    println!("{}",hello);
    hello.push_str("???");
    println!("{}",hello);
    println!("cap:{}",hello.capacity());
    println!("isEmpty:{}",hello.is_empty());
    //能够匹配内部内容,如contain返回是否包含字段,replace返回替换指定内容的字符串(不改变本来内容)
    println!("Contains \"Hello\"?: {}",hello.contains("Hello"));
    println!("Contains \"World\"?: {}",hello.contains("World"));
    println!("Replace: {}",hello.replace("llo", "LLO"));
    hello = String::from("Hello world!");
    for word in hello.split_whitespace(){
        println!("{}",word);
    }
    //能够指定字符串所占的空间
    let mut s = String::with_capacity(10);
    s.push('a');
    s.push('b');

    //断言语句,不成立时投出panic
    //assert_eq!(3,s.len());    //cause panic!
    assert_eq!(2,s.len());
    println!("{}",s);

tuple元组

元组是不一样类型数据的集合,最多拥有十二个数据。指针

let person:(&str,&str,i8) = ("Brad","Mass",20);
    println!("{} is from {} and is {}",person.0,person.1,person.2);

静态数组array

支持索引、切片。

//显式指定类型和长度
    let mut numbers :[i32;5] = [1,2,3,4,5];
    //let numbers :[i32;5] = [1,2,3,4]; //会报错-长度必须匹配
    
    println!("{:?}",numbers);
    //用索引获得单独的值
    println!("{}",numbers[1]);
    //对可变的数组能够对其中的值单独从新赋值
    numbers[2] = 12;
    println!("{:?}",numbers);
    //求长度
    println!("Array Len: {}", numbers.len());
    //这里使用std::mem库得到占有空间大小
    println!("Array occupies {} bytes",std::mem::size_of_val(&numbers));
    //切片语法
    let slc:&[i32] = &numbers[0..2];
    println!("Slice:{:?}",slc);

动态数组vectors

和array相似,能够push和pop,用迭代器进行遍历

//只要明确类型
    let mut numbers: Vec<i32> = vec![1,2,3,4];
    //添加
    numbers.push(5);
    println!("{:?}",numbers);
    //弹出首元素
    numbers.pop();
    println!("{:?}",numbers);
    //用迭代器进行遍历
    for x in numbers.iter(){
        println!("Numbers: {}",x);
    }
    //用可变迭代器能够对内容进行修改
    for x in numbers.iter_mut(){
        *x *=2;
    }
    println!("Numbers Vec:{:?}",numbers);

逻辑结构

条件语句

let age = 15;
    let gender:char = 'M';
    //If-else
    if age>=18 {
        println!("Adult!");
    } else {
        println!("Not");
    }
    if age<=18 && gender=='M'{
        println!("Boy");
    }
    //用if-else进行快速赋值,相似于?:表达式
    let is_adult = if age >= 18 {true} else {false};
    println!("An adult: {}", is_adult);

循环语句

let mut count = 0;
    //最基本的loop循环,须要内部指明跳出条件
    loop{
        count += 1;
        println!("Number: {}",count);
        if count == 5{
            break;}
    }
    //while循环,用法相似其余
    while count <= 100{
        if count % 15 == 0{
            println!("Fuzzbuzz");
        } else if count % 25 == 0{
            println!("by 25");
        } else if count % 5 == 0 {
            println!("{}",count);
        }
        count += 1;
    }
    //for循环,遍历容器中的内容
    for x in 0..20{
        if x % 5 == 0 {println!("Go!{}",x);}
    }

函数调用

参数的声明以及返回值的书写比较值得注意,闭包的写法也要注意

pub fn run(){
    greeting("Jane", "Hello");
    println!("2+3={}",add(2,3));
    //闭包可使用外部的变量
    let n3:i32 = 3;
    let add_nums = |n1:i32, n2:i32| n1 + n2 + n3;

    println!("Sum:{}",add_nums(1,2));
}

fn greeting(greet: &str, name: &str){
    println!("{},{}!",greet,name);
}

fn add(n1:i32, n2:i32) -> i32      //类型在此声明
{
    n1 + n2      //返回值后面没有分号
}

引用指针

这里只是简单的介绍,还有不少内容没有写入

let arr1 = [1,2,3];
    let arr2 = arr1;

    println!("{:?}",arr1);
    println!("{:?}",arr2);

    //Array为原生类型,所以在这里无事发生
    //非原生类型从新赋值时会致使赋值方再也不保留原来的内容,出现全部权的移交
    //这种状况下须要使用引用指针

    let vec1 = vec![1,2,3];
    let vec2 = &vec1;       //使用了引用,vec1认为无事发生
    //let vec2 = vec1;      //这个语句会致使vec1再也不拥有原来的数据
    println!("Val:{:?}",(&vec1,vec2));

结构体

比较特殊,从成员变量的声明到成员函数的加入。

//最基本的结构体,注意成员变量间用','分隔
struct Color {
    red: u8,
    green: u8,
    blue: u8,
}

//元组的形式声明的结构体
struct Color2(u8,u8,u8);

//一个部署了成员方法的结构体,方法在后面用impl引出
struct Person{
    first_name: String,
    last_name: String,
}

impl Person{
    //构造函数
    fn new(first: &str, last: &str) -> Person{
        Person{
            first_name: first.to_string(),
            last_name: last.to_string(),
        }
    }

    fn full_name(&self) -> String{
        format!("{} {}", self.first_name,self.last_name)
    }
    fn set_last_name(&mut self, last: &str){
        self.last_name = last.to_string();
    }
    fn to_tuple(self) -> (String,String){
        (self.first_name,self.last_name)
    }
}

pub fn run(){
    //最基本的初始化方法
    let mut c = Color {
        red: 255,
        green: 0,
        blue: 0,
    };
    //使用和修改时指明名称便可
    println!("Color: {} {} {}",c.red,c.green,c.blue);
    c.red = 200;
    println!("Color: {} {} {}",c.red,c.green,c.blue);
    //初始化元组结构体
    let mut d = Color2(0,255,0);
    //使用和修改时指明位置
    println!("Color: {} {} {}",d.0,d.1,d.2);
    //使用构造函数和其余成员函数
    let mut p = Person::new("John", "Doe");
    println!("Person {} {}",p.first_name,p.last_name);
    println!("Person {}",p.full_name());
    p.set_last_name("Williams");
    println!("Person {}",p.full_name());
    println!("{:?}",p.to_tuple());
}

枚举类

枚举是只有具体的几个值的数据类型。具体值由编写者肯定。

enum Movement{
    Up, Down, Left, Right
}

能够做为参数,也能够用match进行选择

fn move_avatar(m: Movement){
    match m {
        Movement::Up => println!("Avatar moving up"),
        Movement::Down => println!("Avatar moving down"),
        Movement::Left => println!("Avatar moving left"),
        Movement::Right => println!("Avatar moving right"),
    }//match相似于switch,注意用=>指向具体操做,之间用逗号分隔。
}

pub fn run(){
    let avatar1 = Movement::Up;
    let avatar2 = Movement::Down;
    let avatar3 = Movement::Left;
    let avatar4 = Movement::Right;

    move_avatar(avatar2);
    move_avatar(avatar3);
    move_avatar(avatar1);
    move_avatar(avatar4);
}

以上介绍了Rust的基本写法。

相关文章
相关标签/搜索