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

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # 函數 > [functions.md](https://github.com/rust-lang/rust/blob/master/src/doc/book/functions.md) commit 6ba952020fbc91bad64be1ea0650bfba52e6aab4 到目前為止你應該見過一個函數,`main`函數: ~~~ fn main() { } ~~~ 這可能是最簡單的函數聲明。就像我們之前提到的,`fn`表示“這是一個函數”,后面跟著名字,一對括號因為這函數沒有參數,然后是一對大括號代表函數體。下面是一個叫`foo`的函數: ~~~ fn foo() { } ~~~ 那么有參數是什么樣的呢?下面這個函數打印一個數字: ~~~ fn print_number(x: i32) { println!("x is: {}", x); } ~~~ 下面是一個使用了`print_number`函數的完整的程序: ~~~ fn main() { print_number(5); } fn print_number(x: i32) { println!("x is: {}", x); } ~~~ 如你所見,函數參數與`let`聲明非常相似:參數名加上冒號再加上參數類型。 下面是一個完整的程序,它將兩個數相加并打印結果: ~~~ fn main() { print_sum(5, 6); } fn print_sum(x: i32, y: i32) { println!("sum is: {}", x + y); } ~~~ 在調用函數和聲明函數時,你需要用逗號分隔多個參數。 與`let`不同,你*必須*為函數參數聲明類型。下面代碼將不能工作: ~~~ fn print_sum(x, y) { println!("sum is: {}", x + y); } ~~~ 你會獲得如下錯誤: ~~~ expected one of `!`, `:`, or `@`, found `)` fn print_number(x, y) { ~~~ 這是一個有意為之的設計決定。即使像 Haskell 這樣的能夠全程序推斷的語言,注明類型也經常作為一個最佳實踐被建議。我們認為即使允許在在函數體中推斷,也要強制函數聲明參數類型。這是一個全推斷與無推斷的最佳平衡。 如果我們要一個返回值呢?下面這個函數給一個整數加一: ~~~ fn add_one(x: i32) -> i32 { x + 1 } ~~~ Rust 函數只能返回一個值,并且你需要在一個“箭頭”后面聲明類型,它是一個破折號(`-`)后跟一個大于號(`>`)。 注意這里并沒有一個分號。如果你把它加上: ~~~ fn add_one(x: i32) -> i32 { x + 1; } ~~~ 你將會得到一個錯誤: ~~~ error: not all control paths return a value fn add_one(x: i32) -> i32 { x + 1; } help: consider removing this semicolon: x + 1; ^ ~~~ 這揭露了關于 Rust 兩個有趣的地方:它是一個基于表達式的語言,并且分號與其它基于“大括號和分號”的語言不同。這兩個方面是相關的。 ### 表達式 VS 語句 Rust 主要是一個基于表達式的語言。只有兩種語句,其它的一切都是表達式。 然而這又有什么區別呢?表達式返回一個值,而語句不是。這就是為什么這里我們以“不是所有控制路徑都返回一個值”結束:`x + 1;`語句不返回一個值。Rust 中有兩種類型的語句:“聲明語句”和“表達式語句”。其余的一切是表達式。讓我們先討論下聲明語句。 在一些語言中,變量綁定可以被寫成一個表達式,不僅僅是語句。例如 Ruby: ~~~ x = y = 5 ~~~ 然而,在 Rust 中,使用`let`引入一個綁定并*不是*一個表達式。下面的代碼會產生一個編譯時錯誤: ~~~ let x = (let y = 5); // expected identifier, found keyword `let` ~~~ 編譯器告訴我們這里它期望看到表達式的開頭,而`let`只能開始一個語句,不是一個表達式。 注意賦值一個已經綁定過的變量(例如,`y = 5`)仍是一個表達式,即使它的(返回)值并不是特別有用。不像其它語言中賦值語句返回它賦的值(例如,前面例子中的`5`),在 Rust 中賦值的值是一個空的元組`()`: ~~~ let mut y = 5; let x = (y = 6); // x has the value `()`, not `6` ~~~ Rust中第二種語句是*表達式語句*。它的目的是把任何表達式變為語句。在實踐環境中,Rust 語法期望語句后跟其它語句。這意味著你用分號來分隔各個表達式。這意味著Rust看起來很像大部分其它使用分號做為語句結尾的語言,并且你會看到分號出現在幾乎每一行你看到的 Rust 代碼。 那么我們說“幾乎”的例外是神馬呢?你已經見過它了,在這些代碼中: ~~~ fn add_one(x: i32) -> i32 { x + 1 } ~~~ 我們的函數聲稱它返回一個`i32`,不過帶有一個分號,它會返回一個`()`。Rust意識到這可能不是我們想要的,并在我們之前看到的錯誤中建議我們去掉分號。 ### 提早返回(Early returns) 不過提早返回怎么破?Rust確實有這么一個關鍵字,`return`: ~~~ fn foo(x: i32) -> i32 { return x; // we never run this code! x + 1 } ~~~ 使用`return`作為函數的最后一行是可行的,不過被認為是一個糟糕的風格: ~~~ fn foo(x: i32) -> i32 { return x + 1; } ~~~ 如果你之前沒有使用過基于表達式的語言,那么前面的沒有`return`的定義可能看起來有點奇怪。不過它隨著時間的推移它會變得直觀。 ### 發散函數(Diverging functions) Rust有些特殊的語法叫“發散函數”,這些函數并不返回: ~~~ fn diverges() -> ! { panic!("This function never returns!"); } ~~~ `panic!`是一個宏,類似我們已經見過的`println!()`。與`println!()`不同的是,`panic!()`導致當前的執行線程崩潰并返回指定的信息。因為這個函數會崩潰,所以它不會返回,所以它擁有一個類型`!`,它代表“發散”。 如果你添加一個叫做`diverges()`的函數并運行,你將會得到一些像這樣的輸出: ~~~ thread ‘’ panicked at ‘This function never returns!’, hello.rs:2 ~~~ 如果你想要更多信息,你可以設定`RUST_BACKTRACE`環境變量來獲取 backtrace : ~~~ $ RUST_BACKTRACE=1 ./diverges thread '<main>' panicked at 'This function never returns!', hello.rs:2 stack backtrace: 1: 0x7f402773a829 - sys::backtrace::write::h0942de78b6c02817K8r 2: 0x7f402773d7fc - panicking::on_panic::h3f23f9d0b5f4c91bu9w 3: 0x7f402773960e - rt::unwind::begin_unwind_inner::h2844b8c5e81e79558Bw 4: 0x7f4027738893 - rt::unwind::begin_unwind::h4375279447423903650 5: 0x7f4027738809 - diverges::h2266b4c4b850236beaa 6: 0x7f40277389e5 - main::h19bb1149c2f00ecfBaa 7: 0x7f402773f514 - rt::unwind::try::try_fn::h13186883479104382231 8: 0x7f402773d1d8 - __rust_try 9: 0x7f402773f201 - rt::lang_start::ha172a3ce74bb453aK5w 10: 0x7f4027738a19 - main 11: 0x7f402694ab44 - __libc_start_main 12: 0x7f40277386c8 - <unknown> 13: 0x0 - <unknown> ~~~ `RUST_BACKTRACE`也可以用于 Cargo 的`run`命令: ~~~ $ RUST_BACKTRACE=1 cargo run Running `target/debug/diverges` thread '<main>' panicked at 'This function never returns!', hello.rs:2 stack backtrace: 1: 0x7f402773a829 - sys::backtrace::write::h0942de78b6c02817K8r 2: 0x7f402773d7fc - panicking::on_panic::h3f23f9d0b5f4c91bu9w 3: 0x7f402773960e - rt::unwind::begin_unwind_inner::h2844b8c5e81e79558Bw 4: 0x7f4027738893 - rt::unwind::begin_unwind::h4375279447423903650 5: 0x7f4027738809 - diverges::h2266b4c4b850236beaa 6: 0x7f40277389e5 - main::h19bb1149c2f00ecfBaa 7: 0x7f402773f514 - rt::unwind::try::try_fn::h13186883479104382231 8: 0x7f402773d1d8 - __rust_try 9: 0x7f402773f201 - rt::lang_start::ha172a3ce74bb453aK5w 10: 0x7f4027738a19 - main 11: 0x7f402694ab44 - __libc_start_main 12: 0x7f40277386c8 - <unknown> 13: 0x0 - <unknown> ~~~ 發散函數可以被用作任何類型: ~~~ # fn diverges() -> ! { # panic!("This function never returns!"); # } let x: i32 = diverges(); let x: String = diverges(); ~~~ ### 函數指針 我們也可以創建指向函數的變量綁定: ~~~ let f: fn(i32) -> i32; ~~~ `f`是一個指向一個獲取`i32`作為參數并返回`i32`的函數的變量綁定。例如: ~~~ fn plus_one(i: i32) -> i32 { i + 1 } // without type inference let f: fn(i32) -> i32 = plus_one; // with type inference let f = plus_one; ~~~ 你可以用`f`來調用這個函數: ~~~ # fn plus_one(i: i32) -> i32 { i + 1 } # let f = plus_one; let six = f(5); ~~~
                  <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>

                              哎呀哎呀视频在线观看