本文最初发表在我的个人博客,查看原文,获得更好的阅读体验
Go中的函数除了可以声明入参之外,还可以声明结果参数(即返回值)。函数可以没有参数或接受多个参数,并且类型在变量名之后。当连续两个或多个函数的已命名形参类型相同时,除最后一个类型以外,其它都可以省略。
一 函数声明
语法:
func 函数名 (签名 类型)[([结果签名 ]类型)]][函数体]
例如:
示例1:
// 普通函数
func info() {
fmt.Println("some tips.")
}
示例2:
// 2个入参x, y; 1个未命名结果参数(int类型)
func add(x int, y int) int {
return x + y // 必须要有return
}
上边的示例2还可以简写成这样:
示例3:
// 2个入参x, y; 1个未命名结果参数(int类型)
func add(x, y int) int {
return x + y
}
注意第2行写法变化
1 多返回值
Go一个与众不同的特点是,函数和方法可以返回多个值:
func swap(x, y string) (string, string) {
return y, x
}
上述示例接受两个字符串类型的参数,并将其交换返回。
2 可命名结果参数
Go函数的返回“参数”(或称为结果“参数”)可以给出名称并用作常规变量,就像传入参数一样。如果给出名称,它们将在在函数开始时被初始化为其类型的零值;如果函数执行不带参数的return语句(即直接返回),结果参数的当前值将用作返回值。
例如,上一小节的示例还可以这样写:
func swap(x, y string) (m string, n string) {
m = y
n = x
return m, n
}
直接返回语句应当仅用在短函数中。在长的函数中它们会影响代码的可读性。
另外,名称不是强制的,但可以使代码更简短清晰,它们本身就是文档。
因为命名结果被初始化并与简单的return
相关联,因此它们可以更简洁,例如io.ReadFull
:
func ReadFull(r Reader, buf []byte) (n int, err error) {
for len(buf) > 0 && err == nil {
var nr int
nr, err = r.Read(buf)
n += nr
buf = buf[nr:]
}
return
// 等价于 return n, err
}
如果函数的签名声明了结果参数,则函数体的语句列表必须以终止语句(return
)结束:
示例1:
// 2个入参x, y; 1个结果参数(返回值,int类型)
func add(x int, y int) int {
return x + y // 必须要有return
}
示例2:
func IndexRune(s string, r rune) int {
for i, c := range s {
if c ==