[TOC] # 自增和自减 golang里包含其他语言常用的自增i++ 和自减i--,但是在golang里他们是语句而不是表达式,所以j=i++这种是错误的写法,而且golang也不支持++和--放在变量前面如++i的形式。 ~~~ i++ // i的值+1 i-- // i的值-1 ++i //错误 --i // 错误 j = i-- //错误 ~~~ # 短变量声明只能在函数内部不能再外部 ~~~ s := "" //错误 func main() { s := "" prinltln(s) } ~~~ # new只是一个预定义的函数,它并不是一个关键字 ~~~ func delta(old, new int) int { return new - old } // 函数内无法调用new函数, ~~~ # golang 对Unicode标示的支持 对于中文汉字,Unicode标志都作为小写字母处理,因此中文的命名默认不能导出;不过国内的用户针对该问题提出了不同的看法,根据RobPike的回复,在Go2中有可能会将中日韩等字符当作大写字母处理。 # golang 函数参数都是值的传递,所以无法修改实参的值 实参通过值的方式传递,因此函数的形参是实参的拷贝。对形参进行修改不会影响实参。但是,如果实参包括引用类型,如指针,slice(切片)、map、function、channel等类型,实参可能会由于函数的简介引用被修改。 # defer是return语句执行后执行的,所以可以修改返回值 ~~~ func triple(x int) (result int) { defer func() { result += x }() return double(x) } fmt.Println(triple(4)) // "12" ~~~ # golang里任何类型都可以声明变量? golang里除了指针和interface其他类型都可以声明变量。 ~~~ type test []int func (t test)hello() { // 合法 fmt.Println("hello") } ~~~ # 一个包含nil指针的接口不是nil接口 一个不包含任何值的nil接口值和一个刚好包含nil指针的接口值是不同的。这个细微区别产生了一个容易绊倒每个Go程序员的陷阱。 思考下面的程序。当debug变量设置为true时,main函数会将f函数的输出收集到一个bytes.Buffer类型中。 ~~~ const debug = true func main() { var buf *bytes.Buffer if debug { buf = new(bytes.Buffer) // enable collection of output } f(buf) // NOTE: subtly incorrect! if debug { // ...use buf... } } // If out is non-nil, output will be written to it. func f(out io.Writer) { // ...do something... if out != nil { out.Write([]byte("done!\n")) } } ~~~ 我们可能会预计当把变量debug设置为false时可以禁止对输出的收集,但是实际上在out.Write方法调用时程序发生了panic: ~~~ if out != nil { out.Write([]byte("done!\n")) // panic: nil pointer dereference } ~~~ 当main函数调用函数f时,它给f函数的out参数赋了一个bytes.Buffer的空指针,所以out的动态值是nil。然而,它的动态类型是bytes.Buffer,意思就是out变量是一个包含空指针值的非空接口(如图7.5),所以防御性检查out!=nil的结果依然是true。