有没有办法在文档注释中内联常量由货物文档呈现?

问题描述

使用“认”构造函数,记录......认值是什么会很有用。如果这是在文档中以文本方式定义并单独定义为文字或静态/常量,则两者可能会不同步:

impl Foo {
    /// Creates a [Foo] with a `bar` of 3.
    fn new() -> Foo { Foo::new_with_bar(5) }
    /// Creates a [Foo] with the provided `bar`.
    fn new_with_bar(bar: usize) -> Foo { Foo { bar } }
}

可以将文字提取到 const 或 static 并链接到那个,但是读者必须通过间接知道值是什么,而 const / static 必须被 pubcargo doc 投诉并拒绝链接

有什么方法可以替换 docstring 中的 const 值而不是链接到它?或者其他一些可以避免间接的方法?又名

const DEFAULT_BAR: usize = 5
impl Foo {
    /// Creates a [Foo] with a `bar` of ???DEFAULT_BAR???.
    fn new() -> Foo { Foo::new_with_bar(DEFAULT_BAR) }
}

应呈现为:

pub fn new() -> Foo

创建一个 Foo,其 bar 为 5。

尽管类似,How to embed a Rust macro variable into documentation? 似乎不适用于此处。 [doc] 在给定名称作为参数(甚至是 const str)时会抱怨意外标记,我不知道包装宏是否可以强制替换 const。

解决方法

在稳定版上,这并不是一个简单的解决方案,不需要为每种类型/方法使用专门的宏。因此,最简单的方法是回退到使用 const DEFAULT_BAR 并在文档中引用它(您想避免这样做。)


然而,有一个相当新的夜间功能extended_key_value_attributes(参见issue #78835PR 78837。)

除了需要最新的每晚构建之一。用于您的用例(在当前状态下)也会有点麻烦。这是因为它需要使用文字,不包括使用 const DEFAULT_BAR。或者,您可以使用扩展为 5 的宏,这是一个繁琐的解决方案。

#![feature(extended_key_value_attributes)]

struct Foo {
    bar: usize,}

macro_rules! default_bar {
    () => {
        5
    };
}

impl Foo {
    /// Creates a [Foo] with a `bar` of
    #[doc = concat!(default_bar!(),".")]
    fn new() -> Foo {
        Foo::new_with_bar(default_bar!())
    }

    /// Creates a [Foo] with the provided `bar`.
    fn new_with_bar(bar: usize) -> Foo {
        Foo { bar }
    }
}

以上工作在 rustc 1.50.0-nightly (bb1fbbf84 2020-12-22)

请注意,您必须使用 concat!,否则 default_bar 需要扩展为字符串。所以如果你不需要例如".",然后只使用一个空字符串,例如concat!("",default_bar!())

,

这适用于 Rust 1.47:

struct Foo { bar: usize }

macro_rules! impl_foo {
    ($bar_def:expr) => { impl_foo!(@ $bar_def,stringify!($bar_def)); };
    (@ $bar_def:expr,$bar_def_str:expr) => {
        impl Foo {
            /// Creates a [Foo] with a `bar` of
            #[doc = $bar_def_str]
            ///.
            fn new() -> Foo { Foo::new_with_bar($bar_def) }

            /// Creates a [Foo] with the provided `bar`.
            fn new_with_bar(bar: usize) -> Foo { Foo { bar } }
        }
    }
}

impl_foo!(3);

doc output

您可以使用 paste 来避免重定向:

use paste::paste;

struct Foo { bar: usize }

macro_rules! impl_foo {
    ($bar_def:expr) => {
        paste! {
            impl Foo {
                #[doc = "Creates a [Foo] with a `bar` of " $bar_def "."]
                fn new() -> Foo { Foo::new_with_bar($bar_def) }

                /// Creates a [Foo] with the provided `bar`.
                fn new_with_bar(bar: usize) -> Foo { Foo { bar } }
            }
        }
    }
}

impl_foo!(3);

将来,您可以使用 #![feature(extended_key_value_attributes)] 跳过宏中的重定向(或 paste! 的用法),如 vallentin's answer 中所述。

另见: