update
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
# rust 获取东八区时间
|
||||
|
||||
|
||||
|
||||
```rust
|
||||
use time;
|
||||
|
||||
let d = time::OffsetDateTime::now_utc().to_offset(time::UtcOffset::from_hms(8, 0, 0).unwrap());
|
||||
|
||||
```
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
# rust 异步基础
|
||||
|
||||
|
||||
|
||||
### future
|
||||
|
||||
Future 生成三种方式
|
||||
|
||||
- async {}
|
||||
- fn {} -> impl Future<>
|
||||
- Impl Future for struct_future {}
|
||||
|
||||
```rust
|
||||
use std::future::Future;
|
||||
use std::pin::Pin;
|
||||
use std::task::{Context, Poll};
|
||||
|
||||
use tokio::time::{sleep, Duration, Sleep};
|
||||
|
||||
struct ReadFileFuture {
|
||||
count: u8,
|
||||
sp: Pin<Box<Sleep>>,
|
||||
}
|
||||
|
||||
impl Future for ReadFileFuture {
|
||||
type Output = String;
|
||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
match self.sp.as_mut().poll(cx) {
|
||||
Poll::Pending => {
|
||||
println!("wait ....");
|
||||
return Poll::Pending;
|
||||
}
|
||||
Poll::Ready(()) => {
|
||||
println!("finished wait");
|
||||
// return Poll::Ready("asd".to_string());
|
||||
}
|
||||
}
|
||||
if self.count < 5 {
|
||||
println!(" continue read file");
|
||||
self.count = self.count + 1;
|
||||
cx.waker().clone().wake();
|
||||
Poll::Pending
|
||||
} else {
|
||||
println!("finished to read file.");
|
||||
return Poll::Ready("asd".to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn task() -> impl Future<Output = String> {
|
||||
async {
|
||||
sleep(Duration::new(1, 0)).await;
|
||||
println!("task finished. cost 1.");
|
||||
String::from("asd")
|
||||
}
|
||||
}
|
||||
|
||||
async fn task2() {
|
||||
sleep(Duration::new(2, 0)).await;
|
||||
println!("task2 finished. cost 2s")
|
||||
}
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let d = Duration::new(4, 0);
|
||||
let mut s = sleep(d);
|
||||
let mut f1 = ReadFileFuture {
|
||||
count: 0,
|
||||
sp: Box::pin(s),
|
||||
};
|
||||
let h1 = tokio::spawn(f1);
|
||||
let h3 = tokio::spawn(task2());
|
||||
let h2 = tokio::spawn(task());
|
||||
_ = tokio::join!(h1, h2, h3);
|
||||
println!("main finished")
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
- 运行结果
|
||||
|
||||
```bash
|
||||
wait ....
|
||||
|
||||
|
||||
task finished. cost 1.
|
||||
|
||||
task2 finished. cost 2s
|
||||
|
||||
|
||||
finished wait
|
||||
continue read file
|
||||
finished wait
|
||||
continue read file
|
||||
finished wait
|
||||
continue read file
|
||||
finished wait
|
||||
continue read file
|
||||
finished wait
|
||||
continue read file
|
||||
finished wait
|
||||
finished to read file.
|
||||
main finished
|
||||
|
||||
```
|
||||
|
||||
|
||||
+199
@@ -0,0 +1,199 @@
|
||||
# Rust 宏编程(1)
|
||||
|
||||
|
||||
|
||||
rust 宏主要分为 派生宏、类函数宏、属性宏,可以非常方便的生成重复性代码。
|
||||
|
||||
终于可以能写会写代码的代码了罒ω罒。
|
||||
|
||||
### 环境准备
|
||||
|
||||
```bash
|
||||
# dtolnay 大佬提供的 宏教学库
|
||||
git clone https://github.com/dtolnay/proc-macro-workshop.git
|
||||
|
||||
## cargo expand 查看宏产生的全部代码
|
||||
rustup toolchain install nightly-x86_64-apple-darwin
|
||||
# 可先执行该指令 会提示你看着那个版本的nightly
|
||||
cargo +nightly install cargo-expand
|
||||
```
|
||||
|
||||
|
||||
|
||||
## cargo test
|
||||
|
||||
- 目录结构
|
||||
|
||||
```bash
|
||||
|
||||
cd builder/
|
||||
tree
|
||||
|
||||
.
|
||||
├── Cargo.toml
|
||||
├── src
|
||||
│ └── lib.rs # 要编写宏的文件
|
||||
└── tests
|
||||
├── 01-parse.rs
|
||||
├── 02-create-builder.rs
|
||||
├── 03-call-setters.rs
|
||||
├── 04-call-build.rs
|
||||
├── 05-method-chaining.rs
|
||||
├── 06-optional-field.rs
|
||||
├── 07-repeated-field.rs
|
||||
├── 08-unrecognized-attribute.rs
|
||||
├── 08-unrecognized-attribute.stderr
|
||||
├── 09-redefined-prelude-types.rs
|
||||
└── progress.rs # 通过取消注释来确定运行那个test文件
|
||||
```
|
||||
|
||||
- 编写宏代码
|
||||
|
||||
```rust
|
||||
use proc_macro::TokenStream;
|
||||
|
||||
#[proc_macro_derive(Builder)]
|
||||
pub fn derive(input: TokenStream) -> TokenStream {
|
||||
let _ = input;
|
||||
// 打印看看input到底是什么
|
||||
eprintln!("{:#?}", input);
|
||||
// 注释下行 并返回空的结果, 下行表示未实现该发放并进行panic
|
||||
// unimplemented!()
|
||||
TokenStream::new()
|
||||
}
|
||||
```
|
||||
|
||||
- 运行 test
|
||||
|
||||
```bash
|
||||
# builder 目录下
|
||||
cargo test
|
||||
# 可以查看 test 运行成功无报错 并打印input 结构
|
||||
TokenStream [
|
||||
Ident {
|
||||
ident: "pub",
|
||||
span: #0 bytes(990..993),
|
||||
},
|
||||
Ident {
|
||||
ident: "struct",
|
||||
span: #0 bytes(994..1000),
|
||||
},
|
||||
Ident {
|
||||
ident: "Command",
|
||||
span: #0 bytes(1001..1008),
|
||||
},
|
||||
Group {
|
||||
delimiter: Brace,
|
||||
stream: TokenStream [
|
||||
Ident {
|
||||
ident: "executable",
|
||||
span: #0 bytes(1015..1025),
|
||||
},
|
||||
....
|
||||
....
|
||||
...
|
||||
Punct {
|
||||
ch: ',',
|
||||
spacing: Alone,
|
||||
span: #0 bytes(1103..1104),
|
||||
},
|
||||
],
|
||||
span: #0 bytes(1009..1106),
|
||||
},
|
||||
]
|
||||
```
|
||||
|
||||
|
||||
|
||||
## cargo expand
|
||||
|
||||
- builder/src/lib.rs
|
||||
|
||||
```rust
|
||||
use proc_macro::TokenStream;
|
||||
|
||||
#[proc_macro_derive(Builder)]
|
||||
pub fn derive(input: TokenStream) -> TokenStream {
|
||||
eprintln!("{:#?}", input);
|
||||
// 这里直接把传入的结构返回回去
|
||||
input
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
- main.rs 根目录下
|
||||
|
||||
```rust
|
||||
use derive_builder::Builder;
|
||||
|
||||
#[derive(Builder)]
|
||||
pub struct Command {
|
||||
executable: String,
|
||||
args: Vec<String>,
|
||||
env: Vec<String>,
|
||||
current_dir: String,
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
```
|
||||
|
||||
- 查看扩展代码
|
||||
|
||||
```bash
|
||||
# 进入根目录, 运行
|
||||
cargo expand --bin workshop
|
||||
# 等同于
|
||||
cargo expand
|
||||
# 输出
|
||||
```
|
||||
|
||||
```rust
|
||||
#![feature(prelude_import)]
|
||||
#[prelude_import]
|
||||
use std::prelude::rust_2021::*;
|
||||
#[macro_use]
|
||||
extern crate std;
|
||||
use derive_builder::Builder;
|
||||
pub struct Command {
|
||||
executable: String,
|
||||
args: Vec<String>,
|
||||
env: Vec<String>,
|
||||
current_dir: String,
|
||||
}
|
||||
pub struct Command {
|
||||
executable: String,
|
||||
args: Vec<String>,
|
||||
env: Vec<String>,
|
||||
current_dir: String,
|
||||
}
|
||||
fn main() {}
|
||||
|
||||
```
|
||||
|
||||
可以看到生成了一个 多的Command结构体
|
||||
|
||||
```bash
|
||||
# 运行cargo test 可以看到报错 重复定义的Command
|
||||
|
||||
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
|
||||
error[E0428]: the name `Command` is defined multiple times
|
||||
--> tests/01-parse.rs:27:1
|
||||
|
|
||||
27 | pub struct Command {
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| `Command` redefined here
|
||||
| previous definition of the type `Command` here
|
||||
|
|
||||
= note: `Command` must be defined only once in the type namespace of this module
|
||||
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
剩下的就是根据tests/目录下每个测试文件编写符合要求的宏代码。
|
||||
|
||||
祝各位顺利~
|
||||
|
||||
rust真TM难学,其他语言能看着demo直接上手写项目, rus已经看了一周多了,还没开始写实际代码。
|
||||
@@ -0,0 +1,24 @@
|
||||
# Rust
|
||||
|
||||
#### install
|
||||
|
||||
```bash
|
||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
||||
rustup update
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## expand
|
||||
|
||||
```bash
|
||||
# just for mac
|
||||
rustup toolchain install nightly-x86_64-apple-darwin
|
||||
|
||||
cargo +nightly install cargo-expand
|
||||
|
||||
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user