RUST学习笔记
- Axum + Sqlite + minijinja + htmx + alpine.js 制胜网站组合?
vim+rust补全
YouCompleteMe 是 Vim 下的自动补全插件。自从 Vim8 与 YouCompleteMe 支持异步 IO 后,在 Vim 下的使用体验也是直线上升。
使用 YouCompleteMe 有几个先决条件,不然可能会不能正常使用:
Ycm 依赖于 Python3, 所以需要安装支持 Python3 的 Vim. 最好在 Vim 8+ 版本上使用 编译需要 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.
