rust

安装rust

安装

# windows:

https://static.rust-lang.org/rustup/dist/x86_64-pc-windows-msvc/rustup-init.exe

根据提示,安装msvc和windows sdk


# linux:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# 安装完成后需要刷新环境变量
source "$HOME/.cargo/env"


安装完成后,使用 rustc --version 验证安装成功,

# 查看版本
rustc --version

# 显示安装信息
rustup show

# 更新
rustup update

# 显示本地帮助手册
rustup doc


# 卸载
rustup self uninstall

开发工具与插件

开发工具可以选择vscode,插件可以使用rust-analyzer,注意,插件市场有一个山寨的,请看清楚作者为rust-lang.org

编写hello,world

# vi main.rs

fn main() {
    println!("Hello, world!");
}

# 使用rustc编译源文件
rustc main.rs

使用cargo构建和包管理器



# 显示管理版本
cargo --version

# 创建一个新项目
cargo new hello_cargo

# 编译,编译debug版本
cargo build

# 编译,编译release版本
cargo build --release

# 编译并运行
cargo run

# 编译检查
 cargo check

基础语法

项目结构和项目文件定义

/
/Cargo.toml                   # 项目文件定义

/src                          # 源文件目录
├--/main.rs                   # main
└--

/target                       # 编译输出目录
├--/debug                     # debug目录
└--/release                   # release目录


[package]
name = "project_name"
version = "0.1.0"
edition = "2023"


[dependencies]

基础语法


# 定义不可变变量
let x = 5;

# 定义可变变量
let mut x = 5;
x=10;

# 变量覆盖
let x = 9;

fn function_name(){
}

// 带返回值函数
// 使用 ->说明返回类型
fn fun_name() -> u32 {
    // 最后一句指令为返回值
    // 55
    // 或者使用 return
    // return 55;
}

定义结构

struct Employ {
    name: String,
    age: u32,
    sex: String,
}

fn main() {
    let mut em: Employ = Employ {
        name: String::from("董列涛"),
        age: 30,
        sex: String::from("a"),
    };
    em.name = String::from("donglietao");
    println!("{}", em.name);
}


结构作为函数返回值

fn main() {
    let em = get_employ();
  // 赋值更新
    let em2 = Employ { ..em };
    println!("{}", em.name);
    println!("{}", em2.name);


  // 打印调试信息
   println!("{:#?}", em2);
}

fn get_employ() -> Employ {
    let mut em: Employ = Employ {
        name: String::from("董列涛"),
        age: 30,
        sex: String::from("a"),
    };
    em.name = String::from("donglietao");
    return em;
}

 // 支持打印调试信息
#[derive(Debug)]
struct Employ {
    name: String,
    age: u32,
    sex: String,
}

自定义对象

fn main() {
    let em = Employ::new(String::from("董列涛"), 33, String::from("1"));
    println!("{:#?}", em.to_string());
}

// 定义数据结构
#[derive(Debug)]
struct Employ {
    name: String,
    age: u32,
    sex: String,
}

// 使用impl关键字
impl Employ {
    // 并没有构造函数一说
    fn new(name: String, age: u32, sex: String) -> Employ {
        return Employ {
            name: name,
            age: age,
            sex: sex,
        };
    }

    // 定义成员方法
    // 第一个参数self为实例本身
    fn to_string(self) -> String {
        return self.name;
    }
}

定义枚举

enum Sex {
    Main = 0,
    Woman = 1,
}

自定义包

概述

在rust中,自定义包有4个概念

package 和 crate

使用 cargo new project 创建项目后,则默认这是一个包,对应于crate的root,则为src/main.rs(二进制包:binary)或src/lib.rs(库包:library),且名字与package相同

申明module

/Cargo.toml
/src/
/src/main.rs
/src/ffmpeg_encoder/mod.rs
/src/ffmpeg_encoder/book.rs
/src/ffmpeg_encoder/people.rs


crate根文件中申明root模块,既 src/main.rssrc/lib.rs

# src/main.rs

// 引入模块
use crate::ffmpeg_encoder::book::Book;
use crate::ffmpeg_encoder::people::Employ;
use crate::ffmpeg_encoder::people::Sex;
use crate::ffmpeg_encoder::Shop;

// 定义roo module
pub mod ffmpeg_encoder;

fn main() {
    
    println!("{}", Shop::to_string());

    println!("{}", Book::new().to_string());

    let em = Employ::new(String::from("董列涛"), 33, Sex::Woman);
    println!("{}", em.to_string());
}


# 申明子模块,rust根据约定采用固定的文件命令方式,建议采用第一种,可读性更强
# src/ffmpeg_encoder/mod.rs
# src/ffmpeg_encoder.rs


pub mod book;
pub mod people;

pub struct Shop {}

impl Shop {
    pub fn to_string() -> String {
        return String::from("Shop to_string");
    }
}

# src/ffmpeg_encoder/book.rs

pub struct Book;

impl Book {
    pub(crate) fn new() -> Book {
        Book {}
    }

    pub(crate) fn to_string(&self) -> String {
        return String::from("Book to_string");
    }
}

# 编写代码文件
# src/ffmpeg_encoder/people.rs


#[derive(Debug)]
pub struct Employ {
    name: String,
    age: u32,
    sex: Sex,
}

impl Employ {
    pub fn new(name: String, age: u32, sex: Sex) -> Employ {
        return Employ {
            name: name,
            age: age,
            sex: sex,
        };
    }
    // 第一个参数self为实例本身
    pub fn to_string(&self) -> String {
        return self.name.to_string();
    }
}
#[derive(Debug)]
pub enum Sex {
    Main = 0,
    Woman = 1,
}

速查知识库

获取应用程序启动参数

    let args: Vec<String> = std::env::args().collect();

    for arg in args {
        println!("{}", arg);
    }

打印日志

# Cargo.toml
# 增加依赖


[dependencies]
log = "0.4.20"
simple_logger = "4.3.0"

# 特别注意,rust将日志接口与日志实现分开了,所以需要两个组件

# src/main.rs

use log::{debug, info, trace, warn};
use simple_logger::SimpleLogger;

fn main(){
    // 初始化日志组件
    SimpleLogger::new().init().unwrap();
    info!("application start");
}

JSON操作

# Cargo.toml
# 增加依赖
[dependencies]

serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0.68"


# src/main.rs

use log::{debug, info, trace, warn};
use serde::{Deserialize, Serialize};
use serde_json::json;
use simple_logger::SimpleLogger;

#[derive(Serialize, Deserialize)]
struct Person {
    name: String,
    age: u32,
}

async fn root() -> impl IntoResponse {
    info!("entry root");

    // 多行文本与引号可以用  r## 处理
    // 构建一段JSON字符串
    let json_str = r#"{"name": "John Doe", "age": 30}"#;

    // 将JSON字符反序列化为对象
    let json_obj: Person = serde_json::from_str(json_str).unwrap();

    // 将对象序列化为JSON字符串
    let json_str = serde_json::to_string(&json_obj).unwrap();
    log::info!("{}", json_str);

    // 创建一个匿名的JSON对象
    let json_obj = json!({"name": "John Doe", "age": 30});

    // 将匿名JSON对象序列号为字符串
    let json_str = json_obj.to_string();
    log::info!("{}", json_str);

    // 将匿名JSON对象转换为对象
    let json_obj: Person = serde_json::from_value(json_obj).unwrap();
    log::info!("{}", json_obj.name);

    return (StatusCode::OK, Json(json_obj));
}



常用库索引

两个网站

常用类库



[dependencies]
# web 框架
axum = "0.7.2"
# 一个高性能的IO库
tokio = { version = "1.35.1", features = ["full"] }
# http client
reqwest = "0.11.23"
# 日志
log = "0.4.20"
# 日志实现
simple_logger = "4.3.0"
# 序列化
serde = { version = "1.0", features = ["derive"] }
# json序列化
serde_json = "1.0.68"


实现RESTful API服务

项目依赖


[dependencies]
# 一个模块化的web应用程序框架
axum = "0.7.2"
# 一个事件驱动的非阻塞I/O库
tokio = { version = "1.35.1", features = ["full"] }
# http client
reqwest = "0.11.23"
# 日志抽象
log = "0.4.20"
# 日志实现
simple_logger = "4.3.0"
# 序列化
serde = { version = "1.0", features = ["derive"] }
# json序列化
serde_json = "1.0.68"

创建一个http server

# src/main.rs


// 引入模块
use axum::{
    http::StatusCode,
    response::{Html, IntoResponse, Json},
    routing::{get, post},
    Router,
};
use log::{debug, info, trace, warn};
use serde::{Deserialize, Serialize};
use serde_json::json;
use simple_logger::SimpleLogger;

#[tokio::main]
async fn main() {
    // 初始化日志组件
    SimpleLogger::new().init().unwrap();
    debug!("power by iovhm.com");
    warn!("©copyRight");
    trace!("2023年12月27日");
    info!("application start");

    let app = Router::new()
        // GET / 首页
        .route("/", get(root));

    let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
    info!("server listen at 0.0.0.0:3000");

    axum::serve(listener, app).await.unwrap();
}

#[derive(Serialize, Deserialize)]
struct Person {
    name: String,
    age: u32,
}

async fn root() -> impl IntoResponse {
    info!("entry root");

    // 创建一个匿名的JSON对象
    let json_obj = json!({"name": "John Doe", "age": 30});

    return Json(json_obj);
}