<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          「每周譯Go」如何在 Go 中定義并調(diào)用函數(shù)

          共 8626字,需瀏覽 18分鐘

           ·

          2022-12-26 09:28

          目錄

          1. 在 Go 中導(dǎo)入包
          2. 理解 Go 中包的可見性
          3. 如何在 Go 中編寫條件語(yǔ)句
          4. 如何在 Go 中編寫 Switch 語(yǔ)句
          5. 如何在 Go 中構(gòu)造 for 循環(huán)
          6. 在循環(huán)中使用 Break 和 Continue
          7. 如何在 Go 中定義并調(diào)用函數(shù)
          8. 如何在 Go 中使用可變參數(shù)函數(shù)
          9. 了解 Go 中的 defer
          10. 了解 Go 中的 init
          11. 用構(gòu)建標(biāo)簽定制 Go 二進(jìn)制文件
          12. 了解 Go 中的指針
          13. 在 Go 中定義結(jié)構(gòu)體
          14. 在 Go 中定義方法
          15. 如何構(gòu)建和安裝 Go 程序
          16. 如何在 Go 中使用結(jié)構(gòu)體標(biāo)簽
          17. 如何在 Go 使用 interface
          18. 在不同的操作系統(tǒng)和架構(gòu)編譯 Go 應(yīng)用
          19. 用 ldflags 設(shè)置 Go 應(yīng)用程序的版本信息
          20. 在 Go 里面如何使用 Flag 包


          介紹

          _函數(shù)_是一段一旦定義,就可以重用的代碼。函數(shù)的作用在于可以通過(guò)將在整個(gè)程序中多次使用的代碼分解為更小、更可理解的任務(wù),從而使您的代碼更易于理解。

          Go 附帶了強(qiáng)大的標(biāo)準(zhǔn)庫(kù),其中包含許多預(yù)定義的函數(shù)。您可能已經(jīng)熟悉了fmt[1] 包:

          • fmt.Println() 會(huì)將對(duì)象打印到標(biāo)準(zhǔn)輸出(最可能在您的終端)。
          • fmt.Printf() 允許您將輸出格式化打印。

          函數(shù)名稱包括括號(hào),并且可能包括參數(shù)。

          在本教程中,我們將介紹如何定義您自己的函數(shù)以在您的項(xiàng)目中使用。

          定義一個(gè)函數(shù)

          讓我們從經(jīng)典的 “Hello, World!”程序(點(diǎn)擊查看往期文章) 開始理解函數(shù)。

          我們將在一個(gè)文本編輯器中創(chuàng)建一個(gè)新的文本文件,然后調(diào)用程序 hello.go。然后,我們將在里面定義函數(shù)。

          Go 中使用 func 關(guān)鍵字來(lái)定義函數(shù)。然后是您選擇的名稱和一組括號(hào),其中包含函數(shù)將采用的任何參數(shù)(它們可以為空)。函數(shù)代碼行用大括號(hào) {} 括起來(lái)。

          在這種情況下,我們將定義一個(gè)名為 hello() 的函數(shù):

                
                func hello() {}

          這就是用于創(chuàng)建函數(shù)的初始語(yǔ)句。

          基于此,我們將添加第二行來(lái)提供函數(shù)功能的說(shuō)明。我們將打印 Hello, World! 到控制臺(tái):

                
                func hello() {
           fmt.Println("Hello, World!")
          }

          現(xiàn)在我們的函數(shù)已經(jīng)完全定義好了,但是如果我們此時(shí)運(yùn)行程序,什么都不會(huì)發(fā)生,因?yàn)槲覀儧](méi)有調(diào)用函數(shù)。

          因此,在我們的 main() 代碼塊中,來(lái)調(diào)用 hello() 函數(shù):

                
                package main

          import "fmt"

          func main() {
           hello()
          }

          func hello() {
           fmt.Println("Hello, World!")
          }

          現(xiàn)在,讓我們運(yùn)行程序:

                
                
                  $
                   go run hello.go
                  

          您將收到以下輸出:

                
                Output
          Hello, World!

          請(qǐng)注意,我們還引入了一個(gè)名為 main() 的函數(shù)。main() 函數(shù)是一個(gè)特殊的函數(shù),它告訴編譯器程序應(yīng)該從這里開始。對(duì)于 可執(zhí)行 的任何程序(可以從命令行運(yùn)行的程序),都需要一個(gè) main() 函數(shù)。main() 函數(shù)只能在 main() 中出現(xiàn)一次,并且不接收和返回任何參數(shù)。在任何 Go 程序中程序執(zhí)行[2] 都是這樣的。根據(jù)以下示例:

                
                package main

          import "fmt"

          func main() {
           fmt.Println("this is the main section of the program")
          }

          函數(shù)可以比我們定義的 hello() 函數(shù)更復(fù)雜。我們可以在函數(shù)中使用 for循環(huán)(點(diǎn)擊查看往期文章)條件語(yǔ)句(點(diǎn)擊查看往期文章) 等。

          例如,以下函數(shù)使用條件語(yǔ)句檢查 name 變量的輸入是否包含元音,并使用 for 循環(huán)遍歷 name 字符串中的字母。

                
                package main

          import (
           "fmt"
           "strings"
          )

          func main() {
           names()
          }

          func names() {
           fmt.Println("Enter your name:")

           var name string
           fmt.Scanln(&name)
           // Check whether name has a vowel
           for _, v := range strings.ToLower(name) {
            if v == 'a' || v == 'e' || v == 'i' || v == 'o' || v == 'u' {
             fmt.Println("Your name contains a vowel.")
             return
            }
           }
           fmt.Println("Your name does not contain a vowel.")
          }

          我們?cè)谶@里定義的 names() 函數(shù)設(shè)置一個(gè)帶有輸入的變量 name,然后在一個(gè) for 循環(huán)中設(shè)置一個(gè)條件語(yǔ)句。這顯示了如何在函數(shù)定義中組織代碼。但是,根據(jù)我們對(duì)程序的意圖以及我們對(duì)代碼的安排,我們可能希望將條件語(yǔ)句和循環(huán)定義為兩個(gè)獨(dú)立的函數(shù)。

          在程序中定義函數(shù)可使我們的代碼更模塊化和可重用,這樣我們就可以調(diào)用相同的函數(shù)而無(wú)需重寫它們。

          使用參數(shù)

          到目前為止,我們已經(jīng)研究了帶有空括號(hào)且不帶參數(shù)的函數(shù),但我們是可以在函數(shù)定義中的括號(hào)內(nèi)定義參數(shù)的。

          參數(shù) 是函數(shù)定義中的命名實(shí)體,指定函數(shù)可以接受的參數(shù)。在 Go 中,您必須為每個(gè)參數(shù)指定 數(shù)據(jù)類型(點(diǎn)擊查看往期文章) 

          讓我們創(chuàng)建一個(gè)將單詞重復(fù)指定次數(shù)的程序。它將接受一個(gè) string 類型的 word 參數(shù)和一個(gè)用于重復(fù)單詞的次數(shù)的 int 類型參數(shù) reps

                
                package main

          import "fmt"

          func main() {
           repeat("Sammy"5)
          }

          func repeat(word string, reps int) {
           for i := 0; i < reps; i++ {
            fmt.Print(word)
           }
          }

          我們分別為 word 參數(shù)和 reps 參數(shù)傳遞了Sammy5 值。這些值按照給定的順序與每個(gè)參數(shù)相對(duì)應(yīng)。repeat 函數(shù)有一個(gè) for 循環(huán),將循環(huán)參數(shù) reps 指定的次數(shù)。對(duì)于每次循環(huán),都會(huì)打印參數(shù) word  的值。

          這是程序的輸出:

                
                Output
          SammySammySammySammySammy

          如果你有一組參數(shù)都是相同的值,你可以不用每次指定類型。讓我們創(chuàng)建一個(gè)小程序,它接受都是 int 值的參數(shù) x,  y, 和 z 這些。我們將創(chuàng)建一個(gè)函數(shù),函數(shù)將打印他們的總和。下面我們將調(diào)用該函數(shù)并將數(shù)字傳遞給該函數(shù)。

                
                package main

          import "fmt"

          func main() {
           addNumbers(123)
          }

          func addNumbers(x, y, z int) {
           a := x + y
           b := x + z
           c := y + z
           fmt.Println(a, b, c)
          }

          當(dāng)我們創(chuàng)建 addNumbers 的函數(shù)簽名時(shí),我們不需要每次都指定類型,而只需要在最后指定。

          我們將數(shù)字 1 傳入?yún)?shù) x2 傳入?yún)?shù) y3 傳入?yún)?shù) z。這些值按照給定的順序與每個(gè)參數(shù)對(duì)應(yīng)。

          該程序會(huì)根據(jù)我們傳遞參數(shù)的值進(jìn)行以下數(shù)學(xué)運(yùn)算:

                
                a = 1 + 2
          b = 1 + 3
          c = 2 + 3

          該函數(shù)會(huì)打印 abc 的值。基于這個(gè)數(shù)學(xué)運(yùn)算,我們期望 a 等于 3b 等于 4c 等于 5。讓我們運(yùn)行程序:

                
                
                  $
                   go run add_numbers.go
                  
                
                Output
          3 4 5

          當(dāng)我們將 123 作為參數(shù)傳遞給 addNumbers() 函數(shù)時(shí),我們會(huì)收到預(yù)期的輸出。

          在函數(shù)定義中的參數(shù)通常是作為變量使用,當(dāng)您運(yùn)行方法時(shí),會(huì)將參數(shù)傳遞給函數(shù),并為它們賦值。

          返回值

          您可以將參數(shù)值傳遞給函數(shù),一個(gè)函數(shù)也可以產(chǎn)生值。

          函數(shù)可以通過(guò) return 語(yǔ)句生成一個(gè)值,return 語(yǔ)句將退出函數(shù)并 可選地 將表達(dá)式傳遞回調(diào)用者。返回的數(shù)據(jù)類型必須是指定過(guò)的。

          到目前為止,我們?cè)诤瘮?shù)中使用了fmt.Println() 語(yǔ)句而不是 return 語(yǔ)句。讓我們創(chuàng)建一個(gè)程序,返回一個(gè)變量。

          在一個(gè)名為 double.go 的新文本文件中,我們將創(chuàng)建一個(gè)將參數(shù) x 加倍并返回變量 y 的程序。我們將 3 作為double() 函數(shù)的參數(shù),然后打印 result 的值。

                
                package main

          import "fmt"

          func main() {
           result := double(3)
           fmt.Println(result)
          }

          func double(x int) int {
           y := x * 2
           return y
          }

          我們可以運(yùn)行程序并查看輸出:

                
                
                  $
                   go run double.go
                  
                
                Output
          6

          整數(shù) 6 將作為輸出返回,這正是所期望的 3 乘以 2的結(jié)果。

          如果函數(shù)指定了返回值,則必須在代碼中提供返回值。否則,將收到編譯錯(cuò)誤。

          我們可以通過(guò)用 return 語(yǔ)句注釋掉這一行來(lái)證明這一點(diǎn):

                
                package main

          import "fmt"

          func main() {
           result := double(3)
           fmt.Println(result)
          }

          func double(x int) int {
           y := x * 2
           // return y
          }

          現(xiàn)在,讓我們?cè)俅芜\(yùn)行程序:

                
                
                  $
                   go run double.go
                  
                
                Output
          ./double.go:13:1: missing return at end of function

          如果不使用此處的 return 語(yǔ)句,程序?qū)o(wú)法編譯。

          函數(shù)在遇到 return 語(yǔ)句時(shí)立即退出,即使它們不在函數(shù)末尾:

                
                package main

          import "fmt"

          func main() {
           loopFive()
          }

          func loopFive() {
           for i := 0; i < 25; i++ {
            fmt.Print(i)
            if i == 5 {
             // Stop function at i == 5
             return
            }
           }
           fmt.Println("This line will not execute.")
          }

          這里我們?cè)O(shè)置一個(gè) for 循環(huán),循環(huán)運(yùn)行 25 次。但是,在 for 循環(huán)內(nèi)部,我們有一個(gè)條件語(yǔ)句來(lái)檢查 i 的值是否等于 5。如果等于,我們將 return 進(jìn)行返回。因?yàn)槲覀冊(cè)?loopFive 函數(shù)中,所以函數(shù)中的任何一個(gè) return 都會(huì)退出函數(shù)。所以,我們永遠(yuǎn)不會(huì)到達(dá)該函數(shù)的最后一行來(lái)打印 This line will not execute.語(yǔ)句。

          for 循環(huán)內(nèi)使用了 return 語(yǔ)句來(lái)結(jié)束函數(shù),因此循環(huán)外的行將不會(huì)運(yùn)行。相反,如果我們使用了break語(yǔ)句[3],那么此時(shí)只有循環(huán)會(huì)退出,最后 fmt.Println() 一行會(huì)被運(yùn)行。

          return 語(yǔ)句能夠退出一個(gè)函數(shù),并且如果在函數(shù)簽名中指定,則會(huì)返回一個(gè)值。

          返回多個(gè)值

          一個(gè)函數(shù)可以指定多個(gè)返回值。讓我們編寫 repeat.go 程序并讓它返回兩個(gè)值。第一個(gè)返回值是得到的最終重復(fù)值,第二個(gè)返回值在參數(shù) reps 小于等于 0 時(shí)會(huì)得到一個(gè)錯(cuò)誤。

                
                
          package main

          import "fmt"

          func main() {
           val, err := repeat("Sammy"-1)
           if err != nil {
            fmt.Println(err)
            return
           }
           fmt.Println(val)
          }

          func repeat(word string, reps int) (string, error) {
           if reps <= 0 {
            return "", fmt.Errorf("invalid value of %d provided for reps. value must be greater than 0.", reps)
           }
           var value string
           for i := 0; i < reps; i++ {
            value = value + word
           }
           return value, nil
          }

          repeat 函數(shù)首先檢查 reps 參數(shù)是否為有效值。任何不大于 0 的值都會(huì)導(dǎo)致錯(cuò)誤。由于我們傳入了 -1,因此該代碼分支將執(zhí)行。請(qǐng)注意,當(dāng)我們從函數(shù)返回時(shí),我們必須同時(shí)提供 stringerror 的返回值。因?yàn)樘峁┑膮?shù)導(dǎo)致了錯(cuò)誤,我們將為第一個(gè)返回值傳回一個(gè)空白字符串,為第二個(gè)返回值傳回錯(cuò)誤。

          main() 函數(shù)中,我們可以通過(guò)聲明兩個(gè)新變量來(lái)接收兩個(gè)返回值,valueerr。因?yàn)榉祷刂锌赡苡绣e(cuò)誤,我們想在繼續(xù)程序之前檢查是否收到錯(cuò)誤。在這個(gè)例子中,我們確實(shí)收到了一個(gè)錯(cuò)誤。我們打印出錯(cuò)誤并 return 返回退出main() 函數(shù)以退出程序。

          如果沒(méi)有錯(cuò)誤,我們將打印出函數(shù)的返回值。

          注意: 最好只返回兩個(gè)或三個(gè)值。此外,您應(yīng)該始終將錯(cuò)誤作為函數(shù)的最后一個(gè)返回值返回。

          運(yùn)行程序?qū)a(chǎn)生以下輸出:

                
                output
          invalid value of -1 provided for reps. value must be greater than 0.

          在本節(jié)中,我們回顧了如何使用 return 語(yǔ)句從函數(shù)返回多個(gè)值。

          結(jié)論

          函數(shù)是在程序中執(zhí)行操作指令的代碼塊,有助于使我們的代碼更好地可重用和模塊化。

          要了解有關(guān)如何使您的代碼更模塊化的更多信息,您可以閱讀我們關(guān)于《如何在 Go 中編寫包》(點(diǎn)擊查看往期文章) 的指南。
          相關(guān)鏈接:

          [1] https://golang.org/pkg/fmt/

          [2] https://golang.org/ref/spec#Program_execution

          [3] https://gocn.github.io/How-To-Code-in-Go/docs/26-Using_Break_and_Continue_Statements_When_Working_with_Loops_in_Go/#break-%E8%AF%AD%E5%8F%A5



          往期推薦



          1e927cc14eebdc69acab8b54b439ec1c.webp

          Go1.20新功能:多重錯(cuò)誤包裝

          ed5aa8a083cea8272ef8696b9b95de79.webp

          谷歌發(fā)布查找開源漏洞的Go工具OSV-Scanner


          341228eb4942ce900095203aec50825f.webp

          ? 最好的Go框架:沒(méi)有框架?

          想要了解Go更多內(nèi)容,歡迎掃描下方??關(guān)注公眾號(hào), 回復(fù)關(guān)鍵詞 [實(shí)戰(zhàn)群]   ,就有機(jī)會(huì)進(jìn)群和我們進(jìn)行交流

          分享、在看與點(diǎn)贊Go  69f472457b97fef7c887ac46f7fc1024.webp

          瀏覽 47
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产精品久久久久久久久借妻 | 7799天天综合症 | 三级做爱网站 | 欧美色图日韩色图 | 狼人香蕉在线 |