函数声明包括函数名、形式参数列表、返回值列表(可省略)以及函数体。
func name(parameter-list) (result-list) {
body
}
实参通过值的方式传递,因此函数的形参是实参的拷贝。对形参进行修改不会影响实参。但是,如果实参包括引用类型,如指针,slice,map,function, channel等类型,实参可能会由于函数的间接引用被修改。
递归:Go语言使用可变栈,栈的大小按需增加(初始时很小)。这使得我们使用递归时不必考虑溢出和安全问题。 虽然Go的垃圾回收机制会回收不被使用的内存,但不包括操作系统层面的资源,比如打开的文件、网络连接。 log包中的所有函数会为没有换行符的字符串增加换行符。 fmt.Errorf函数使用fmt.Sprintf格式化错误信息并返回。 匿名函数:
func squares() func() int {
var x int
return func() int {
x++
return x * x
}
}
可变参数:
func sum(vals...int) int {
total := 0
for _, val := range vals {
total += val
}
return total
}
defer语句经常用于处理成对的操作,如打开、关闭、连接、断开连接、加锁、释放锁。通过defer机制,不论函数逻辑多复杂,都能保证在执行路径下,资源被释放。释放资源的defer应该直接跟在请求资源的语句后。
package ioutil
func ReadFile(filename string) ([]byte, error) {
f, err := os.Open(filename)
if err != nil {
return nil, err
}
defer f.Close()
return ReadAll(f)
}
var mu sync.Mutex
var m = make(map[string]int)
func lookup(key string) int {
mu.Lock()
defer mu.Unlock()
return m[key]
}
Panic异常 Go的类型系统会在编译时捕获很多错误,但有些错误只能在运行时检查,如数组访问越界、 空指针引用等。这些运行时错误会引起painc异常。 一般而言,当panic异常发生时,程序会中断运行,并立即执行在该goroutine(可以先理解成线程)中被延迟的函数(defer 机制)。随后,程序崩溃并输出日志信息。日志信息包括panic value和函数调用的堆栈跟踪信息。panic value通常是某种错误信息。
Recover捕获异常 如果在deferred函数中调用了内置函数recover,并且定义该defer语句的函数发生了panic异 常,recover会使程序从panic中恢复,并返回panic value。导致panic异常的函数不会继续运 行,但能正常返回。在未发生panic时调用recover,recover会返回nil。
func Parse(input string) (s *Syntax, err error) {
defer func() {
if p := recover(); p != nil {
err = fmt.Errorf("internal error: %v", p)
}
}()
// ...parser...
}
Ref: 1.The Go Programming Language