目录

RUST学习笔记

vim+rust补全

YouCompleteMe 是 Vim 下的自动补全插件。自从 Vim8 与 YouCompleteMe 支持异步 IO 后,在 Vim 下的使用体验也是直线上升。

使用 YouCompleteMe 有几个先决条件,不然可能会不能正常使用:

  1. Ycm 依赖于 Python3, 所以需要安装支持 Python3 的 Vim.
  2. 最好在 Vim 8+ 版本上使用
  3. 编译需要 cmake
如果不想折腾或者不喜欢终端编程, 试试 VSCode+RA 最舒服的 Rust IDE

学习知识点

快速生成字典

普通 hashmap

  let mut trans_hashmap = HashMap::new();
  trans_hashmap.insert("key", "hello");
  trans_hashmap.insert("value", "rust");
  for (k, v) in trans_hashmap.iter() {
      println!("{} is {}", k, v);
  }
  println!("{:?}", trans_hashmap[&"key"]);

快捷 hashmap

let trans_hashmap:HashMap<char,char> = [('A','T'),('G','C')].iter().copied().collect();
for (k, v) in trans_hashmap.iter() {
    println!("{} is {}", k, v);
}

结构体和方法

Rust的结构可以全部是数据,这种类似python的字典,也可以有方法,类似python/C++的类。
struct Rectangle{
    width: u32,
    height: u32,
}
impl Rectangle{
    fn area(&self) -> u32 {
    self.width * self.height
    }
}
 
fn main(){
    let rect = &Rectangle{
        width : 30,
        height: 50,
    };
    println!("{}", rect.area()) ;
}

训练营

判断是否为素数

use std::io::stdin;
 
fn main() {
    println!("input a number: ");
    let mut input =  String::new();
    stdin().read_line(&mut input).expect("error");
    let number = input.trim().parse::<u32>().unwrap();
    let mut is_prime = true;
    for i in 2..number  {
        if number % i == 0 {
            is_prime = false;
            println!("{} is PrimeNumber( div by {} ).", input.trim(), i);
            break;
        }
    }
 
    if is_prime {
        println!("{} is not PrimeNumber.", input.trim());
    }
}

判断奇偶数

fn main(){
   let v1:Vec<i32> = (1..=30).filter(|x| x %2 == 0).collect();
   println!("{:?}", v1);
} 

猜数字

use rand::Rng;
use std::io;
use std::io::Write;
 
fn get_num() -> i32 {
    let mut input = String::new();
    print!("输入你想猜的数字(0~50): ");
    io::stdout().flush();
    io::stdin().read_line(&mut input).ok().unwrap();
    input.trim().parse::<i32>().ok().expect("Wrong number.")
}
fn main() {
    let rand_num = rand::thread_rng().gen_range(0..=50);
 
    loop {
        let guess = get_num();
        if guess < rand_num {
            println!("小了 < ");
        } else if guess > rand_num {
            println!("大了 > ");
        } else {
            println!("正确.");
            break;
        }
    }
}

阿姆斯特朗数

如果一个n位正整数等于其各位数字的n次方之和,则称该数为阿姆斯特朗数。

如1^3 + 5^3 + 3^3 = 153。

fn main() {
    for i in 100..100000 {
        let n: u32 = i.to_string().len() as u32;
        let mut num: i32 = i;
        let mut sum: i32 = 0;
 
        while num / 10 > 0 {
            let x = num % 10;
            num /= 10;
            sum += x.pow(n);
        }
        sum += num.pow(n);
        if sum == i {
            println!("{:?} 是阿姆斯特朗数. ", i);
        }
    }
}

约瑟夫生死者

30 个人在一条船上,超载,需要 15 人下船。于是人们排成一队,排队的位置即为他们的编号。报数,从 1 开始,数到 9 的人下船。如此循环,直到船上仅剩 15 人为止,问都有哪些编号的人下船了呢?

fn main(){
   let mut v1:Vec<u8> = (1..=30).collect();
   println!("{:?}", v1);
   while v1.len() > 15 {
     println!("{}号下船了。", v1[8]);
     let v2 = &v1[..8].to_vec();
     v1 = v1[9..].to_vec();
     v1.extend(v2);
   }
}
 
 
fn main(){
    let mut n:Vec<u8> = (1..31).collect();
    let mut a = 0;
    for i in (1..15){
        a = if a+8 >=n.len() {8-(n.len()-a)}  else {a+8};
        println!("第{}号船员下船了",n.remove(a));
    }
}
 
fn main(){
    let mut a:Vec<u8> = (1..31).collect();
    while a.len() > 15 {
        let mut b = a.split_off(8);
        println!("{} was down",b.remove(0));
        b.extend(a);
        a = b;
    }
}
 
fn main(){
    let mut a:Vec<u8> = (1..31).collect();
    while a.len() > 15 {
        a = [a.split_off(8), a].concat();
        println!("{} was down",a.remove(0));
    }
}

猴子吃桃

猴子第一天摘下若干个桃子,当即吃了一半,还不瘾,又多吃了一个;第二天早上又将剩下的桃子吃掉一半,又多吃了一个;以后每天早上都吃了前一天剩下的一半零一个。到第10天早上想再吃时,见只剩下一个桃子了。求第一天共摘了多少?

fn main() {
    let mut m: u32 = 1;
    for _ in (0..9).rev() {
        let n: u32 = (m + 1) * 2;
        m = n;
    }
    println!("{}", m);
}

国王发金币

国王将金币作为工资,发放给忠诚的骑士。第1天,骑士收到一枚金币;之后两天(第2天和第3天)里,每天收到两枚金币;之后三天(第4、5、6天)里,每天收到三枚金币;之后四天(第7、8、9、10天)里,每天收到四枚金币……这种工资发放模式会一直这样延续下去:求第n天,骑士一共获得了多少金币?

use std::io;
fn main() {
  println!("请输入第几天?");
  let mut input = String::new();
  let n = match io::stdin().read_line(&mut input){
    Ok(_) => {input.trim().parse().unwrap()},
    Err(_) => {return;}
  };
 
  let mut sum:Vec<i32> = Vec::new();
  for i in 1..=n{
    for _ in 0..i{
      sum.push(i);
    }
  }
  // println!("{:?}", sum);
  println!("{:?}", &sum[..n as usize].iter().sum::<i32>());
}
 
 
 
use std::io;
fn main() {
  println!("请输入第几天?");
  let mut input = String::new();
  let n = match io::stdin().read_line(&mut input){
    Ok(_) => {input.trim().parse().unwrap()},
    Err(_) => {return;}
  };
 
 let (mut sum, mut day) =  (0, 0 );
 
  for i in 1..=n{
    for _ in 0..i{
      sum += i;
      day += 1;
      if day == n{
        println!("{:?}", sum);
      }
    }
  }
}

rust版本带宽去噪

extern crate umya_spreadsheet;
extern crate rand;
extern crate round;
extern crate regex;
use round::round;
use rand::Rng;
use regex::Regex;
 
fn main() {
    let my_regex = Regex::new(r"^A").unwrap();
 
    // let new_file = std::path::Path::new("/Users/shaohy/Downloads/xxx.xlsx");
    // let mut new_book = umya_spreadsheet::new_file();
 
    let old_file = std::path::Path::new("/Users/shaohy/Downloads/原始数据.xlsx");
    let mut old_book = umya_spreadsheet::reader::xlsx::read(old_file).unwrap();
    let old_workbook = old_book.get_sheet_by_name_mut("流量数据").unwrap();
 
    let rows = old_workbook.get_highest_row(); //获取原表里的行数
    for i in 1 ..= rows { // 从第一行标题开始
        for cell in ['A','B'] { // excel的格式为字母列
            let d = format!("{}{}", cell, i);
            // println!("{}",d);
            let result = match i {
                1 => { // 标题行不做处理
                    format!("{}", old_workbook.get_cell_value(&d).get_value())
                },
                _ => {
                    if let Some(mat) = my_regex.find(&d) {
                    format!("{}", old_workbook.get_cell_value(&d).get_value())
                    }
                    else {
                        let r =  (1000. - rand::thread_rng().gen_range(0. ..= 10.)) / 1000.;
                        let r = round(r, 5);
                        let res:f64 = old_workbook.get_cell_value(&d).get_value().parse().unwrap();
                        format!("{}", round(res * r, 2))
                    }
                }
            };
        //     match i  {
        //         1 => { // 标题行不做处理
        //             let result = old_workbook.get_cell_value(&d).get_value();
        //             new_book.get_sheet_by_name_mut("Sheet1").unwrap().get_cell_mut(&d).set_value(format!("{}", result));
        //         },
        //         _ => {
        //             if let Some(mat) = my_regex.find(&d) {
        //                 let result = old_workbook.get_cell_value(&d).get_value();
        //                 new_book.get_sheet_by_name_mut("Sheet1").unwrap().get_cell_mut(&d).set_value(format!("{}", result));
        //             }
        //             else {
        //                 let r =  (1000. - rand::thread_rng().gen_range(0. ..= 10.)) / 1000.;
        //                 let r = round(r, 5);
        //                 let result:f64 = old_workbook.get_cell_value(&d).get_value().parse().unwrap();
        //                 let newres= round(result * r, 2);
        //                 new_book.get_sheet_by_name_mut("Sheet1").unwrap().get_cell_mut(&d).set_value(format!("{}", newres));
        //                 println!("{}: {}, diff is {}, after {}",i, result, r, newres);
        //             }
        //         }
        //     }
                println!("{}: {}",i, result);
                old_workbook.get_cell_mut(&d).set_value(format!("{}", result));
        }
    }
        let _ = umya_spreadsheet::writer::xlsx::write(&old_book, old_file);
}
[package]
name = "up_xlsx"
version = "0.1.0"
authors = ["shaohy"]
edition = "2018"
 
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
[dependencies]
umya-spreadsheet = "0.8"
rand = "0.8"
round = "0.1"
regex = "1.7.0"
  • 在拼接字符串时,优先使用format!

高手版本

精简版本

extern crate umya_spreadsheet;
extern crate rand;
extern crate round;
use round::round;
use rand::Rng;
 
fn main() {
    let file = std::path::Path::new("/Users/shaohy/Downloads/原始数据.xlsx");
    let mut book = umya_spreadsheet::reader::xlsx::read(file).unwrap();
    let workbook = book.get_sheet_by_name_mut("流量数据").unwrap();
 
    (2 ..= workbook.get_highest_row()).for_each(
        |i| {
            let d = format!("B{}",i);
            let r =  round( rand::thread_rng().gen_range(995. ..= 1000.) / 1000. , 5 );
            let res:f64 = workbook.get_cell_value(&d).get_value().parse().unwrap();
            println!("{}: {}",i, res);
            workbook.get_cell_mut(&d).set_value( format!("{}", round(res * r, 2)));
            }
    );
 
    let _ = umya_spreadsheet::writer::xlsx::write(&book, file);
}

常见问题

安装和卸载

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

rust unresolved import

cargo clean
cargo build

cargo build 一直出现 Blocking waiting for file lock on package cache

如果确定没有多个程序占用,可以删除
rm -rf ~/.cargo/.package-cache
然后再执行 

crate太慢/加速

vi ~/.cargo/config
 
[source.crates-io]
registry = "https://github.com/rust-lang/crates.io-index"
 
# 替换成你偏好的镜像源
replace-with = 'sjtu'
 
# 清华大学
[source.tuna]
registry = "https://mirrors.tuna.tsinghua.edu.cn/git/crates.io-index.git"
 
# 中国科学技术大学
[source.ustc]
registry = "git://mirrors.ustc.edu.cn/crates.io-index"
 
# 上海交通大学
[source.sjtu]
registry = "https://mirrors.sjtug.sjtu.edu.cn/git/crates.io-index"
 
# rustcc社区
[source.rustcc]
registry = "git://crates.rustcc.cn/crates.io-index"
 
[net]
git-fetch-with-cli=true
 
[http]
check-revoke = false

学习视频重点

P20~P24重点

Rust前端和后端框架

Yew前端框架

Demo安装记录

# Yew官方推荐Trunk来构建、打包成前端Web应用
cargo install trunk
 
# 将 wasm32-unknown-unknown 添加为编译目标
rustup target add wasm32-unknown-unknown
 
cargo new yew-app
cd yew-app
 
cargo run

简单的演示代码

use yew::prelude::*;
 
struct Video {
    id: usize,
    title: String,
    speaker: String,
    url: String,
}
 
#[function_component(App)]
fn app() -> Html {
    let videos = vec![
        Video {
            id: 1,
            title: "Building and breaking things".to_string(),
            speaker: "John Doe".to_string(),
            url: "https://youtu.be/PsaFVLr8t4E".to_string(),
        },
        Video {
            id: 2,
            title: "The development process".to_string(),
            speaker: "Jane Smith".to_string(),
            url: "https://youtu.be/PsaFVLr8t4E".to_string(),
        },
        Video {
            id: 3,
            title: "The Web 7.0".to_string(),
            speaker: "Matt Miller".to_string(),
            url: "https://youtu.be/PsaFVLr8t4E".to_string(),
        },
        Video {
            id: 4,
            title: "Mouseless development".to_string(),
            speaker: "Tom Jerry".to_string(),
            url: "https://youtu.be/PsaFVLr8t4E".to_string(),
        },
    ];
 
    let videos = videos.iter().map(|video| html! {
        <p key={video.id}>{format!("{}: {}", video.speaker, video.title)}</p>
    }).collect::<Html>();
 
    html! {
        <>
        <h1>{ "RustConf Explorer" }</h1>
        <div>
            <h3>{ "Videos to watch" }</h3>
           { videos }
        </div>
        </>
    }
}
 
fn main() {
    // println!("Hello, world!");
    yew::Renderer::<App>::new().render();
}
需要一个空白的index.html ,运行
trunk serve --open

Ntex后端框架

Ntex runs on Rust 1.75 or later and it works with stable releases.