简体   繁体   English

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

[英]Is there any way to inline a const inside a doc comment (rendered by cargo doc)?

With "default" constructors, it can be useful to document what the… defaults are.使用“默认”构造函数,记录什么是……默认值是很有用的。 If this is textually defined in the doc and separately defined as a literal or a static / const, the two can get out of sync:如果这是在文档中以文本方式定义并单独定义为文字或 static / const,则两者可能会不同步:

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 } }
}

It's possible to extract the literal to a const or static and link to that, but then the reader has to go through the indirection to know what the value is, and the const / static has to be pub or cargo doc complains and refuses to link to it. It's possible to extract the literal to a const or static and link to that, but then the reader has to go through the indirection to know what the value is, and the const / static has to be pub or cargo doc complains and refuses to link给它。

Is there any way to substitute the const value in the docstring instead of linking to it?有什么方法可以替换文档字符串中的 const 值而不是链接到它? Or some other method which would avoid the indirection?或者其他一些可以避免间接的方法? aka又名

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) }
}

should be rendered as:应呈现为:

 pub fn new() -> Foo

Creates a Foo with a bar of 5.创建一个bar为 5 的Foo

Although similar, How to embed a Rust macro variable into documentation?虽然类似,如何将 Rust 宏变量嵌入到文档中? doesn't seem to apply here.似乎不适用于这里。 [doc] complains about an unexpected token when given a name as a parameter (even a const str) and I don't know if a wrapping macro can force the substitution of a const. [doc]抱怨将名称作为参数(甚至是 const str)时出现意外标记,我不知道包装宏是否可以强制替换 const。

On stable there isn't really an easy solution to doing this, without requiring a specialized macro for each type/method.在 stable 上,没有一个简单的解决方案来做到这一点,而不需要为每种类型/方法使用专门的宏。 So the easiest is to fallback to using a const DEFAULT_BAR and referencing it in the docs (which you wanted to avoid.)因此,最简单的方法是回退到使用const DEFAULT_BAR并在文档中引用它(您想避免这种情况。)


However, there's a rather new nightly feature extended_key_value_attributes (see issue #78835 and PR 78837 .)但是,有一个相当新的夜间功能extended_key_value_attributes (请参阅问题 #78835PR 78837 。)

Besides requiring one of the latest nightly builds.除了需要最新的夜间版本之一。 It will also be slightly cumbersome to use for your use case (in its current state).用于您的用例(在当前状态下)也会有点麻烦。 This is because it either requires the use of literals, which excludes using const DEFAULT_BAR .这是因为它要么需要使用文字,但不包括使用const DEFAULT_BAR Alternatively, you can use a macro which expands to 5 , which is the cumbersome solution.或者,您可以使用扩展为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 }
    }
}

The above works on rustc 1.50.0-nightly (bb1fbbf84 2020-12-22)以上适用于 rustc 1.50.0-nightly (bb1fbbf84 2020-12-22)

Note that you have to use concat!请注意,您必须使用concat! , as otherwise default_bar needs to expand into a string. ,否则default_bar需要扩展为字符串。 So if you don't need eg "."因此,如果您不需要例如"." , then just use an empty string, eg concat,("", default_bar!()) . , 然后只使用一个空字符串,例如concat,("", default_bar!())

This works in Rust 1.47:这适用于 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);

文档输出

You can use the paste to avoid the redirection:您可以使用粘贴来避免重定向:

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);

In the future, you'll be able to skip the re-direction in the macro (or the usage of paste! ) by using #![feature(extended_key_value_attributes)] , as described in vallentin's answer .将来,您将能够使用#![feature(extended_key_value_attributes)]跳过宏中的重定向(或使用paste! ),如vallentin 的回答中所述。

See also:也可以看看:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM