diff --git a/source/_posts/ASP.NET Core.md b/source/_posts/ASP.NET Core.md index 6eb0759..3d42f4a 100644 --- a/source/_posts/ASP.NET Core.md +++ b/source/_posts/ASP.NET Core.md @@ -888,7 +888,55 @@ public class SayHelloJob : IJob } ``` +`SayHelloJob`在执行时需要参数`UserName`,这个参数被称为JobData,`Quartz.Net`通过JobDataMap的方式传递参数。代码如下: +```C# +// 创建作业 +var jobDetail = JobBuilder.Create() + .SetJobData(new JobDataMap() { + new KeyValuePair("UserName", "Tom") + }).Build(); +``` + +通过JobBuilder的SetJobData方法,传入JobDataMap对象,JobDataMap对象中可以包含多个参数,这些参数可以映射到Job类的属性上。我们完善代码运行示例,可以看到如下: + +```shell +任务调度器已启动 +Hello Tom! +Hello Tom! +Hello Tom! +Hello Tom! +``` + +#### JobDetail + +JobDetail是Quartz.Net对作业的封装,它包含Job类型,以及Job在执行时用到的数据,还包括是否孤立存储、请求恢复作业等选项。 + +JobDetail是通过JobBuilder进行创建的。例如: + +```c# +var jobDetail = JobBuilder.Create() + .SetJobData(new JobDataMap(){ + new KeyValuePair("UserName", "Tom") + }) + .StoreDurably(true) + .RequestRecovery(true) + .WithIdentity("SayHelloJob-Tom", "DemoGroup") + .WithDescription("Say hello to Tom job") + .Build(); +``` + +**参数说明:** + +- SetJobData: 设置JobData +- StoreDurably: 孤立存储,指即使该JobDetail没有关联的Trigger,也会进行存储 +- RequestRecovery: 请求恢复,指应用崩溃后再次启动,会重新执行该作业 +- WithIdentity: 作业的描述信息 + +除此之外,`Quartz.Net`还支持两个非常有用的特性: + +- DisallowConcurrentExecution: 禁止并行执行,该特性是针对JobDetail生效的 +- PersistJobDataAfterExecution: 在执行完成后持久化JobData,该特性是针对Job类型生效的,意味着所有使用该Job的JobDetail都会在执行完成后持久化JobData。 # NLog 日志记录 diff --git a/source/_posts/Pinia.md b/source/_posts/Pinia.md new file mode 100644 index 0000000..e69de29 diff --git a/source/_posts/Rust.md b/source/_posts/Rust.md index 1ffed1d..89f0187 100644 --- a/source/_posts/Rust.md +++ b/source/_posts/Rust.md @@ -4,9 +4,9 @@ date: 2023-09-15 09:25:54 tags: --- -# Rust教程 +# Rust 教程 -## 第一个Rust程序 +## 第一个 Rust 程序 Rust语言代码文件后缀名为`.rs`,如helloworld.rs。 @@ -29,9 +29,9 @@ rustc helloworld.rs # 编译 helloworld.rs 文件 Hello World! ``` -# Rust环境搭建 +# Rust 环境搭建 -## 安装Rust编译工具 +## 安装 Rust 编译工具 Rust 编译工具从链接 [安装 Rust - Rust 程序设计语言 (rust-lang.org)](https://www.rust-lang.org/zh-CN/tools/install) 中下载的Rustup安装。下载好的Rustup在Windows 上是一个可执行程序 rustup-init.exe。(在其他平台上应该是`rustup-init.sh`)。 @@ -118,4 +118,141 @@ cargo run Cargo 还具有获取包、打包、高级构建等功能,详细使用方法参见 Cargo 命令。 -## 在 +```shell +cargo clippy # 类似ESLint,lint工具检查代码可以优化的地方 +cargo fmt # 类似go fmt,代码格式化 +cargo tree # 查看第三方库的版本和依赖关系 +cargo bench # 运行benchmark(基准测试,性能测试) +cargo udeps # (第三方)检查项目中未使用的依赖 +# 另外cargo build/run --release 使用release编译会比默认的debug编译性能提升10倍以上,但是 release 缺点是编译速度较慢,而且不会显示 panic backtrace 的具体行号 +``` + +## 在 VsCode 中配置 Rust 工程 + +Cargo 是一个不错的构建工具,如果使VsCode 与它相配合那么 VsCode 将会是一个十分便捷的开发环境。 + +在上一章中我们建立了 greeting 工程,现在我们用 VsCode 打开 greeting 文件夹**(注意不是 RustLeanrning)**。 + +打开 greeting 之后,在里面新建一个新的文件夹`.vscode` + +# Rust 输出到命令行 + +在正式学习 Rust 语言以前,我们需要先学会怎样输出一段文字到命令行,这几乎是学习每一门语言之前必备的技能,因为输出到命令行几乎是语言学习阶段程序表达结果的唯一方式。 + +在之前的 Hello, World 程序中大概已经告诉了大家输出字符串的方式,但并不全面,大家可能很疑惑为什么 println!( "Hello World") 中的 println 后面还有一个 `!` 符号,难道 Rust 函数之后都要加一个感叹号?显然并不是这样。println 不是一个函数,而是一个宏规则。这里不需要更深刻的挖掘宏规则是什么,后面的章节中会专门介绍,并不影响接下来的一段学习。 + +Rust 输出文字的方式主要有两种:`println!()` 和 `print!()`。这两个"函数"都是向命令行输出字符串的方法,区别仅在于前者会在输出的最后附加输出一个换行符。当用这两个"函数"输出信息的时候,第一个参数是格式字符串,后面是一串可变参数,对应着格式字符串中的"占位符",这一点与 C 语言中的 printf 函数很相似。但是,Rust 中格式字符串中的占位符不是 **"% + 字母"** 的形式,而是一对 **{}**。 + +`printlna.rs`文件 + +```rust +fn main() { + let a = 12; + println!("a is {}", a); +} +``` + +使用`rustc`命令编译`printlna.rs`文件: + +```rust +rustc printlna.rs # 编译 printlna.rs 文件 +``` + +编译后会生成 `printlna`可执行文件: + +```shell +./printlna # 执行 printlna +``` + +以上程序的输出结果是: + +```shell +a is 12 +``` + +如果我想把 a 输出两遍,那岂不是要写成: + +```rust +println!("a is {}, a again is {}", a, a); +``` + +其实有更好的写法: + +```rust +println!("a is {0}, a again is {0}", a); +``` + +在`{}`之间可以放一个数字,它将把之后的可变参数当做一个数组来访问,下标从0开始。 + +如果要输出 **{** 或 **}** 怎么办呢?格式字符串通过 **{{** 和 **}}** 分别转义代表 { 和 } 。但是其他常用转义字符与 C 语言里的转义字符一样,都是反斜杠开头的形式。 + +```rust +fn main() { + println!("{{}}"); +} +``` + +以上程序的输出结果是: + +```shell +{} +``` + +# Rust 基础语法 + +变量,基本类型,函数,注释和控制流,这些几乎是每种编程语言都具有的编程概念。 + +这些基础概念将存在于每个 Rust 程序中,及早学习它们将使你以最快的速度学习 Rust 的使用。 + +## 变量 + +首先必须说明,Rust 是强类型语言,但具有自动判断变量类型的能力。这很容易让人与弱类型语言产生混淆。 + +如果要声明变量,需要使用 `let` 关键字。例如: + +```rust +let a = 123; +``` + +只学习过 JavaScript 的开发者对这句话很敏感,只学习过 C 语言的开发者对这句话很不理解。 + +在这句声明语句之后,以下三行代码都是被禁止的: + +```rust +a = "abc"; +a = 4.56; +a = 456; +``` + +第一行的错误在于当声明 a 是 123 以后,a 就被确定为整型数字,不能把字符串类型的值赋给它。 + +第二行的错误在于自动转换数字精度有损失,Rust 语言不允许精度有损失的自动数据类型转换。 + +第三行的错误在于 a 不是个可变变量。 + +前两种错误很容易理解,但第三个是什么意思?难道 a 不是个变量吗? + +这就牵扯到了 Rust 语言为了高并发安全而做的设计:在语言层面尽量少的让变量的值可以改变。所以 a 的值不可变。但这不意味着 a 不是"变量"(英文中的 variable),官方文档称 a 这种变量为"不可变变量"。 + +如果我们编写的程序的一部分在假设值永远不会改变的情况下运行,而我们代码的另一部分在改变该值,那么代码的第一部分可能就不会按照设计的意图去运转。由于这种原因造成的错误很难在事后找到。这是 Rust 语言设计这种机制的原因。 + +当然,使变量变得"可变"(mutable)只需一个 `mut`关键字。 + +```rust +let mut a = 123; +a = 456; +``` + +这个程序是正确的。 + +## 常量与不可变变量的区别 + +既然不可变变量是不可变的,那不就是常量吗?为什么叫变量? + +变量和常量还是有区别的。在 Rust 中,以下程序是合法的: + +```rust +let a = 123; // 可以编译,但可能有警告,因为该变量没有被使用 +let a = 456; +``` + diff --git a/source/_posts/Vite.md b/source/_posts/Vite.md new file mode 100644 index 0000000..e69de29