<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                文檔是任何軟件項目中重要的一部分,并且它在Rust中是一級重要的。讓我們討論下Rust提供給我們編寫項目文檔的的工具。 ## 關于`rustdoc` Rust發行版中包含了一個工具,`rustdoc`,它可以生成文檔。`rustdoc`也可以在Cargo中通過`cargo doc`。 文檔可以使用兩種方法生成:從源代碼,或者從單獨的Markdown文件。 ### 文檔化源代碼 文檔化Rust項目的主要方法是在源代碼中添加注釋。為了這個目標你可以這樣使用文檔注釋: ~~~ /// Constructs a new `Rc<T>`. /// /// # Examples /// /// ~~~ /// use std::rc::Rc; /// /// let five = Rc::new(5); /// ``` pub fn new(value: T) -> Rc?{ // implementation goes here } ~~~ 這段代碼產生像[這樣](http://doc.rust-lang.org/nightly/std/rc/struct.Rc.html#method.new)的文檔。我忽略了函數的實現,而是留下了一個標準的注釋。第一個需要注意的地方是這個注釋:它使用了`///`,而不是`//`。三斜線表明這是文檔注釋。 文檔注釋用Markdown語法編寫。 Rust會記錄這些注釋,并在生成文檔時使用它們。這在文檔化像數組這樣的結構時很重要: ```rust /// The `Option` type. See [the module level documentation](../) for more. enum Option<T> { /// No value None, /// Some value `T` Some(T), } ~~~ 上面的代碼可以工作,但這個不行: ~~~ /// The `Option` type. See [the module level documentation](../) for more. enum Option<T> { None, /// No value Some(T), /// Some value `T` } ~~~ 你會得到一個錯誤: ~~~ hello.rs:4:1: 4:2 error: expected ident, found `}` hello.rs:4 } ^ ~~~ 這個[不幸的錯誤](https://github.com/rust-lang/rust/issues/22547)是有道理的:文檔注釋適用于它后面的內容,而在在最后的注釋后面沒有任何內容。 ### 編寫文檔注釋 不管怎樣,讓我們來詳細了解一下注釋的每一部分: ~~~ /// Constructs a new `Rc<T>`. ~~~ 文檔注釋的第一行應該是他功能的一個簡要總結。一句話。只包括基礎。高層次。 ~~~ /// /// Other details about constructing `Rc<T>`s, maybe describing complicated /// semantics, maybe additional options, all kinds of stuff. /// ~~~ 我們原始的例子只有一行總結,不過如果有更多東西要寫,我們在一個新的段落增加更多解釋。 ### 特殊部分 ~~~ /// # Examples ~~~ 下面,是特殊部分。它由一個標頭表明,`#`。有三種經常使用的標頭。它們不是特殊的語法,只是傳統,目前為止。 ~~~ /// # Panics ~~~ 不可恢復的函數濫用(也就是說,程序錯誤)在Rust中通常用恐慌表明,它會在最后殺死整個當前的線程。如果你的函數有這樣有意義的被識別為或者強制為恐慌的約定,記錄文檔是非常重要的。 ~~~ /// # Failures ~~~ 如果你的函數或方法返回`Result`,那么描述何種情況下它會返回`Err(E)`是件好事。這并不如`Panics`重要,因為失敗被編碼進了類型系統,不過仍舊是件好事。 ~~~ /// # Safety ~~~ 如果你的函是`unsafe`的,你應該解釋調用者應該支持哪種不可變量。 ~~~ /// # Examples /// /// ~~~ /// use std::rc::Rc; /// /// let five = Rc::new(5); /// ``` ~~~ 第三個,`Examples`。包含一個或多個使用你函數的例子,這樣你的用戶會為此感(ai)謝(shang)你的。這些例子寫在代碼塊注釋中,我們稍后會討論到,并且可以you不止一個部分: ```rust /// # Examples /// /// Simple `&str` patterns: /// /// ~~~ /// let v: Vec = "Mary had a little lamb".split(' ').collect(); /// assert_eq!(v, vec!["Mary", "had", "a", "little", "lamb"]); ///?`/// /// More complex patterns with a lambda: /// ///`?/// let v: Vec = "abc1def2ghi".split(|c: char| c.is_numeric()).collect(); /// assert_eq!(v, vec!["abc", "def", "ghi"]); /// ``` ~~~ 讓我們聊聊這些代碼塊的細節。 ### 代碼塊注釋 在注釋中編寫Rust代碼,使用三重音符: ```rust /// ~~~ /// println!("Hello, world"); /// ``` ~~~ 如果你想要一些不是Rust的代碼,你可以加上一個注釋: ```rust /// ```c /// printf("Hello, world\n"); /// ~~~ ~~~ 這回根據你選擇的語言高亮代碼。如果你只是想展示普通文本,選擇`text`。 選擇正確的注釋是很重要的,因為`rustdoc`用一種有意思的方法是用它:它可以用來實際測試你的代碼,這樣你的注釋就不會過時。如果你寫了些C代碼不過`rustdoc`會認為它是Rust代碼由于你忽略了注釋,`rustdoc`會在你生成文檔時抱怨。 ## 文檔作為測試 讓我們看看我的例子文檔的樣例: ```rust /// ~~~ /// println!("Hello, world"); /// ``` ~~~ 你會注意到你并不需要`fn main()`或者別的什么函數。`rustdoc`會自動一個`main()`包裝你的代碼,并且在正確的位置。例如: ```rust /// ~~~ /// use std::rc::Rc; /// /// let five = Rc::new(5); /// ``` ~~~ 這回作為測試: ```rust fn main() { use std::rc::Rc; let five = Rc::new(5); } ~~~ 這里是`rustdoc`用來后處理例子的完整的算法: 1. 任何`#![foo]`開頭的屬性會被完整的作為包裝箱屬性 2. 一些通用的`allow`屬性被插入,包括`unused_variables`,`unused_assignments`,`unused_mut`,`unused_attributes`和`dead_code`。小的例子經常觸發這些lint檢查 3. 如果例子并未包含`extern crate`,那么`extern crate ;`被插入 4. 最后,如果例子不包含`fn main`,剩下的文本將被包裝到`fn main() { your_code }`中 有時,這是不夠的。例如,我們已經考慮到了所有`///`開頭的代碼樣例了嗎?普通文本: ~~~ /// Some documentation. # fn foo() {} ~~~ 與它的輸出看起來有些不同: ~~~ /// Some documentation. ~~~ 是的,你猜對了:你寫的以`#`開頭的行會在輸出中被隱藏,不過會在編譯你的代碼時被使用。你可以利用這一點。在這個例子中,文檔注釋需要適用于一些函數,所以我只想向你展示文檔注釋,我需要在下面增加一些函數定義。同時,這只是用來滿足編譯器的,所以省略它會使得例子看起來更清楚。你可以使用這個技巧來詳細的解釋較長的例子,同時保留你文檔的可測試行。例如,這些代碼: ~~~ let x = 5; let y = 6; println!("{}", x + y); ~~~ 這是表現出來的解釋: 首先,我們把`x`設置為`5`: ~~~ let x = 5; ~~~ 接著,我們把`y`設置為`6`: ~~~ let y = 6; ~~~ 最后,我們打印`x`和`y`的和: ~~~ println!("{}", x + y); ~~~ 這是同樣的解釋的原始文本: ~~~ 首先,我們把`x`設置為`5`: let x = 5; # let y = 6; # println!("{}", x + y); 接著,我們把`y`設置為`6`: # let x = 5; let y = 6; # println!("{}", x + y); 最后,我們打印`x`和`y`的和: # let x = 5; # let y = 6; println!("{}", x + y); ~~~ 通過重復例子的所有部分,你可以確保你的例子仍能編譯,同時只顯示與你解釋相關的部分。 ### 文檔化宏 下面是一個宏的文檔例子: ~~~ /// Panic with a given message unless an expression evaluates to true. /// /// # Examples /// /// ~~~ /// # #[macro_use] extern crate foo; /// # fn main() { /// panic_unless!(1 + 1 == 2, “Math is broken.”); /// # } ///?`/// ///`should_panic /// # #[macro_use] extern crate foo; /// # fn main() { /// panic_unless!(true == false, “I’m broken.”); /// # } /// ``` # [macro_export] macro_rules! panic_unless { ($condition:expr, $($rest:expr),+) => ({ if ! $condition { panic!($($rest),+); } }); } ~~~ 你會注意到3個地方:我們需要添加我們自己的`extern crate`行,這樣我們可以添加`#[macro_use]`屬性。第二,我們也需要添加我們自己的`main()`。最后,用`#`機智的注釋掉這兩個代碼,這樣它們不會出現在輸出中。 ### 運行文檔測試 要運行測試,那么 ```bash $ rustdoc --test path/to/my/crate/root.rs # or $ cargo test ~~~ 對了,`cargo test`也會測試嵌入的文檔。 這還有一些注釋有利于幫助`rustdoc`在測試你的代碼時正常工作: ~~~ /// ```ignore /// fn foo() { /// ~~~ ~~~ `ignore`指令告訴Rust忽略你的代碼。這幾乎不會是你想要的,因為這是最不受支持的。相反,考慮注釋為`text`如果不是代碼的話,或者使用`#`來形成一個只顯示你關心部分的例子。 ```rust /// ```should_panic /// assert!(false); /// ~~~ ~~~ `should_panic`告訴`rustdoc`這段代碼應該正確編譯,但是作為一個測試則不能通過。 ```rust /// ```no_run /// loop { /// println!("Hello, world"); /// } /// ~~~ ~~~ `no_run`屬性會編譯你的代碼,但是不運行它。這對像如“如何開始一個網絡服務”這樣的例子很重要,你會希望確保它能夠編譯,不過它可能會無限循環的執行! ### 文檔化模塊 Rust有另一種文檔注釋,`//!`。這種注釋并不文檔化接下來的內容,而是包圍它的內容。換句話說: ```rust mod foo { //! This is documentation for the `foo` module. //! //! # Examples // ... } ~~~ 這是你會看到`//!`最常見的用法:作為模塊文檔。如果你在`foo.rs`中有一個模塊,打開它你常常會看到這些: ~~~ //! A module for using `foo`s. //! //! The `foo` module contains a lot of useful functionality blah blah blah ~~~ ### 文檔注釋風格 查看[RFC 505](https://github.com/rust-lang/rfcs/blob/master/text/0505-api-comment-conventions.md)以了解文檔風格和格式的慣例。 ### 其它文檔 所有這些行為都能在非Rust代碼文件中工作。因為注釋是用Markdown編寫的,它們通常是`.md`文件。 當你在Markdown文件中寫文檔時,你并不需要加上注釋前綴。例如: ~~~ /// # Examples /// /// ~~~ /// use std::rc::Rc; /// /// let five = Rc::new(5); /// ``` ~~~ 就是 > ~~~ > # Examples > > use std::rc::Rc; > > let five = Rc::new(5); ``` 當在一個Markdown文件中。不過這里有個竅門:Markdown文件需要有一個像這樣的標題: ~~~ % The title This is the example documentation. ~~~ `%`行需要放在文件的第一行。 ## `doc`屬性 在更底層,文檔注釋是文檔屬性的語法糖: ~~~ /// this #[doc="this"] ~~~ 跟下面這個是相同的: ~~~ //! this #![doc="/// this"] ~~~ 寫文檔時你不會經常看見這些屬性,不過當你要改變一些選項,或者寫一個宏的時候比較有用。 ## 重導出(Re-exports) `rustdoc`會將公有部分的文檔重導出: ~~~ extern crate foo; pub use foo::bar; ~~~ 這回在`foo`包裝箱中生成文檔,也會在你的包裝箱中生成文檔。它會在兩個地方使用相同的內容。 這種行文可以通過`no_inline`來阻止: ~~~ extern crate foo; #[doc(no_inline)] pub use foo::bar; ~~~ ## 控制HTML 你可以通過`#![doc]`屬性控制`rustdoc`生成的THML文檔的一些方面: ~~~ #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "http://www.rust-lang.org/favicon.ico", html_root_url = "http://doc.rust-lang.org/")]; ~~~ 這里設置了一些不同的選項,帶有一個logo,一個收藏夾,和一個根URL。 ## 通用選項 `rustdoc`也提供了一些其他命令行選項,以便進一步自定義: * `--html-in-header FILE`:在`...`部分的末尾加上`FILE`內容 * `--html-before-content FILE`:在``之后,在渲染內容之前加上`FILE`內容 * `--html-after-content FILE`:在所有渲染內容之后加上`FILE`內容 ## 注解安全 文檔注釋中的Markdown會被不加處理的放置于最終的網頁中。注意HTML文本(XSS?): ~~~ /// <script>alert(document.cookie)</script> ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看