mirror of
https://github.com/gopl-zh/gopl-zh.github.com.git
synced 2025-08-05 23:21:51 +00:00
回到简体
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
## 5.3. 多返迴值
|
||||
## 5.3. 多返回值
|
||||
|
||||
在Go中,一個函數可以返迴多個值。我們已經在之前例子中看到,許多標準庫中的函數返迴2個值,一個是期望得到的返迴值,另一個是函數出錯時的錯誤信息。下面的例子會展示如何編寫多返迴值的函數。
|
||||
在Go中,一个函数可以返回多个值。我们已经在之前例子中看到,许多标准库中的函数返回2个值,一个是期望得到的返回值,另一个是函数出错时的错误信息。下面的例子会展示如何编写多返回值的函数。
|
||||
|
||||
下面的程序是findlinks的改進版本。脩改後的findlinks可以自己發起HTTP請求,這樣我們就不必再運行fetch。因爲HTTP請求和解析操作可能會失敗,因此findlinks聲明了2個返迴值:鏈接列表和錯誤信息。一般而言,HTML的解析器可以處理HTML頁面的錯誤結點,構造出HTML頁面結構,所以解析HTML很少失敗。這意味着如果findlinks函數失敗了,很可能是由於I/O的錯誤導致的。
|
||||
下面的程序是findlinks的改进版本。修改后的findlinks可以自己发起HTTP请求,这样我们就不必再运行fetch。因为HTTP请求和解析操作可能会失败,因此findlinks声明了2个返回值:链接列表和错误信息。一般而言,HTML的解析器可以处理HTML页面的错误结点,构造出HTML页面结构,所以解析HTML很少失败。这意味着如果findlinks函数失败了,很可能是由于I/O的错误导致的。
|
||||
|
||||
<u><i>gopl.io/ch5/findlinks2</i></u>
|
||||
```Go
|
||||
@@ -39,23 +39,23 @@ func findLinks(url string) ([]string, error) {
|
||||
}
|
||||
```
|
||||
|
||||
在findlinks中,有4處return語句,每一處return都返迴了一組值。前三處return,將http和html包中的錯誤信息傳遞給findlinks的調用者。第一處return直接返迴錯誤信息,其他兩處通過fmt.Errorf(§7.8)輸出詳細的錯誤信息。如果findlinks成功結束,最後的return語句將一組解析獲得的連接返迴給用戶。
|
||||
在findlinks中,有4处return语句,每一处return都返回了一组值。前三处return,将http和html包中的错误信息传递给findlinks的调用者。第一处return直接返回错误信息,其他两处通过fmt.Errorf(§7.8)输出详细的错误信息。如果findlinks成功结束,最后的return语句将一组解析获得的连接返回给用户。
|
||||
|
||||
在finallinks中,我們必須確保resp.Body被關閉,釋放網絡資源。雖然Go的垃圾迴收機製會迴收不被使用的內存,但是這不包括操作繫統層面的資源,比如打開的文件、網絡連接。因此我們必須顯式的釋放這些資源。
|
||||
在finallinks中,我们必须确保resp.Body被关闭,释放网络资源。虽然Go的垃圾回收机制会回收不被使用的内存,但是这不包括操作系统层面的资源,比如打开的文件、网络连接。因此我们必须显式的释放这些资源。
|
||||
|
||||
調用多返迴值函數時,返迴給調用者的是一組值,調用者必須顯式的將這些值分配給變量:
|
||||
调用多返回值函数时,返回给调用者的是一组值,调用者必须显式的将这些值分配给变量:
|
||||
|
||||
```Go
|
||||
links, err := findLinks(url)
|
||||
```
|
||||
|
||||
如果某個值不被使用,可以將其分配給blank identifier:
|
||||
如果某个值不被使用,可以将其分配给blank identifier:
|
||||
|
||||
```Go
|
||||
links, _ := findLinks(url) // errors ignored
|
||||
```
|
||||
|
||||
一個函數內部可以將另一個有多返迴值的函數作爲返迴值,下面的例子展示了與findLinks有相同功能的函數,兩者的區别在於下面的例子先輸出參數:
|
||||
一个函数内部可以将另一个有多返回值的函数作为返回值,下面的例子展示了与findLinks有相同功能的函数,两者的区别在于下面的例子先输出参数:
|
||||
|
||||
```Go
|
||||
func findLinksLog(url string) ([]string, error) {
|
||||
@@ -64,7 +64,7 @@ func findLinksLog(url string) ([]string, error) {
|
||||
}
|
||||
```
|
||||
|
||||
當你調用接受多參數的函數時,可以將一個返迴多參數的函數作爲該函數的參數。雖然這很少出現在實際生産代碼中,但這個特性在debug時很方便,我們隻需要一條語句就可以輸出所有的返迴值。下面的代碼是等價的:
|
||||
当你调用接受多参数的函数时,可以将一个返回多参数的函数作为该函数的参数。虽然这很少出现在实际生产代码中,但这个特性在debug时很方便,我们只需要一条语句就可以输出所有的返回值。下面的代码是等价的:
|
||||
|
||||
```Go
|
||||
log.Println(findLinks(url))
|
||||
@@ -72,7 +72,7 @@ links, err := findLinks(url)
|
||||
log.Println(links, err)
|
||||
```
|
||||
|
||||
準確的變量名可以傳達函數返迴值的含義。尤其在返迴值的類型都相同時,就像下面這樣:
|
||||
准确的变量名可以传达函数返回值的含义。尤其在返回值的类型都相同时,就像下面这样:
|
||||
|
||||
```Go
|
||||
func Size(rect image.Rectangle) (width, height int)
|
||||
@@ -80,9 +80,9 @@ func Split(path string) (dir, file string)
|
||||
func HourMinSec(t time.Time) (hour, minute, second int)
|
||||
```
|
||||
|
||||
雖然良好的命名很重要,但你也不必爲每一個返迴值都取一個適當的名字。比如,按照慣例,函數的最後一個bool類型的返迴值表示函數是否運行成功,error類型的返迴值代表函數的錯誤信息,對於這些類似的慣例,我們不必思考合適的命名,它們都無需解釋。
|
||||
虽然良好的命名很重要,但你也不必为每一个返回值都取一个适当的名字。比如,按照惯例,函数的最后一个bool类型的返回值表示函数是否运行成功,error类型的返回值代表函数的错误信息,对于这些类似的惯例,我们不必思考合适的命名,它们都无需解释。
|
||||
|
||||
如果一個函數將所有的返迴值都顯示的變量名,那麽該函數的return語句可以省略操作數。這稱之爲bare return。
|
||||
如果一个函数将所有的返回值都显示的变量名,那么该函数的return语句可以省略操作数。这称之为bare return。
|
||||
|
||||
```Go
|
||||
// CountWordsAndImages does an HTTP GET request for the HTML
|
||||
@@ -104,14 +104,14 @@ func CountWordsAndImages(url string) (words, images int, err error) {
|
||||
func countWordsAndImages(n *html.Node) (words, images int) { /* ... */ }
|
||||
```
|
||||
|
||||
按照返迴值列表的次序,返迴所有的返迴值,在上面的例子中,每一個return語句等價於:
|
||||
按照返回值列表的次序,返回所有的返回值,在上面的例子中,每一个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。
|
||||
当一个函数有多处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.5:** 实现countWordsAndImages。(参考练习4.9如何分词)
|
||||
|
||||
**練習 5.6:** 脩改gopl.io/ch3/surface (§3.2) 中的corner函數,將返迴值命名,併使用bare return。
|
||||
**练习 5.6:** 修改gopl.io/ch3/surface (§3.2) 中的corner函数,将返回值命名,并使用bare return。
|
||||
|
Reference in New Issue
Block a user