diff --git a/2023/12/04/rust/index.html b/2023/12/04/rust/index.html index d51e824..bf32edc 100644 --- a/2023/12/04/rust/index.html +++ b/2023/12/04/rust/index.html @@ -202,6 +202,8 @@

Rust

  • 集合
  • 生命周期
  • 错误处理
  • +
  • 包和模块
  • +
  • 注释和文档
  • diff --git a/SpringCloud/bus/index.html b/SpringCloud/bus/index.html index c1341ce..4613ac0 100644 --- a/SpringCloud/bus/index.html +++ b/SpringCloud/bus/index.html @@ -194,7 +194,7 @@

    服务总线

    - 服务总线 + 服务总线 diff --git a/SpringCloud/bus/springcloud-bus.html b/SpringCloud/bus/springcloud-bus.html index e89c022..3c25111 100644 --- a/SpringCloud/bus/springcloud-bus.html +++ b/SpringCloud/bus/springcloud-bus.html @@ -194,7 +194,7 @@

    SpringCloud Bus

    - 服务总线 + 服务总线 diff --git a/SpringCloud/config-center/index.html b/SpringCloud/config-center/index.html index 59669d3..3c8ad8c 100644 --- a/SpringCloud/config-center/index.html +++ b/SpringCloud/config-center/index.html @@ -194,7 +194,7 @@

    配置中心

    - 配置中心 + 配置中心 diff --git a/SpringCloud/config-center/springcloud-config.html b/SpringCloud/config-center/springcloud-config.html index 31db335..f557cfd 100644 --- a/SpringCloud/config-center/springcloud-config.html +++ b/SpringCloud/config-center/springcloud-config.html @@ -194,7 +194,7 @@

    SpringCloud Config

    - 配置中心 + 配置中心 diff --git a/SpringCloud/gateway/springcloud-gateway.html b/SpringCloud/gateway/springcloud-gateway.html index 2985c3c..a32795b 100644 --- a/SpringCloud/gateway/springcloud-gateway.html +++ b/SpringCloud/gateway/springcloud-gateway.html @@ -194,7 +194,7 @@

    SpringCloud Gateway

    - 服务网关 + 服务网关 diff --git a/SpringCloud/service-degradation/hystrix.html b/SpringCloud/service-degradation/hystrix.html index e07df57..838a5df 100644 --- a/SpringCloud/service-degradation/hystrix.html +++ b/SpringCloud/service-degradation/hystrix.html @@ -194,7 +194,7 @@

    Hystrix

    - 服务降级 + 服务降级 diff --git a/SpringCloud/service-degradation/sentinel.html b/SpringCloud/service-degradation/sentinel.html index b127031..33f3fef 100644 --- a/SpringCloud/service-degradation/sentinel.html +++ b/SpringCloud/service-degradation/sentinel.html @@ -194,7 +194,7 @@

    Sentinel

    - 服务降级 + 服务降级 diff --git a/SpringCloud/service-invoke/open-feign.html b/SpringCloud/service-invoke/open-feign.html index 6bd7acd..c660354 100644 --- a/SpringCloud/service-invoke/open-feign.html +++ b/SpringCloud/service-invoke/open-feign.html @@ -194,7 +194,7 @@

    OpenFeign

    - 服务调用 + 服务调用 diff --git a/SpringCloud/service-invoke/spring-cloud-square.html b/SpringCloud/service-invoke/spring-cloud-square.html index f29c379..4084740 100644 --- a/SpringCloud/service-invoke/spring-cloud-square.html +++ b/SpringCloud/service-invoke/spring-cloud-square.html @@ -194,7 +194,7 @@

    Spring Cloud Square

    - 服务调用 + 服务调用 diff --git a/index.html b/index.html index f0c1d75..5ff3b4e 100644 --- a/index.html +++ b/index.html @@ -627,6 +627,8 @@

    Rust

  • 集合
  • 生命周期
  • 错误处理
  • +
  • 包和模块
  • +
  • 注释和文档
  • diff --git a/java-source/concurrent-hashmap.html b/java-source/concurrent-hashmap.html index e11a6b1..dec1c96 100644 --- a/java-source/concurrent-hashmap.html +++ b/java-source/concurrent-hashmap.html @@ -194,7 +194,7 @@

    ConcurrentHashMap源码

    - Java + Java diff --git a/java-source/conditional.html b/java-source/conditional.html index f16fe7e..e3d475f 100644 --- a/java-source/conditional.html +++ b/java-source/conditional.html @@ -194,7 +194,7 @@

    @Conditional注解

    - SpringBoot + SpringBoot diff --git a/java-source/hash-map.html b/java-source/hash-map.html index 28eee3b..859e52c 100644 --- a/java-source/hash-map.html +++ b/java-source/hash-map.html @@ -194,7 +194,7 @@

    HashMap源码

    - Java + Java diff --git a/java-source/linked-transfer-queue.html b/java-source/linked-transfer-queue.html index 8e61726..c5d8a84 100644 --- a/java-source/linked-transfer-queue.html +++ b/java-source/linked-transfer-queue.html @@ -174,7 +174,7 @@

    - 2024/3/25 + 2024/3/29 diff --git a/java-source/named-context-factory.html b/java-source/named-context-factory.html index b26c1bb..b781e7c 100644 --- a/java-source/named-context-factory.html +++ b/java-source/named-context-factory.html @@ -194,7 +194,7 @@

    NamedContextFactory使用与源码解读

    - SpringCloud + SpringCloud diff --git a/java-source/springcloud-sentinel-source.html b/java-source/springcloud-sentinel-source.html index 3e7ade4..8a0f1f4 100644 --- a/java-source/springcloud-sentinel-source.html +++ b/java-source/springcloud-sentinel-source.html @@ -194,7 +194,7 @@

    SpringCloud Sentinel 排队等待和Warm Up限流源码

    - SpringCloud + SpringCloud diff --git a/java-source/synchronized.html b/java-source/synchronized.html index 435a476..31a1f31 100644 --- a/java-source/synchronized.html +++ b/java-source/synchronized.html @@ -194,7 +194,7 @@

    synchronized与锁升级

    - JVM + JVM diff --git a/java-source/threadpool.html b/java-source/threadpool.html index c658bbc..d6f7a6f 100644 --- a/java-source/threadpool.html +++ b/java-source/threadpool.html @@ -194,7 +194,7 @@

    线程池

    - Java + Java diff --git a/rust/packages.html b/rust/packages.html index 823f99d..92328cf 100644 --- a/rust/packages.html +++ b/rust/packages.html @@ -178,7 +178,7 @@

    包和模块

    - + @@ -191,7 +191,10 @@

    包和模块

    -

    Package 和 Crate

    +
    +

    这一章很抽象,一定要自己多写,不然很难理解。

    +
    +

    Package 和 Crate

    crate!我第一眼看成了 create…

    crate(箱) 是 Rust 的最小编译单元,一个 package 中包含一个活多个 cratecrate可以是一个二进制项目,或者一个库。

    @@ -271,6 +274,138 @@

    使用 use 导入模块

    可以使用 use 关键字来简化导入:

    +
    // hosting.rs
    +use crate::product::provider;
    +
    +pub fn add_to_waitlist() {}
    +
    +pub fn seat_at_table() -> String {
    +    provider::give()
    +}
    +
    +

    use 也可以直接导入函数:

    +
    // hosting.rs
    +use crate::product::provider::give;
    +
    +pub fn add_to_waitlist() {}
    +
    +pub fn seat_at_table() -> String {
    +    give()
    +}
    +
    +

    限制可见性语法

      +
    • pub 意味着可见性无任何限制
    • +
    • pub(crate) 表示在当前包可见
    • +
    • pub(self) 在当前模块可见
    • +
    • pub(super) 在父模块可见
    • +
    • pub(in ) 表示在某个路径代表的模块中可见,其中 path 必须是父模块或者祖先模块
    • +
    +
    // 一个名为 `my_mod` 的模块
    +mod my_mod {
    +    // 模块中的项默认具有私有的可见性
    +    fn private_function() {
    +        println!("called `my_mod::private_function()`");
    +    }
    +
    +    // 使用 `pub` 修饰语来改变默认可见性。
    +    pub fn function() {
    +        println!("called `my_mod::function()`");
    +    }
    +
    +    // 在同一模块中,项可以访问其它项,即使它是私有的。
    +    pub fn indirect_access() {
    +        print!("called `my_mod::indirect_access()`, that\n> ");
    +        private_function();
    +    }
    +
    +    // 模块也可以嵌套
    +    pub mod nested {
    +        pub fn function() {
    +            println!("called `my_mod::nested::function()`");
    +        }
    +
    +        #[allow(dead_code)]
    +        fn private_function() {
    +            println!("called `my_mod::nested::private_function()`");
    +        }
    +
    +        // 使用 `pub(in path)` 语法定义的函数只在给定的路径中可见。
    +        // `path` 必须是父模块(parent module)或祖先模块(ancestor module)
    +        pub(in crate::my_mod) fn public_function_in_my_mod() {
    +            print!("called `my_mod::nested::public_function_in_my_mod()`, that\n > ");
    +            public_function_in_nested()
    +        }
    +
    +        // 使用 `pub(self)` 语法定义的函数则只在当前模块中可见。
    +        pub(self) fn public_function_in_nested() {
    +            println!("called `my_mod::nested::public_function_in_nested");
    +        }
    +
    +        // 使用 `pub(super)` 语法定义的函数只在父模块中可见。
    +        pub(super) fn public_function_in_super_mod() {
    +            println!("called my_mod::nested::public_function_in_super_mod");
    +        }
    +    }
    +
    +    pub fn call_public_function_in_my_mod() {
    +        print!("called `my_mod::call_public_funcion_in_my_mod()`, that\n> ");
    +        nested::public_function_in_my_mod();
    +        print!("> ");
    +        nested::public_function_in_super_mod();
    +    }
    +
    +    // `pub(crate)` 使得函数只在当前包中可见
    +    pub(crate) fn public_function_in_crate() {
    +        println!("called `my_mod::public_function_in_crate()");
    +    }
    +
    +    // 嵌套模块的可见性遵循相同的规则
    +    mod private_nested {
    +        #[allow(dead_code)]
    +        pub fn function() {
    +            println!("called `my_mod::private_nested::function()`");
    +        }
    +    }
    +}
    +
    +fn function() {
    +    println!("called `function()`");
    +}
    +
    +fn main() {
    +    // 模块机制消除了相同名字的项之间的歧义。
    +    function();
    +    my_mod::function();
    +
    +    // 公有项,包括嵌套模块内的,都可以在父模块外部访问。
    +    my_mod::indirect_access();
    +    my_mod::nested::function();
    +    my_mod::call_public_function_in_my_mod();
    +
    +    // pub(crate) 项可以在同一个 crate 中的任何地方访问
    +    my_mod::public_function_in_crate();
    +
    +    // pub(in path) 项只能在指定的模块中访问
    +    // 报错!函数 `public_function_in_my_mod` 是私有的
    +    //my_mod::nested::public_function_in_my_mod();
    +    // 试一试 ^ 取消该行的注释
    +
    +    // 模块的私有项不能直接访问,即便它是嵌套在公有模块内部的
    +
    +    // 报错!`private_function` 是私有的
    +    //my_mod::private_function();
    +    // 试一试 ^ 取消此行注释
    +
    +    // 报错!`private_function` 是私有的
    +    //my_mod::nested::private_function();
    +    // 试一试 ^ 取消此行的注释
    +
    +    // 报错! `private_nested` 是私有的
    +    //my_mod::private_nested::function();
    +    // 试一试 ^ 取消此行的注释
    +}
    +
    diff --git a/rust/rust-doc.html b/rust/rust-doc.html new file mode 100644 index 0000000..ff930ee --- /dev/null +++ b/rust/rust-doc.html @@ -0,0 +1,459 @@ + + + + + + 注释和文档 | IceOfSummerの博客 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    +
    +

    LOADING

    +

    加载过慢请开启缓存 浏览器默认开启

    + +
    +
    +
    + +
    + + +
    +
    +

    注释和文档

    +
    +
    + + + + + 2024/3/28 + + + + + + + + Rust + + + + +
    + + +
    +

    在 Rust 中,注释分为三类:

    +
      +
    • 代码注释,用于说明某一块代码的功能,读者往往是同一个项目的协作开发者
    • +
    • 文档注释,支持 Markdown,对项目描述、公共 API 等用户关心的功能进行介绍,同时还能提供示例代码,目标读者往往是想要了解你项目的人
    • +
    • 包和模块注释,严格来说这也是文档注释中的一种,它主要用于说明当前包和模块的功能,方便用户迅速了解一个项目
    • +
    +

    代码注释

    行注释//:

    +
    fn main() {
    +    // 我是Sun...
    +    // face
    +    let name = "sunface";
    +    let age = 18; // 今年好像是18岁
    +}
    +
    +

    当行数过多时,可以使用块注释/* ... */:

    +
    fn main() {
    +    /*
    +        我
    +        是
    +        S
    +        u
    +        n
    +        ... 哎,好长!
    +    */
    +    let name = "sunface";
    +    let age = "???"; // 今年其实。。。挺大了
    +}
    +
    +

    文档注释

    Rust 提供了 cargo doc 的命令,可以用于把这些文档注释转换成 HTML 网页文件,最终展示给用户浏览。

    +

    文档行注释 ///

    /// `add_one` 将指定值加1
    +///
    +/// # Examples
    +///
    +/// ```
    +/// let arg = 5;
    +/// let answer = my_crate::add_one(arg);
    +///
    +/// assert_eq!(6, answer);
    +/// ```
    +pub fn add_one(x: i32) -> i32 {
    +    x + 1
    +}
    +
    +

    以上代码有几点需要注意:

    +
      +
    • 文档注释需要位于 lib 类型的包中,例如 src/lib.rs 中
    • +
    • 文档注释可以使用 markdown语法!例如 # Examples 的标题,以及代码块高亮
    • +
    • 被注释的对象需要使用 pub 对外可见,记住:文档注释是给用户看的,内部实现细节不应该被暴露出去
    • +
    +

    文档块注释 /** .. */

    与代码注释一样,文档也有块注释,当注释内容多时,使用块注释可以减少 /// 的使用:

    +
    /** `add_two` 将指定值加2
    +
    +
    +

    let arg = 5;
    let answer = my_crate::add_two(arg);

    +

    assert_eq!(7, answer);

    +
    */
    +pub fn add_two(x: i32) -> i32 {
    +    x + 2
    +}
    +
    +

    查看文档

    编写完文档后,运行 cargo doc 可以直接生成 HTML 文件,默认在 target/doc 目录下。

    +

    也可以直接使用 cargo doc --open 命令,可以在文档生成后在浏览器中自动打开。

    +
    ///
    +/// # 你好
    +///
    +/// 我是rust文档
    +///
    +/// #test
    +/// ```rust
    +/// hello_rust()
    +/// ```
    +pub fn hello_rust() {
    +    println!("hello rust!");
    +}
    +
    +

    rust-doc

    +

    除了 #example 外,还有一些常用的,你可以在项目中酌情使用:

    +
      +
    • Panics:函数可能会出现的异常状况,这样调用函数的人就可以提前规避
    • +
    • Errors:描述可能出现的错误及什么情况会导致错误,有助于调用者针对不同的错误采取不同的处理方式
    • +
    • Safety:如果函数使用 unsafe 代码,那么调用者就需要注意一些使用条件,以确保 unsafe 代码块的正常工作
    • +
    +

    仅仅是一种代码风格,没有强制要求。

    +

    包和模块级别的注释

    除了函数、结构体等 Rust 项的注释,还可以给包和模块添加注释,需要注意的是,这些注释要添加到包、模块的最上方

    +

    包级别的注释也分为两种:行注释 //! 和块注释 /*! ... */

    +
    /*! lib包是world_hello二进制包的依赖包,
    + 里面包含了compute等有用模块 */
    +
    +pub mod compute;
    +
    +

    文档测试 (Doc Test)

    在 Rust 中,测试用例可以直接写在文档中!

    +
    /// `add_one` 将指定值加1
    +///
    +/// # Examples11
    +///
    +/// ```
    +/// let arg = 5;
    +/// let answer = world_hello::compute::add_one(arg);
    +///
    +/// assert_eq!(6, answer);
    +/// ```
    +pub fn add_one(x: i32) -> i32 {
    +    x + 1
    +}
    +
    +

    以上的注释不仅仅是文档,还可以作为单元测试的用例运行,使用 cargo test 运行测试:

    +
    Doc-tests world_hello
    +
    +running 2 tests
    +test src/compute.rs - compute::add_one (line 8) ... ok
    +test src/compute.rs - compute::add_two (line 22) ... ok
    +
    +test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.00s
    +
    +

    可以看到,文档中的测试用例被完美运行,而且输出中也明确提示了 Doc-tests world_hello,意味着这些测试的名字叫 Doc test 文档测试。

    +

    期望 panic 的测试用例

    若某个测试用例期望调用能够 panic,则需要加上should_panic来控制:

    +
    /// # Panics
    +///
    +/// The function panics if the second argument is zero.
    +///
    +/// ```rust,should_panic
    +/// // panics on division by zero
    +/// world_hello::compute::div(10, 0);
    +/// ```
    +pub fn div(a: i32, b: i32) -> i32 {
    +    if b == 0 {
    +        panic!("Divide-by-zero error");
    +    }
    +
    +    a / b
    +}
    +
    +

    保留测试,隐藏文档

    在某些时候,我们希望保留文档测试的功能,但是又要将某些测试用例的内容从文档中隐藏起来(例如只关心输入,不关心细节和输出):

    +
    /// ```
    +/// # // 使用#开头的行会在文档中被隐藏起来,但是依然会在文档测试中运行
    +/// # fn try_main() -> Result<(), String> {
    +/// let res = world_hello::compute::try_div(10, 0)?;
    +/// # Ok(()) // returning from try_main
    +/// # }
    +/// # fn main() {
    +/// #    try_main().unwrap();
    +/// #
    +/// # }
    +/// ```
    +pub fn try_div(a: i32, b: i32) -> Result<i32, String> {
    +    if b == 0 {
    +        Err(String::from("Divide-by-zero"))
    +    } else {
    +        Ok(a / b)
    +    }
    +}
    +
    +

    用户在文档中只能看到相关的输入,无法看到其它的细节:
    input-only!

    +

    代码跳转

    Rust 在文档注释中还提供了一个非常强大的功能,那就是可以实现对外部项的链接。

    +

    跳转到标准库:

    +
    /// `add_one` 返回一个[`Option`]类型
    +pub fn add_one(x: i32) -> Option<i32> {
    +    Some(x + 1)
    +}
    +
    +

    此处的 [`Option`] 就是一个链接,指向了标准库中的 Option 枚举类型。

    +

    也可以使用完整路径跳转到任意项:

    +
    // lib.rs
    +pub mod a {
    +    /// `add_one` 返回一个[`Option`]类型
    +    /// 跳转到[`crate::MySpecialFormatter`]
    +    pub fn add_one(x: i32) -> Option<i32> {
    +        Some(x + 1)
    +    }
    +}
    +
    +pub struct MySpecialFormatter;
    +
    +

    同名项的跳转

    如果遇到同名项,可以使用标示类型的方式进行跳转:

    +
    /// 跳转到结构体  [`Foo`](struct@Foo)
    +pub struct Bar;
    +
    +/// 跳转到同名函数 [`Foo`](fn@Foo)
    +pub struct Foo {}
    +
    +/// 跳转到同名宏 [`foo!`]
    +pub fn Foo() {}
    +
    +#[macro_export]
    +macro_rules! foo {
    +  () => {}
    +}
    +
    +

    文档搜索别名

    Rust 文档支持搜索功能,可以给自己的结构添加别名来方便搜索:

    +
    #[doc(alias = "x")]
    +#[doc(alias = "big")]
    +pub struct BigX;
    +
    +#[doc(alias("y", "big"))]
    +pub struct BigY;
    +
    + +
    + + + + +
    +
    +
    + + + + +
    + + + +
    +
    + + +
    + +
    +
    + +
    + + + + + + + + + + + +