Rust语言开发

博客 分享
0 378
张三
张三 2022-02-18 14:55:30
悬赏:0 积分 收藏

Rust语言开发

Rust开发

第一个程序 fn main() {    println!("Hello, world!");  // 带!号的都是宏 并不是函数}fn main() {    let name = "peter";    println!("{}{}","Hello, world!", name);}cargo new projectname // 创建一个rust项目cargo build  // 构建程序为可执行程序cargo run  // 运行构建好的可执行程序
  • 创建自定义函数
#![allow(non_snake_case)]fn main() {    let name = "peter";    println!("{}{}","Hello, world!", name);    show_me()}fn show_me() {    let name = "peter";    let age = 21;    println!("my name is {}, age is {}", name, age)}
  • 创建模块 使用模块
#![allow(non_snake_case)]fn main() {    let name = "peter";    println!("{}{}","Hello, world!", name);    lib::show_me()  // 引用模块内的函数 ::}mod lib {  // pub声明函数是公有地 可以使用 模块进行调用函数执行    pub fn show_me() {        let name = "peter";        let age = 21;        println!("my name is {}, age is {}", name, age)    }}
  • 函数传参 定义str类型 int i32 i64 类型
#![allow(non_snake_case)]fn main() {    let name = "peter";    println!("{}{}","Hello, world!", name);    // lib::show_me();    let uid = 101;    println!("{}", get_user(uid))}// &'static str 声明str类型// i64 i32 声明int类型 fn get_user(uid:i64) -> &'static str {    return if uid == 101 {        "root"    } else if uid == 102 {        "$pub"    } else {        "error"    }}

上边的写法 可以换成下方这种

#![allow(non_snake_case)]fn main() {    let name = "peter";    println!("{}{}","Hello, world!", name);    // lib::show_me();    let uid = 101;    println!("{}", get_user(uid));}fn get_user(uid:i64) -> &'static str {    let ret = if uid == 101 {        "root"    } else if uid == 102 {        "$pub"    } else {        "error"    };    ret}
  • if 的高阶写法
    let age = 2;    let new_age = if age == 2 {        5    }else {        10    };    println!("{}", age)
  • for 循环
    // .chars 将字符串类型转换为可迭代对象iter    for i in text.chars(){        println!("{}",i);    };
  • switch 写法 =>match
    // rust中的switch写法match    match text.len() {        // 如果长度等于4 打印ok        4 => println!("ok!"),      	// 1..=3是[1,2,3] 全部闭合              	//1..3 是[1,2] 左开右闭合        // 如果text长度在5-20之间打印normal         5..=20 => println!("normal"),        // _ 否则        _ => println!("sorry"),    };
  • string 堆栈
// 考虑下面这段代码  在内存的角度发生了什么?let name = String::from("abc");abc的ptr            0  aabc的len            1  babc的cap						 2  c  堆                 栈堆放具体的数据   栈存在数据的地址及数据的基本信息(长度, 容量, 内存地址)语言的垃圾回收 回收的是堆   栈存放的主要是函数之类的 调用完自动回收 无需使用语言的垃圾回收器回收RUST 常见的符号 :? -> debug:o -> 8进制数:x -> lower 小写16进制数:X -> upper 大写16进制数:p -> Pointer 指针:b -> Binary  二进制例子 :    let test = String::from("abc");    // 打印内存地址    println!("{:p}", test.as_ptr())
  • 所有者 (rust语言很重要的特性ownership)
// 注: 所有者有且只能有一个// 这个me就是String的所有者ownershiplet me = String::from("abc");// 例如 将me赋值给you  me变量将失去所有String的权利属性  you将获得所有权变为所有者let me = String::from("123");let you = me;// 解决这种问题 // 1.可以使用me.clone() 将堆栈复制开辟新的内存空间let you = me.clone();// 2.可以使用&me引用的方式, 这种方式you 就是me的所有者 me就是String的所有者  let you = &me;// 如果使用下面的是没有问题的&str不是string 执行String才会有所有权的问题let me = "123";let you = me; 
  • 所有者理解
#![allow(non_snake_case)]fn show_len(s: &String) { // &传入指针 就不会出现所有者 转移的情况    println!("{}", s.len())}pub fn test() {    let test = String::from("abc");    show_len(&test);  // 这里如果传入的不是指针 就相当于let s = test; 所有者转移 后边的内存地址是打印不出来的    // 打印内存地址    println!("{:p}", test.as_ptr())}// 所以在进行函数传参时 除非这个参数后边不在用了只给函数用了 否则我们要传指针&类型 
  • 可变参数 mut
// 上述的参数都不是可变参数定义之后不可修改 声明可变参数关键词为mut#![allow(non_snake_case)]fn show_len(s: &mut String) { // &传入指针 就不会出现所有者 转移的情况    println!("{}", s.len());    s.push_str("123")}pub fn test() {    let mut test = String::from("abc");    show_len(&mut test);  // 这里如果传入的不是指针 就相当于let s = test; 所有者转移 后边的内存地址是打印不出来的    // 打印内存地址    println!("{:p} {}", test.as_ptr(), test)    }
  • 结构体 struct
struct User{    name: String,    age: i64}    let user = User{name:String::from("zhangJiAn"), age: 123};
  • Sturct 定义方法进行面向对象
// 相当于go中的 func (this *User) getUser() {}#[derive(Debug)]struct User{    name: String,    age: u8}// 实现方法的关键词implimpl User{    fn version(&self){        println!("测试rust中的方法面向对象");    }    fn to_String(&self) -> String{        format!("{}{}", self.name, self.age)    }}    let user = User{name:String::from("zhangJiAn"), age: 123};    println!("{:?}", user);		// User { name: "zhangJiAn", age: 123 }    user.version();		// 测试rust中的方法面向对象    println!("{}", user.to_String())		// zhangJiAn123
  • 数组
    // 同let me: &str = "fgag"		// let tags = ["python", "vue", "js", "golang", "rust"];    let tags: [&str; 5] = ["python", "vue", "js", "golang", "rust"];		    for i in tags {        println!("{}", i)    }
  • 创建空数组 , 并赋值
    let mut tags: [u8; 10] = [0;10];    for item in 0..tags.len() {        tags[item] = item as u8;    }    println!("{:?}", tags)
  • 元祖
    let tags: (&str, i32) = ("", 10);    println!("{:?}",tags)		// ("", 10)
  • rust 泛型
// 泛型就是 一个函数中传形参的时候 我可以 传入不同类型的参数 给形参 // 这个形参的类型 由我引用的的时候自己指定即可// model/user_model.rs#[derive(Debug)]pub struct UserScore <A,B>{    pub user_id: A,    pub score: B,    pub comment: &'static str,}pub fn get_user_score_first() -> UserScore<i32, i32> {    UserScore {        user_id: 1,        score: 90,        comment: "A类用户",    }}// 泛型的关键  就在这 可以允许传入不同的类型的A,B  例如 [int, str, bool] and [str, float, bool] 可以提取出bool// UserScore中有了泛型  impl中也需要标明泛型A,Bimpl <A,B> UserScore<A,B> {    pub(crate) fn get_uid(&self) -> &'static str {        &self.comment    }}pub fn get_user_score_second() -> UserScore<&'static str, f32> {    UserScore {        user_id: "xxx111100",        score: 90.0,        comment: "B类用户",    }}// model/mod.rspub mod user_model;// main.rs    let mut score = model::user_model::get_user_score_first();    score.score = 10;    println!("{:?}", score.get_uid());    let score = model::user_model::get_user_score_second();    println!("{:?}", score.get_uid());		// "A类用户"		// "B类用户"
  • trait 共享行为 (接口设计)

trait 类似于java中的抽象类 将公共的方法抽离出来 可以被子类继承

// api/prods.rs use crate::model::book_model::Book;// 定义好公共函数pub trait Prods {    fn get_price(&self) -> f32 ;}// 在需要使用公共函数的方法中 实现这个 函数方法 即可impl Prods for Book {    fn get_price(&self) -> f32 {        &self.price + 10.0    }}// model/book_model.rs#[derive(Debug)]pub struct Book {    pub id: i32,    pub price: f32}pub fn new_book(id: i32, price: f32) -> Book {    Book{        id,        price,    }}main.rs    let book = model::book_model::new_book(1, 99.9);    println!("{:?}", book.get_price())		// 109.9
  • trait 简便实例化函数
// model/book_model.rs#[derive(Debug)]pub struct Book {    pub id: i32,    pub price: f32}// api/prods.rsuse crate::model::book_model::Book;// 定义好公共函数pub trait Prods {    fn new(id: i32, price: f32) -> Self;    fn get_price(&self) -> f32 ;}// 在需要使用公共函数的方法中 实现这个 函数方法 即可  (基于Book结构体实现的Prods trait实现的方法)impl Prods for Book {    // 基于trait实现的方法可以直接 通过方法实例化    fn new(id: i32, price: f32) -> Book {        Book{            id,            price        }    }    fn get_price(&self) -> f32 {        &self.price + 10.0    }}// main.rs    // 这样使用需要 声明book 所对应实现的struct结构体    let book: Book = api::prods::Prods::new(2, 88.8);    println!("{:?}", book.get_price())		// 98.8
  • 在函数中传递两个trait
// api/prods.rsuse crate::model::book_model::Book;use crate::model::iphone_model::Phone;// 定义好公共函数pub trait Prods {    fn new(id: i32, price: f32) -> Self;    fn get_price(&self) -> f32 ;}// 在需要使用公共函数的方法中 实现这个 函数方法 即可  (基于Book结构体实现的Prods trait实现的方法)impl Prods for Book {    // 基于trait实现的方法可以直接 通过方法实例化    fn new(id: i32, price: f32) -> Book {        Book{            id,            price        }    }    fn get_price(&self) -> f32 {        &self.price + 10.0    }}impl Prods for Phone {    fn new(id: i32, price: f32) -> Self {        Self {            id,            price        }    }    fn get_price(&self) -> f32 {        &self.price + 22.0    }}// main.rs    let book: Book = api::prods::Prods::new(2, 88.8);    let iphone: Phone = api::prods::Prods::new(3, 1500.5);    sum(book, iphone);		// 商品总价为1621.3// 传入两个trait的泛型声明fn sum<T: Prods, U: Prods>(p1: T, p2: U) {    println!("商品总价为{}", p1.get_price()+ p2.get_price())}
  • 一个struct 对应着多个trait共享
// api/stock.rsuse crate::model::book_model::Book;pub trait Stock{    fn get_stock(&self) -> i32;}impl Stock for Book {    fn get_stock(&self) -> i32 {        1000    }}//main.rsuse crate::api::prods::Prods;use crate::model::book_model::Book;use crate::model::iphone_model::Phone;use crate::api::stock::Stock;    // 商品库存    let book_stock: Book = api::prods::Prods::new(32, 88.0);    show_detail(book_stock)		// 商品库存为1000// 传入两个 trait使用+号声明fn show_detail<T>(p: T)    where T: Stock + Prods{    println!("商品库存为{}", p.get_stock())}
  • Trait 操作符重载 (例如 +号 : 1+1 返回的是2 i32类型 重载 例如我不想他返回结果2 而是返回结果的长度 len 就是使用到操作符重载 diy )
// api/prods.rs// +号定义的位置// std::ops::Add 基于+号的trait共享行为 实现struct impl std::ops::Add<Book> for Book {    type Output = f32;    fn add(self, rhs: Book) -> Self::Output {        self.get_price() + rhs.get_price()    }}//main.rs     let book: Book = api::prods::Prods::new(2, 88.8);    // 商品库存    let book_stock: Book = api::prods::Prods::new(32, 88.0);    sum(book, book_stock);fn sum(p1: Book, p2: Book) {    // println!("商品总价为{}", p1.get_price()+ p2.get_price())    println!("商品总价为{}", p1 + p2);}
  • 生命周期

    • 1.作用域的生命周期
    fn max (a: i32, b: i32) -> i32 {    if a> b {        a    }else {        b    }}    let a = 10;    let b = 100;    println!("{}", max(a, b))// 如果程序这样运行 就不会出现生命周期的问题  因为a,b 两个参数传参的时候相当于copy 开辟了新的内存空间存放数据  如果使用&引用 也就是指针就会出现变量的生命周期问题 // 引用生命周期 解决方法 // 这个 &' 就是生命周期的写法 标记生命周期 fn max<'a> (a: &'a i32, b: &'a i32) -> &'a i32{    if a> b {        a    }else {        b    }}    let a = 10;    let b = 100;    println!("{:?}", max(&a, &b))

& 引用的概念是借用的意思 被借走的数据如果没有被归还 是无法被修改使用的

  • 生命周期 - struct中使用引用
#[derive(Debug)]struct User<'a> {  id : &'a i32}fn main() {  let mut id = 109; // 好比是声明一个汽车   let u = User{id: &id}; // 引用& 就是车被struct借走了    id=108; // 这个时候我想开车 肯定开不了 这里就报错了   println!("{:?}", u); // 在这执行完车才归还给我  我在下面执行才能开车  }
  • 生命周期 - &str
// 之前写的&'static str 这个是贯穿全局的生命周期声明// 在输入值和输出值 生命周期相同 或者输入>输出生命周期时, 程序才允许编译fn show_name<'a> (name: &'a str) -> &'a str {  name}fn main() {    let name = "zhangsan";  show_name(name);}
  • vector 集合
数组:1.存在栈上2.数组是rust内置的数据类型3.长度固定vector 与数组正好相反 1.存在堆上2.长度可以自动扩容3.第三方库    // let vec_tags = vec!["go", "py", "rust"];		// 两种声明是相同的 写法不同     let mut vec_tags = Vec::new();    // 注: &str 是不可变类型    vec_tags.push(String::from("go"));    vec_tags.push(String::from("vue"));    vec_tags.push(String::from("js"));    for i in &mut vec_tags {        // i = i+"1";      	// 如果要对vec集合中的元素 进行修改 需要保证遍历的元素是可修改的  *是反解&的  &就是引用内存地址 加上*之后 是显示真实数据        *i += "hae";        println!("{:?}", i)    }    println!("{:?}", vec_tags);		// ["gohae", "vuehae", "jshae"]
  • 枚举

枚举理解下来 应该是用来约束数据类型的

#[derive(Debug)]enum Sex {    Male(String), // ()内可以定义多个类型 例如(String, i32)    FeMale(String)}#[derive(Debug)]struct User {    id: i32,    sex: Sex}fn check_sex(u: User) {    // 判断 u.sex 数据类型 和 Sex是否匹配    if let Sex::Male(s) = u.sex {        println!("{:?}", s)    }}// enumerate 枚举例子fn enumerate() {    println!("{:?}", Sex::Male(String::from("man")    ));    // Male("man")    println!("{:?}", User{id:1, sex:Sex::Male(String::from("man"))});    // User { id: 1, sex: Male("man") }    let u = User{id:1, sex:Sex::Male(String::from("man"))};    check_sex(u);}
  • 内置枚举 取代 自定义枚举

    #[derive(Debug)]struct User {    id: i32,    // sex: Sex    sex: Option<String>}fn check_sex(u: User) {    // 判断 u.sex 数据类型 和 Sex是否匹配    // if let Sex::Male(s) = u.sex {    if let Some(s) = u.sex {        println!("{:?}", s)        // "man"    }}// enumerate 枚举例子fn enumerate() {    let u = User{id:1, sex: Some(String::from("man")) };    check_sex(u);}
posted @ 2022-02-18 14:31 听风走了八千里 阅读(0) 评论(0) 编辑 收藏 举报
回帖
    张三

    张三 (王者 段位)

    821 积分 (2)粉丝 (41)源码

     

    温馨提示

    亦奇源码

    最新会员