Rust日常笔记_持续更新_v1.0.7_Rust

文件名称版本号作者qq版本
Rust日常笔记_持续更新v1.0.7学生宫布8416837rust 1.44.1 cargo 1.46.0
rustup 1.11.0

Rust开发环境

安装基础环境

Win OS环境

使用Chocolatey软件包工具安装Rust,Chocolatey的安装教程见Chocolatey教程。或者使用其它方式安装,下载Rustup
如果是巧克力方式安装:
执行:choco search rust
在这里插入图片描述
rust包被发现,但是我们不需要直接安装rust,先安装rustup

  • 设置rustup国内镜像:
set RUSTUP_DIST_SERVER=https://mirrors.ustc.edu.cn/rust-static
set RUSTUP_UPDATE_ROOT=https://mirrors.ustc.edu.cn/rust-static/rustup

以上镜像配置当前页面有效。有可能设置镜像后报ssl错误。
如果不起效,使用PowerShell设置:

$ENV:RUSTUP_DIST_SERVER='https://mirrors.ustc.edu.cn/rust-static'
$ENV:RUSTUP_UPDATE_ROOT='https://mirrors.ustc.edu.cn/rust-static/rustup'

choco install rustup --pre
在这里插入图片描述
输入yes,开始安装

在这里插入图片描述在这里插入图片描述
Installing rustup-init...
晚上安装时,在这个初始化卡住了

  • 安装界面,查看方便点
    choco install ChocolateyGUI
    在这里插入图片描述
    打开:在这里插入图片描述
  • 查看rustup和cargo.Cargo:包管理器。类似npm、Java的Maven。

在这里插入图片描述
*

  • rustup show 查看工具链
    没有
    在这里插入图片描述
    看下存在的工具链,也可以增加工具链
    rustup toolchain list
    设置默认工具链
    rustup default stable-x86_64-pc-windows-msvc
    在这里插入图片描述
  • 组件是必需的:
    装上
rustup component add rust-src

很遗憾,不支持组件:
在这里插入图片描述

  • 安装其它版本的
    rustup toolchain install nightly-2019-01-17orrustup toolchain add nightly
    如果报ssl错误,则先不要用国内镜像
    好的开始:
    在这里插入图片描述
    移除这个
    rustup toolchain remove stable
    设置新的默认
    rustup default nightly
  • 防止报错:找不到link.exe。请安装VCBuild tools 2015
  • 检查编译器是否存在rustc -V:
    在这里插入图片描述

LINUX OS

Ubuntu

脚本
curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh # 执该命令即开始安装
source $HOME/.cargo/env # 重启console
rustc -V# out:rustc 1.53.0 (53cb7b09b 2021-06-17)
cargo -V

Cargo

# 进入项目
cargo build # 构建
cargo run # 执行

在线的IDE

进入在线编辑

Rust In IDEA

  • 安装 Rust
    在这里插入图片描述
    有点慢

  • 重启后,New Project,选择Rust
    在这里插入图片描述
    须按照上文了设置了默认工具链,新建项目才有显示rust版本1.44.1:
    在这里插入图片描述
    选择或不选择工具链、标准库
    界面:
    在这里插入图片描述
    结构详情:
    在这里插入图片描述

  • Cargo.toml
    依赖管理。如:

[dependencies]
hyper = "0.12.35"
tokio-core = "0.1.17"
futures = "0.1.29"

如果不引入依赖,则会报错找不到类。

Hello, world!

main.rs拷入代码:

fn main() {
    const X: i32 = 9;
    println!("{}", "Hello, world!".to_owned() + &X.to_string());
}

在这里插入图片描述
点绿色三角执行,执行结果:
Hello, world!9
有什么感想?比如说,类型是不是比较严格?——Java、Js用+号就可以连接两个对象了

  • exe运行
    Cargo项目,进入target/debug目录找到可执行文件,比如
.\rustTestFourth.exe

注意是.\

Rust In VsCode

辅助

依赖镜像 若引入了外部依赖,需要下载,则设置从镜像库下载

找到磁盘上的.cargo目录,新建文件名称config,填入下述内容:

[source.crates-io]
replace-with = 'tuna'

[source.tuna]
registry = "https://mirrors.tuna.tsinghua.edu.cn/git/crates.io-index.git"

如果起效了,会下载本地磁盘不存在的包,如图:
在这里插入图片描述

语法

引用别的类及函数

  1. code
// main.rs
use second::Pear;
fn main() {
    let obj = Pear::new(511, String::from("yellow"));
    obj.color();
}

// second.rs
pub struct Pear {
    size: i32,
    color: String,
}

impl Pear {
    pub fn new(size_value: i32, color_value: String) -> Pear {
        Pear {
            size: size_value,
            color: color_value
        }
    }

    pub fn color(&self) {
        println!("Its color is {}", self.color);
        self.size();
    }

    fn size(&self) {
        println!("It's large {}", self.size);
    }
}
  1. output
Its color is yellow
It's large 511

线程

  1. code

Cargo.toml
[dependencies]
chrono = { version = “0.4”, features = [“serde”] }

use std::thread;
use std::time::{Duration, SystemTime};
use chrono::{DateTime, Local, NaiveDateTime};

pub mod constant{
 pub fn get_number() -> u64 {
     2
 }
}

fn spawn_fn() {
    for i in 0..4 {
        println!("spawn {}-{}", i, Local::now().naive_local());
        thread::sleep(Duration::from_millis(constant::get_number())); // constant::get_number() 不要漏了括弧
    }
}

fn main() {
    thread::spawn(spawn_fn);

    for i in 1..5 { // 1-4 循环
        println!("main {}-{}", i, Local::now().naive_local());
        thread::sleep(Duration::from_millis(constant::get_number()));
    }
}
  1. output👇
main 1-2021-01-08 22:38:07.104416800
spawn 0-2021-01-08 22:38:07.104574500
main 2-2021-01-08 22:38:07.112333
spawn 1-2021-01-08 22:38:07.112351100
main 3-2021-01-08 22:38:07.115331800
spawn 2-2021-01-08 22:38:07.115616700
main 4-2021-01-08 22:38:07.118316
spawn 3-2021-01-08 22:38:07.118338

泛型

  1. code
struct Point<T> { // 定义结构体的属性为泛型
    x: T,
    y: T,
}

impl<T> Point<T> {
    fn x(&self) -> &T { // 返回属性之一
        &self.x
    }
}

fn main() {
    let p = Point { x: 33.19, y: 75.28 };
    println!("p.x = {}", p.x);
    println!("p.x() = {}", p.x());
    println!("p.y = {}", p.y);
}
  1. output
p.x = 33.19
p.x() = 33.19
p.y = 75.28
  1. code

结构体

  1. code
fn main() {
    #[derive(Debug)]
    struct employee {
        name: String,
        age: u8,
        isNative: bool,
    }

    let name = String::from("包惜弱");
    let isNative = false;

    let epl = employee {
        name,
        age: 17,
        isNative,
    };

    println!("这个雇员的信息:{:?}", epl);
}
  1. output
这个雇员的信息:employee { name: "包惜弱", age: 17, isNative: false }
  1. code
struct User {
    username: String,
    email: String,
    sign_in_count: u64,
    active: bool,
}

fn main() {
    let mut lord = User {
        email: String::from("VillagePeak@example.com"),
        username: String::from("元始天尊"),
        active: false,
        sign_in_count: 9999,
    };

    let ha = User {
        email: String::from("H@example.com"),
        username: String::from("通天教主"),
        ..lord // 复制部分属性
    };
    println!("激活 == {}", ha.active);
    println!("用户名 == {}", ha.username);
    println!("数目 == {}", ha.sign_in_count);
    lord.sign_in_count = 8848;
    println!("数目 == {}", ha.sign_in_count);
}
  1. output
激活 == false
用户名 == 通天教主
数目 == 9999
数目 == 9999

元组结构体

  1. code
fn main() {
    // 矩形
    struct square(u32, u32, u32, u32);
    //    三角形
    struct triangle(u32, u32, u32);
    let square1 = square(2, 3, 2, 3);
    let triangle1 = triangle(4, 4, 4);
    println!("{},{},{},{}", square1.0, square1.1, square1.2, square1.3);
    println!("{},{},{}", triangle1.0, triangle1.1, triangle1.2);
}
  1. output
2,3,2,3
4,4,4

模块 访问控制

  1. code
pub mod custom_{ // 定义模块 开放
//    pub fn max(array: &[T]) -> T {
    pub fn max(array: &[i32]) -> i32 { // pub开放max函数
        let mut max_index = 0;
        let mut i = 1;
        while i < array.len() {
            if array[i] > array[max_index] {
                max_index = i;
                println!("较大值索引是{}", i)
            }
            i += 1;
        }
        array[max_index]
    }
}

fn main() {
    let a = [9527, 27, 10010, 6, 3, 6751];
    println!("max = {}", custom_::max(&a)); // 模块::公共函数 调用
}
  1. output
较大值索引是2
max = 10010

Trait 特性

所有权 指针那些事儿

  1. 说明
    所有者:值的所有者就是变量
字符串 有没浅度拷贝、深度拷贝?
  1. code
fn main() {
    let name1 = String::from("Zhenyuan");
    let name2 = name1;
    println!("{}", name1)
}
  1. 编译报错👇
error[E0382]: borrow of moved value: `name1`
  --> src\main.rs:27:20
   |
25 |     let name1 = String::from("Zhenyuan");
   |         ----- move occurs because `name1` has type `std::string::String`, which does not implement the `Copy` trait
26 |     let name2 = name1;
   |                 ----- value moved here
27 |     println!("{}", name1)
   |                    ^^^^^ value borrowed here after move

error: aborting due to previous error; 1 warning emitted

报错原因说得很详细了,因为String没实现拷贝特性,已经移动,值已经被租了,name1已经到期了。但可以克隆值,保证所有权不变,见下文↓。
3) 值拷贝的例子↓,以下代码不报错

fn main() {
    let x1 = 9;
    let x2 = x1;
    println!("{}", x1)
}
fn main() {
    let s1 = "龙";
    let s2 = s1;
    println!("{}", s1)                                                                                                  
}
// 或者使用克隆
fn main() {
    let s1 = String::from("龙威");
    let s2 = s1.clone();
    println!("{}", s1)
}
引用 不释放所有权
  1. code
  1. output

奋斗

学习指导

网站

执行rustup命令:rustup doc --book,打开web页面,可获得匹配当前rust版本的文档,保证例子可以跑起来。

Getting Started

老规矩,Hello Everyone !
  • 代码
fn main() {
// let x = 5;
let x = "9";
    println!("{}", "Hello, world!".to_owned() + x);
}

在这里插入图片描述

  • 疑问1:为什么字符串连接要用到函数to_owned?
    答:语法使然
  • 疑问2:为什么连接个字符串,打印时,还要加{}进行格式化?
小实践
简单功能
简单的线程

代码:

use std::thread;
use std::time::Duration;

fn main() {
    thread::spawn(|| {
        for i in 1..10 {
            println!("hi number {} from the spawned thread!", i);
            thread::sleep(Duration::from_millis(1));
        }
    });

    for i in 1..5 {
        println!("hi main number {} from the main thread!", i);
        thread::sleep(Duration::from_millis(1));
    }
}

控制台输出:
在这里插入图片描述

简单的接口调用:

在Cargo.toml加入对应依赖:

[dependencies]
hyper = "0.12.35"
tokio-core = "0.1.17"
futures = "0.1.29"

代码:

extern crate futures;
extern crate hyper;
extern crate tokio_core;

use futures::Future;
use hyper::{Client, Uri};
use tokio_core::reactor::Core;

fn main() {
    // Core is the Tokio event loop used for making a non-blocking request
    let mut core = Core::new().unwrap();

    let client = Client::new();

    let url: Uri = "http://kunpeng.csdn.net/ad/474".parse().unwrap();
    assert_eq!(url.query(), None);

    let _request_result = core.run(client
        .get(url)
        .map(|res| {
            println!("Response: {}", res.status());
            println!("Response: {:?}", res.body());
        })
        .map_err(|err| {
            println!("Error: {}", err);
        })
    );
}

响应:
在这里插入图片描述
Body流需要转成明文。

读取简单的文本文件

在Cargo.toml加入对应依赖:

[dependencies]
hyper = "0.12.35"
tokio-core = "0.1.17"
futures = "0.1.29"

代码:

fn main() {
//    / Create a path to the desired file
    let path = Path::new("C:\\dev\\test\\project\\backend\\rust\\rustTestFourth\\src\\One.txt");
    let display = path.display();

    // Open the path in read-only mode, returns `io::Result<File>`
    let mut file = match File::open(&path) {
        // The `description` method of `io::Error` returns a string that
        // describes the error
        Err(why) => panic!("couldn't open {}: {}", display,
                           why.description()),
        Ok(file) => file,
    };

    // Read the file contents into a string, returns `io::Result<usize>`
    let mut s = String::new();
    match file.read_to_string(&mut s) {
        Err(why) => panic!("couldn't read {}: {}", display,
                           why.description()),
        Ok(_) => print!("{} contains:\\n{}", display, s),
    }

    // `file` goes out of scope, and the "hello.txt" file gets closed
}

控制台输出响应,该响应是文件的具体内容。

打印控制台的输入
use std::io;

fn main() {
    println!("Guess the number!");

    println!("Please input your guess.");

    let mut guess = String::new();

    io::stdin()
        .read_line(&mut guess)
        .expect("Failed to read line");

    println!("You guessed: {}", guess);
}
引入依赖库
  • 引入依赖*
[dependencies]
ferris-says = "0.1"
  • 主代码-打印Logo
use std::io::{BufWriter, stdin, stdout};
use ferris_says::say;

fn main() {
    println!("I'm cc");
    println!("Movie Starting");
    let standout = stdout();
    let message = String::from("TV Play");
    //    获取msg的宽度
    let mut buf = BufWriter::new(standout.lock());
    say(message.as_bytes(), message.chars().count(), &mut buf); // 播放小电影
    println!("打印的{}", message); // 比say早输出
}

注意standout是点不是括弧

  • 编译,引入新包后,编译时下载:
    在这里插入图片描述
  • 执行结果:
    在这里插入图片描述
猜数字游戏
fn recIn(correctlyMsg: i32) {
    let mut msg = String::new();
    let inIn = io::stdin()
        .read_line(&mut msg)
        .expect("Fmt failed");
    let inNum: i32 = msg.trim().parse::<i32>().unwrap();
    if (inNum == correctlyMsg) { // todo 改成Switch
        println!("Your answer is correctly {}", msg)
    } else {
        let mut ret = String::new();
        if inNum > correctlyMsg { // todo rust的三目运算符则搞?
            ret = "bigger".to_string();
        } else {
            ret = "smaller".to_string();
        }

        println!("Sorry.Wrong.Your input is {} {}", ret, msg);
        recIn(correctlyMsg);
    }
}

fn main() {
    println!("Come to one Game");
    println!("Please input your answer,it's one number");

    let msg2 = 32;

    recIn(msg2);

    return;
}

在这里插入图片描述

猜数字游戏2
  • 引入依赖,随机数
[dependencies]
rand = "0.6.0"

下载依赖,好像下载了不少包:
在这里插入图片描述

  • 主代码
use std::io;
use rand::Rng;

fn main() {
    println!("Hello, world!");
    let num = rand::thread_rng().gen_range(500, 505); // 随机数

    println!("Please input one number");
    let mut msg = String::new();
    io::stdin()
        .read_line(&mut msg)
        .expect("Failed");
    println!("Your input is {}", msg);
    println!("Correctly number is {}", num);
}

还是同样,使用stdin标准输入,接收控制台输入并与变量的指针关联,这样才可打印正确。

猜数字游戏3
  • 这次升级了,代码优雅了点:
use std::io;
use std::cmp::Ordering;
use rand::Rng;
use rand::seq::index::IndexVec::U32;

fn main() {
    println!("Hello, world!");
    let right:String = rand::thread_rng().gen_range(500, 505).to_string(); // 随机数

    println!("Please input one number");
    let mut guess = String::new();
    io::stdin()
        .read_line(&mut guess)
        .expect("Failed");
    println!("Your guess is {}", guess);
    match guess.trim().cmp(&right) {
        Ordering::Less => println!("太小"),
        Ordering::Greater => println!("太大"),
        Ordering::Equal => println!("胜利"),
    };
        println!("Correctly number is {}", right);
}

使用工具use std::cmp::Ordering;进行大小比较操作,那这个例子字符串和数字怎么比呀,我改成了字符串和字符串比,实验了一下也能行

猜数字游戏4 强转 循环
fn main() {
    let secretNumber: u32 = 35;

    loop {
        let mut num1: String = String::new();
        io::stdin().read_line(&mut num1).expect("异常");
        // let num1: u32 = num1.trim().parse().expect("强转失败");
        let num1: u32 = match num1.trim().parse(){
            Ok(num) => num,
            Err(_) => continue
        };

        println!("Please input your number");

        match num1.cmp(&secretNumber) {
            Ordering::Less => {
                println!("Too small");
                continue;
            }
            Ordering::Greater => {
                println!("Too Large");
                continue;
            }
            Ordering::Equal => {
                println!("Success");
                println!("Your number is {}", num1);
                break;
            }
        }
    }
}
实现接口
//结构体 实现接口
pub mod kongfu_background {
    // 演武场
    pub struct Box {
        // 打拳
        size: String,
        power: String,
        pub name: String,
    }

    // 实现
    impl Box {
        pub fn punches(name: &str) -> Box { //  pub 公开函数
            Box {
                size: String::from("Long"),
                power: String::from("75%"),
                name: String::from(name),
            }
        }
    }
}

fn main() {
    let mut box1 = kongfu_background::Box::punches("x"); // 注意加分号
    println!("{}", box1.name);
    box1.name = String::from("形意拳");
    println!("{}", box1.name)
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值