todo! 巨集

有時你通常想寫點程式碼幫助你想像你的專案。例如,想像一個簡單的專案,會用書籍來做一些事情。這裡是你思考寫下的想法:

struct Book {} // Okay, 首先我需要書籍的結構體.
               // 還沒有東西在那 - 之後會加入

enum BookType { // 一本書可以是精裝或平裝, 所以加入這個例舉
    HardCover,
    SoftCover,
}

fn get_book(book: &Book) -> Option<String> {} // ⚠️ get_book 應該要接受 &Book 並回傳 Option<String>

fn delete_book(book: Book) -> Result<(), String> {} // delete_book 應該要接受 Book 並回傳 Result...
                                                    // TODO: impl 區塊和寫出這些函式方法...
fn check_book_type(book_type: &BookType) { // 讓我們確定來匹配有成功
    match book_type {
        BookType::HardCover => println!("It's hardcover"),
        BookType::SoftCover => println!("It's softcover"),
    }
}

fn main() {
    let book_type = BookType::HardCover;
    check_book_type(&book_type); // Okay, 讓我們來檢查這個函式!
}

但 Rust 對 get_bookdelete_book 不滿意。它說:

error[E0308]: mismatched types
  --> src\main.rs:32:29
   |
32 | fn get_book(book: &Book) -> Option<String> {}
   |    --------                 ^^^^^^^^^^^^^^ expected enum `std::option::Option`, found `()`
   |    |
   |    implicitly returns `()` as its body has no tail or `return` expression
   |
   = note:   expected enum `std::option::Option<std::string::String>`
           found unit type `()`

error[E0308]: mismatched types
  --> src\main.rs:34:31
   |
34 | fn delete_book(book: Book) -> Result<(), String> {}
   |    -----------                ^^^^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found `()`
   |    |
   |    implicitly returns `()` as its body has no tail or `return` expression
   |
   = note:   expected enum `std::result::Result<(), std::string::String>`
           found unit type `()`

但是你這時並不關心 get_bookdelete_book。這就是你能使用 todo!() 的地方。如果你把它加到函式中,Rust 不會抱怨,而且會編譯好。

struct Book {}

fn get_book(book: &Book) -> Option<String> {
    todo!() // todo 的意思是 "我之後會做, 請安靜"
}

fn delete_book(book: Book) -> Result<(), String> {
    todo!()
}

fn main() {}

所以現在程式碼能編譯,你可以看到 check_book_type 的結果:It's hardcover

但是要小心,因為它只是能編譯--你不能使用函式。如果你呼叫裡面有 todo!() 的函式,它就會恐慌。

另外,todo!() 函式仍然需要真實的輸入和輸出型別。如果你只寫這樣,它將無法編譯:

struct Book {}

fn get_book(book: &Book) -> WorldsBestType { // ⚠️
    todo!()
}

fn main() {}

它會說:

error[E0412]: cannot find type `WorldsBestType` in this scope
  --> src\main.rs:32:29
   |
32 | fn get_book(book: &Book) -> WorldsBestType {
   |                             ^^^^^^^^^^^^^^ not found in this scope

todo!() 其實和另一個巨集一樣:unimplemented!()。程式設計師們經常使用 unimplemented!(),但打字時太長了,所以他們建立了比較短的 todo!()