mirror of
https://github.com/gopl-zh/gopl-zh.github.com.git
synced 2024-11-24 15:18:57 +00:00
ch5-07 done
This commit is contained in:
parent
178f6e769b
commit
c49becae58
@ -1,3 +1,68 @@
|
|||||||
## 5.7. 可變參數
|
## 5.7. 可變參數
|
||||||
|
|
||||||
TODO
|
参数数量可变的函数称为为可变参数函数。典型的例子就是fmt.Printf和类似函数。Printf首先接收一个的必备参数,之后接收任意个数的后续参数。
|
||||||
|
|
||||||
|
在声明可变参数函数时,需要在参数列表的最后一个参数类型之前加上省略符号“...”,这表示该函数会接收任意数量的该类型参数。
|
||||||
|
|
||||||
|
```Go
|
||||||
|
gopl.io/ch5/sum
|
||||||
|
func sum(vals...int) int {
|
||||||
|
total := 0
|
||||||
|
for _, val := range vals {
|
||||||
|
total += val
|
||||||
|
}
|
||||||
|
return total
|
||||||
|
}
|
||||||
|
```
|
||||||
|
sum函数返回任意个int型参数的和。在函数体中,vals被看作是类型为[] int的切片。sum可以接收任意数量的int型参数:
|
||||||
|
|
||||||
|
```Go
|
||||||
|
fmt.Println(sum()) // "0"
|
||||||
|
fmt.Println(sum(3)) // "3"
|
||||||
|
fmt.Println(sum(1, 2, 3, 4)) // "10"
|
||||||
|
```
|
||||||
|
|
||||||
|
在上面的代码中,调用者隐式的创建一个数组,并将原始参数复制到数组中,再把数组的一个切片作为参数传给被调函数。如果原始参数已经是切片类型,我们该如何传递给sum?只需在最后一个参数后加上省略符。下面的代码功能与上个例子中最后一条语句相同。
|
||||||
|
|
||||||
|
```Go
|
||||||
|
values := []int{1, 2, 3, 4}
|
||||||
|
fmt.Println(sum(values...)) // "10"
|
||||||
|
```
|
||||||
|
|
||||||
|
虽然在可变参数函数内部,...int 型参数的行为看起来很像切片类型,但实际上,可变参数函数和以切片作为参数的函数是不同的。
|
||||||
|
|
||||||
|
```Go
|
||||||
|
func f(...int) {}
|
||||||
|
func g([]int) {}
|
||||||
|
fmt.Printf("%T\n", f) // "func(...int)"
|
||||||
|
fmt.Printf("%T\n", g) // "func([]int)"
|
||||||
|
```
|
||||||
|
|
||||||
|
可变参数函数经常被用于格式化字符串。下面的errorf函数构造了一个以行号开头的,经过格式化的错误信息。函数名的后缀f是一种通用的命名规范,代表该可变参数函数可以接收Printf风格的格式化字符串。
|
||||||
|
|
||||||
|
```Go
|
||||||
|
func errorf(linenum int, format string, args...interface{})
|
||||||
|
{
|
||||||
|
fmt.Fprintf(os.Stderr, "Line %d: ", linenum)
|
||||||
|
fmt.Fprintf(os.Stderr, format, args…)
|
||||||
|
fmt.Fprintln(os.Stderr)
|
||||||
|
}
|
||||||
|
linenum, name := 12, "count"
|
||||||
|
errorf(linenum, "undefined: %s", name) // "Line 12:
|
||||||
|
undefined: count"
|
||||||
|
```
|
||||||
|
|
||||||
|
interfac{}表示函数的最后一个参数可以接收任意类型,我们会在第7章详细介绍。
|
||||||
|
|
||||||
|
**练习5.15:** 编写类似sum的可变参数函数max和min。考虑不传参时,max和min该如何处理,再编写至少接收1个参数的版本。
|
||||||
|
|
||||||
|
**练习5.16:**编写多参数版本的strings.Join。
|
||||||
|
|
||||||
|
**练习5.17:**编写多参数版本的ElementsByTagName,函数接收一个HTML结点树以及任意数量的标签名,返回与这些标签名匹配的所有元素。下面给出了2个例子:
|
||||||
|
|
||||||
|
```Go
|
||||||
|
func ElementsByTagName(doc *html.Node, name...string)
|
||||||
|
[]*html.Node
|
||||||
|
images := ElementsByTagName(doc, "img")
|
||||||
|
headings := ElementsByTagName(doc, "h1", "h2", "h3", "h4")
|
||||||
|
```
|
Loading…
Reference in New Issue
Block a user