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

        共 8626字,需瀏覽 18分鐘

         ·

        2022-12-26 09:28

        目錄

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


        介紹

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

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

        • fmt.Println() 會將對象打印到標準輸出(最可能在您的終端)。
        • fmt.Printf() 允許您將輸出格式化打印。

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

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

        定義一個函數(shù)

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

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

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

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

              
              func hello() {}

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

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

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

        現(xiàn)在我們的函數(shù)已經(jīng)完全定義好了,但是如果我們此時運行程序,什么都不會發(fā)生,因為我們沒有調用函數(shù)。

        因此,在我們的 main() 代碼塊中,來調用 hello() 函數(shù):

              
              package main

        import "fmt"

        func main() {
         hello()
        }

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

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

              
              
                $
                 go run hello.go
                

        您將收到以下輸出:

              
              Output
        Hello, World!

        請注意,我們還引入了一個名為 main() 的函數(shù)。main() 函數(shù)是一個特殊的函數(shù),它告訴編譯器程序應該從這里開始。對于 可執(zhí)行 的任何程序(可以從命令行運行的程序),都需要一個 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ù)更復雜。我們可以在函數(shù)中使用 for循環(huán)(點擊查看往期文章) 、 條件語句(點擊查看往期文章) 等。

        例如,以下函數(shù)使用條件語句檢查 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.")
        }

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

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

        使用參數(shù)

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

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

        讓我們創(chuàng)建一個將單詞重復指定次數(shù)的程序。它將接受一個 string 類型的 word 參數(shù)和一個用于重復單詞的次數(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 值。這些值按照給定的順序與每個參數(shù)相對應。repeat 函數(shù)有一個 for 循環(huán),將循環(huán)參數(shù) reps 指定的次數(shù)。對于每次循環(huán),都會打印參數(shù) word  的值。

        這是程序的輸出:

              
              Output
        SammySammySammySammySammy

        如果你有一組參數(shù)都是相同的值,你可以不用每次指定類型。讓我們創(chuàng)建一個小程序,它接受都是 int 值的參數(shù) x,  y, 和 z 這些。我們將創(chuàng)建一個函數(shù),函數(shù)將打印他們的總和。下面我們將調用該函數(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)
        }

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

        我們將數(shù)字 1 傳入?yún)?shù) x,2 傳入?yún)?shù) y,3 傳入?yún)?shù) z。這些值按照給定的順序與每個參數(shù)對應。

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

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

        該函數(shù)會打印 a,b, c 的值?;谶@個數(shù)學運算,我們期望 a 等于 3, b 等于 4c 等于 5。讓我們運行程序:

              
              
                $
                 go run add_numbers.go
                
              
              Output
        3 4 5

        當我們將 1、23 作為參數(shù)傳遞給 addNumbers() 函數(shù)時,我們會收到預期的輸出。

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

        返回值

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

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

        到目前為止,我們在函數(shù)中使用了fmt.Println() 語句而不是 return 語句。讓我們創(chuàng)建一個程序,返回一個變量。

        在一個名為 double.go 的新文本文件中,我們將創(chuàng)建一個將參數(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
        }

        我們可以運行程序并查看輸出:

              
              
                $
                 go run double.go
                
              
              Output
        6

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

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

        我們可以通過用 return 語句注釋掉這一行來證明這一點:

              
              package main

        import "fmt"

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

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

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

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

        如果不使用此處的 return 語句,程序將無法編譯。

        函數(shù)在遇到 return 語句時立即退出,即使它們不在函數(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.")
        }

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

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

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

        返回多個值

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

              
              
        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 的值都會導致錯誤。由于我們傳入了 -1,因此該代碼分支將執(zhí)行。請注意,當我們從函數(shù)返回時,我們必須同時提供 stringerror 的返回值。因為提供的參數(shù)導致了錯誤,我們將為第一個返回值傳回一個空白字符串,為第二個返回值傳回錯誤。

        main() 函數(shù)中,我們可以通過聲明兩個新變量來接收兩個返回值,valueerr。因為返回中可能有錯誤,我們想在繼續(xù)程序之前檢查是否收到錯誤。在這個例子中,我們確實收到了一個錯誤。我們打印出錯誤并 return 返回退出main() 函數(shù)以退出程序。

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

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

        運行程序將產(chǎn)生以下輸出:

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

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

        結論

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

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

        [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新功能:多重錯誤包裝

        ed5aa8a083cea8272ef8696b9b95de79.webp

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


        341228eb4942ce900095203aec50825f.webp

        ? 最好的Go框架:沒有框架?

        想要了解Go更多內容,歡迎掃描下方??關注公眾號, 回復關鍵詞 [實戰(zhàn)群]   ,就有機會進群和我們進行交流

        分享、在看與點贊Go  69f472457b97fef7c887ac46f7fc1024.webp

        瀏覽 47
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
          
          

            1. 国产精品女教师 | 男人叉女人的视频 | 成人电影久久久 | 国产精品pans嫩模写真 | 日韩一区在线电影 |