函数
文章目录
函数可以让我们将一个语句序列打包为一个单元,然后可以从程序中其他地方多次调用。即函数是可重复使用的、用于执行指定任务的代码块。
函数声明
函数的声明包括函数名、形式参数列表、返回值参数列表及函数体。
func 函数名(参数列表)(返回值列表){
函数体
}
- 函数名是由字母、数字和下划线组成,但首位不能使用数字。同一个包中,函数名是唯一的。
- 形式参数列表描述了函数的参数名以及参数类型
- 返回值列表描述了返回值的变量名以及参数类型,当返回一个匿名返回值时,括号可以省略;当没有返回值返回时,返回值列表可以省略不写
func floatSum(x float64, y float64) float64 {
z := x + y
return z
}
func main() {
rlt := floatSum(1, 2)
fmt.Println(rlt)
} //5
其中x,y是形参、1,2为实参,函数返回一个float64类型的值。
函数参数列表如果类型相同,可以合并,只写一个类型;如果函数有命名的返回值,那么return
语句可以省略返回的参数名,下面的写法也是合理的
func floatSum(x, y float64) (z float64) {
z = x + y
return
}
函数调用
go语言中我们可以通过函数名的方式调用函数。例如上面在main()
方法中直接调用floatSum()
函数。调用时,函数的参数必须与函数声明时一致。go语言没有默认参数值、也没有任何方法通过参数名指定形参,因此形参和返回值的变量名,对于函数调用者来说没有意义。
参数
常规参数
函数的形参在函数体中,是一个局部变量,有名的返回值和参数作为函数最外层的局部变量,被存储在相同的词法块中。
go语言中的传参都是按值传递,函数的形参是实参的拷贝,对形参进行修改,不会影响到实参。如果实参的类型是引用类型(指针、slice、map、function、channel等类型)则实参可能会由于函数的间接引用被修改,这点在使用时要注意。
可变参数
可变参数是指函数的参数数量不固定,通过在参数名后加...
来标识。
func floatSum(m float64,x ...float64) {
fmt.Println(m)//1
fmt.Println(x)//[2,3]
fmt.Printf("%T\n", x) //[]float64
}
func main() {
floatSum(1, 2, 3)
}
固定参数搭配可变参数使用时,可变参数放在固定参数后。
可变参数是一个切片,其本质是通过切片来实现的。
多返回值
在go语言中一个函数可以返回多个值。许多标准库中的函数返回2个值,一个是想要得到的值,另一个是函数出错时的错误信息。函数有多个返回值时,必须使用()
将所有的返回值包裹起来。
func calc(x, y float64) (float64, float64) {
sum := x + y
sub := x - y
return sum, sub
}
func main() {
sum, sub := calc(3, 4)
fmt.Printf("sum:%v\nsub:%v\n", sum, sub)
}
对于大部分函数而言,永远无法确保能够成功。比如任何进行I/O操作的函数都会面临出现错误的可能。在go语言的错误处理中,错误被认为是API和应用程序用户界面的一个重要组成部分,程序运行失败仅被认为是几个预期的结果之一。
对于将运行失败看作是预期结果的函数,它们会返回一个额外的返回值,通常是最后一个,如果导致失败的原因只有一个,那么可以是一个布尔值,通常命名为ok。例如map
取值
_,ok := map[key]
if !ok{
//map key does not exist
}
如果返回的值,不需要使用,可以使用匿名的方式_
下划线来表示。
通常,导致错误的原因不止是一个,用户需要了解更多的信息,因此额外返回的类型不再是布尔型,而是error类型。
当error类型返回的是nil时,意味着成功,no-nil时意味着失败,通常当函数返回no-nil时,其他的返回值是未定义的,这些未定义的返回值应该被忽略(被定义为匿名变量_
)。但也有特例,比如读取文件时发生错误,Read函数会返回可以读取的字节数以及错误的信息。
常见的错误处理方式
-
传播错误:最常见的处理方式,函数中某个子程序的失败,会变成该函数的失败。
resp,err := http.get(url) if err != nil{ return nil, error } doc, err := html.Parse(resp.Body) resp.Body.