一 坑
1. 用自带的 json 库序列化 strut 变量时,只有那些首字母大写的变量才会被序列化,这意味着在go的世界里,所有的json属性名都是大写开头...这真的不是bug吗...(ps : 已经找到大写转小写的解决方案,没搞清楚就挖坑,捂脸...)
2. 任何一个未被捕获的 panic 都有可能导致整个程序的崩溃,一定要defer, recover...
3. err != nil 就是翔,interface{} 滥用是翔中翔...
4. 基础属性间的转换 和 拼接 也是翔...
5. 用go时,先忘记java的 设计模式 和 一切皆对象
6. 在go里,变量的nil值需要特别关注,因为会被赋予0值。业务设计上需要避开 或者 利用这一点
7. window 和 linux 的syscall包的 api 不一致,需要特别关注,想编译个linux包时才知道什么叫痛
二 指北
1. package <pkgName>这一行表示当前文件属于哪个包,而包名main则告诉我们它是一个可独立运行的包,它在编译后会产生可执行文件。除了main包之外,其它的包最后都会生成*.a文件(也就是包文件)并放置在$GOPATH/pkg/$GOOS_$GOARCH中。每一个可独立运行的Go程序,必定包含一个package main,在这个main包中必定包含一个入口函数main,而这个函数既没有参数,也没有返回值。
2. 点操作,导入包时,如果包名前有点号,则在调用这个包的函数时,可以省略前缀的包名。如fmt.println()可以写为println()。
3. 别名操作,可以在导入的包前加入字符串指定别名;_操作,当导入的报名前包含该符号时,意为调用该包里的init函数,而不直接使用包里的函数。
4. rune是int32的别称,byte是uint8的别称,int8和int32这类位数不同的变量之间不允许互相赋值或者操作。
5. 浮点数的类型有float32和float64两种(没有float类型),默认是float64。
6. ` 括起的字符串为Raw字符串,即字符串在代码中的形式就是打印时的形式,它没有字符转义,换行也将原样输出。
7. 除非被显式设置为其它值或iota,每个const分组的第一个常量被默认设置为它的0值,第二及后续的常量被默认设置为它前面那个常量的值,如果前面那个常量的值是iota,则它也被设置为iota,iota的默认值为0,每调用一次都会加1,但每遇到一个const,iota就会重置
8. 大写字母开头的变量是可导出的,也就是其它包可以读取的,是公用变量;小写字母开头的就是不可导出的,是私有变量。 大写字母开头的函数也是一样,相当于class中的带public关键词的公有函数;小写字母开头的就是有private关键词的私有函数。
9. Slice,go里面的动态数组,它是一个引用类型。声明一个slice和申明一个array一样,只是少了长度定义:var myslice []int
10. Slice可以从一个已经存在的数组或者slice中再次声明,通过array[i:j] 来获取,因为slice是引用类型,改变其值也会改变原数组的值。
11. Map有两个返回值,第一返回值为请求的key的value,第二个返回值为该key是否存在,是的话true,反之false;map也是引用类型,值的修改会影响所有同样引用该map的值
12. Make用于内建类型(map,slice 和channel)的内存分配,new用于各种类型的内存分配
13. For配合range可以用于读取slice和map中的内容。
14. Switch的每个case后面默认带有break,可以通过fallthrough强制执行后面的代码,每一个fallthrough只会生效一次。
15. 在函数体中,变参是一个slice数组。
16. 函数的参数传递是值传递,如果需要在函数体中调整参数本体信息,需要定义指针类型参数,并传入地址。
17. Defer语句会在函数体执行完后开始执行,执行顺序是后进先出,也就是逆序。
18. 当函数作为一种变量时,可以通过type来进行定义,他的类型就是所有拥有相同的参数,相同的返回值的一种类型。
19. panic有点像java中的抛出异常,当函数调用了panic后,该协程的会执行函数体中的defer,然后一路向上返回,直到协程退出。
20. 正常时调用recover会返回nil,没有任何其他效果,但是当协程陷入崩溃状态(类似panic),则recover会捕获到panic的值,并且让协程恢复正常执行,有点类似java中的catch。
21. Struct有 N 种初始化方式,一种按参数顺序提供值 p:=person(‘xxx’, 123);第二种时通过field:value的方式初始化,如:p:={name:’xx’,age:12}
22. 当匿名字段是一个stuct时,该struct的全部字段都被隐式的导入当前的struct。
23. 对象的方法需要以函数的形式进行绑定,默认是值传递,当以指针绑定时,是引用传递,类似: func (b *box) test() string{}
24. Go里,接口是方法的聚合,当某个对象实现了某个接口的所有方法时,则认为此对象实现了该接口,可以将对象的值赋给该接口类型,可以通过接口访问对象的方法,但不能访问对象的属性。
25. 空接口做参数时,可以接受任何类型的参数,因为相当于任意类型都实现了该接口。
26. Value, ok = element.(T) 可以用于判断 element是否是T类型的数据,value是变量的值,element是interface类型的变量;element.(type)不能在switch外的地方使用。
27. 可以通过close(c)方法来关闭一个channel;可以通过range来不断的读取channel中的数据,直到该channel被显示的关闭;可以通过select来监视channel的读写。
28. 交换 i 和 j 变量的方式 : i, j = j, i 。
来源:oschina
链接:https://my.oschina.net/u/1268144/blog/641509