<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之旅 廣告
                ## 5.3. 多返回值 在Go中,一個函數可以返回多個值。我們已經在之前例子中看到,許多標準庫中的函數返回2個值,一個是期望得到的返回值,另一個是函數出錯時的錯誤信息。下面的例子會展示如何編寫多返回值的函數。 下面的程序是findlinks的改進版本。修改后的findlinks可以自己發起HTTP請求,這樣我們就不必再運行fetch。因為HTTP請求和解析操作可能會失敗,因此findlinks聲明了2個返回值:鏈接列表和錯誤信息。一般而言,HTML的解析器可以處理HTML頁面的錯誤結點,構造出HTML頁面結構,所以解析HTML很少失敗。這意味著如果findlinks函數失敗了,很可能是由于I/O的錯誤導致的。 <u><i>gopl.io/ch5/findlinks2</i></u> ```Go func main() { for _, url := range os.Args[1:] { links, err := findLinks(url) if err != nil { fmt.Fprintf(os.Stderr, "findlinks2: %v\n", err) continue } for _, link := range links { fmt.Println(link) } } } // findLinks performs an HTTP GET request for url, parses the // response as HTML, and extracts and returns the links. func findLinks(url string) ([]string, error) { resp, err := http.Get(url) if err != nil { return nil, err } if resp.StatusCode != http.StatusOK { resp.Body.Close() return nil, fmt.Errorf("getting %s: %s", url, resp.Status) } doc, err := html.Parse(resp.Body) resp.Body.Close() if err != nil { return nil, fmt.Errorf("parsing %s as HTML: %v", url, err) } return visit(nil, doc), nil } ``` 在findlinks中,有4處return語句,每一處return都返回了一組值。前三處return,將http和html包中的錯誤信息傳遞給findlinks的調用者。第一處return直接返回錯誤信息,其他兩處通過fmt.Errorf(§7.8)輸出詳細的錯誤信息。如果findlinks成功結束,最后的return語句將一組解析獲得的連接返回給用戶。 在finallinks中,我們必須確保resp.Body被關閉,釋放網絡資源。雖然Go的垃圾回收機制會回收不被使用的內存,但是這不包括操作系統層面的資源,比如打開的文件、網絡連接。因此我們必須顯式的釋放這些資源。 調用多返回值函數時,返回給調用者的是一組值,調用者必須顯式的將這些值分配給變量: ```Go links, err := findLinks(url) ``` 如果某個值不被使用,可以將其分配給blank identifier: ```Go links, _ := findLinks(url) // errors ignored ``` 一個函數內部可以將另一個有多返回值的函數調用作為返回值,下面的例子展示了與findLinks有相同功能的函數,兩者的區別在于下面的例子先輸出參數: ```Go func findLinksLog(url string) ([]string, error) { log.Printf("findLinks %s", url) return findLinks(url) } ``` 當你調用接受多參數的函數時,可以將一個返回多參數的函數調用作為該函數的參數。雖然這很少出現在實際生產代碼中,但這個特性在debug時很方便,我們只需要一條語句就可以輸出所有的返回值。下面的代碼是等價的: ```Go log.Println(findLinks(url)) links, err := findLinks(url) log.Println(links, err) ``` 準確的變量名可以傳達函數返回值的含義。尤其在返回值的類型都相同時,就像下面這樣: ```Go func Size(rect image.Rectangle) (width, height int) func Split(path string) (dir, file string) func HourMinSec(t time.Time) (hour, minute, second int) ``` 雖然良好的命名很重要,但你也不必為每一個返回值都取一個適當的名字。比如,按照慣例,函數的最后一個bool類型的返回值表示函數是否運行成功,error類型的返回值代表函數的錯誤信息,對于這些類似的慣例,我們不必思考合適的命名,它們都無需解釋。 如果一個函數所有的返回值都有顯式的變量名,那么該函數的return語句可以省略操作數。這稱之為bare return。 ```Go // CountWordsAndImages does an HTTP GET request for the HTML // document url and returns the number of words and images in it. func CountWordsAndImages(url string) (words, images int, err error) { resp, err := http.Get(url) if err != nil { return } doc, err := html.Parse(resp.Body) resp.Body.Close() if err != nil { err = fmt.Errorf("parsing HTML: %s", err) return } words, images = countWordsAndImages(doc) return } func countWordsAndImages(n *html.Node) (words, images int) { /* ... */ } ``` 按照返回值列表的次序,返回所有的返回值,在上面的例子中,每一個return語句等價于: ```Go return words, images, err ``` 當一個函數有多處return語句以及許多返回值時,bare return 可以減少代碼的重復,但是使得代碼難以被理解。舉個例子,如果你沒有仔細的審查代碼,很難發現前2處return等價于 return 0,0,err(Go會將返回值 words和images在函數體的開始處,根據它們的類型,將其初始化為0),最后一處return等價于 return words,image,nil。基于以上原因,不宜過度使用bare return。 **練習 5.5:** 實現countWordsAndImages。(參考練習4.9如何分詞) **練習 5.6:** 修改gopl.io/ch3/surface (§3.2) 中的corner函數,將返回值命名,并使用bare return。
                  <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>

                              哎呀哎呀视频在线观看