go基础-函数
函数声明包含了函数名,形参列表,函数体和返回值。 func 函数名(形参列表) (返回值) {
函数体
}
返回值可以像形参一样命名,每一个返回的命名值会声明为一个局部变量,并根据变量类型初始化为相应的0值。
如果几个形参或返回值的函数类型相同,那么类型只需要写一次。如:
func f(i, j, k int, s, t string)
函数的类型称作函数签名,当两个函数拥有相同的形参列表和返回列表时,认为这两个函数的类型或签名都是相同的。
go语言没有默认参数值也不能指定实参名
go的实参是按值传递的
如果提供的实参包含引用类型(指针,slice,map,函数或者通道)那么函数使用这些变量将会简介的修改实参内容
go语言的垃圾回收机制将回收未使用的内存,但不能指望他会释放未使用的操作系统资源
一个多值调用可以作为单独的实参传递给拥有两个形参的函数中
比如:
func findLinksLog(url string) ([]string, error) {return nil, nil}
fmt.Println(findLinksLog(url));
一个函数如果有命名的返回值,可以省略return语句的操作数称为裸返回
func test() (a string, b int) {
a = "1"
b = 2
return //相当于 return a, b
}
函数变量不能比较所以不能用在map的键中
函数字面量在任何表达式内指定函数变量,函数字面量就像函数声明(就是函数变量)
拓展符
可以通过以下调用:
values := []int{1,2,3,4}
fmt.Println(sum(values...))
defer 以倒序进行
一个典型的宕机发生时goroutine中的所有延迟函数会执行,
可以利用recover函数对宕机进行恢复
比如:
func Parse(input string) (s *Syntax, err error){
defer func(){
if p := recover(); p!=nil {
err = fmt.Errorf("internal error: %v", p)
}
}
}
接口的nil有分 动态值nil 和 动态类型nil
比如:
var s interface{}
此时动态值和动态类型都为nil
如果是:
var s *bytes.Buffer
此时动态值为空,但是动态类型不是空 所以如下: 会为真
if s != nil {
}
当你实现了一个接口 然后调用此函数时,本质上go是调用了实现此接口的方法,然后给了这个接口对应的接收者地址。