[关闭]
@ironzhang 2018-12-16T08:11:54.000000Z 字数 2083 阅读 314

effect go

技术文章/golang


golang语法详解

golang中的继承并非面向对象意义上的继承,只是一种匿名变量

golang中如何保证类型TA实现了接口IA

  1. var _ IA = &TA{}

使用go vet检查代码,发现隐蔽错误

  1. log.Errorf("ping mysql faield: source[%s], err[%d]", source, err)

string和[]byte相互转换的成本

从概念上讲,一个[]byte(s)转换是分配了一个新的字节数组用于保存字符串数据的拷贝,然后引用这个底层的字节数组。编译器的优化可以避免在一些场景下分配和复制字符串数据,但总的来说需要确保在变量b被修改的情况下,原始的s字符串也不会改变。将一个字节slice转到字符串的string(b)操作则是构造一个字符串拷贝,以确保s2字符串是只读的。

为了避免转换中不必要的内存分配,bytes包和strings同时提供了许多实用函数。

nil值的slice

一个nil值的slice的行为和其它任意0长度的slice一样;例如reverse(nil)也是安全的。

结构体匿名成员

任何命名的类型都可以作为结构体的匿名成员

go的函数值是一个闭包

函数值不仅仅是一串代码,还记录了状态

我们经常选择一个方法,并且在同一个表达式里执行,比如常见的p.Distance()形式,实际上将其分成两步来执行也是可能的。p.Distance叫作“选择器”,选择器会返回一个方法"值"->一个将方法(Point.Distance)绑定到特定接收器变量的函数。这个函数可以不通过指定其接收器即可被调用;即调用时不需要指定接收器,只要传入函数的参数即可:

  1. p := Point{1, 2}
  2. q := Point{4, 6}
  3. distanceFromP := p.Distance // method value
  4. fmt.Println(distanceFromP(q)) // "5"
  5. var origin Point // {0, 0}
  6. fmt.Println(distanceFromP(origin)) // "2.23606797749979", sqrt(5)
  7. scaleP := p.ScaleBy // method value
  8. scaleP(2) // p becomes (2, 4)
  9. scaleP(3) // then (6, 12)
  10. scaleP(10) // then (60, 120)

golang中的坑

往接口赋值指针

一个包含nil指针的接口不是nil接口

  1. func NilFile() *os.File {
  2. return nil
  3. }
  4. func test1() {
  5. var r io.Reader
  6. r = NilFile()
  7. if r == nil {
  8. fmt.Printf("r is nil\n")
  9. } else {
  10. fmt.Printf("r is not nil\n")
  11. }
  12. }

接口值是否可比较

interface{}与其他类型如int型的比较

  1. func test4() {
  2. v.Get("c5") == int64(i+1)
  3. }

defer

  1. func test2() {
  2. for i := 0; i < 5; i++ {
  3. fmt.Printf("%d\n", i)
  4. defer fmt.Printf("defer %d\n", i)
  5. }
  6. }

select

  1. func test3() {
  2. c := make(chan struct{})
  3. select {
  4. case <-c:
  5. default:
  6. }
  7. fmt.Printf("test done\n")
  8. }

不定参数

  1. func printf(format string, args ...interface{}) {
  2. fmt.Printf(format, args)
  3. }

词法作用域的陷阱

函数值中记录的是循环变量的内存地址,而不是循环变量某一时刻的值

  1. package main
  2. import "fmt"
  3. func test1() {
  4. for _, s := range []string{"hello", "world", "test"} {
  5. defer func() {
  6. fmt.Printf("%s\n", s)
  7. }()
  8. }
  9. }
  10. func test2() {
  11. for _, s := range []string{"hello", "world", "test"} {
  12. defer fmt.Printf("%s\n", s)
  13. }
  14. }
  15. func test() {
  16. test1()
  17. test2()
  18. }
  1. func Test1(t *testing.T) {
  2. var ints = []int{0, 1, 2, 3}
  3. var wg sync.WaitGroup
  4. for _, i := range ints {
  5. wg.Add(1)
  6. go func(p *int) {
  7. defer wg.Done()
  8. fmt.Println(*p)
  9. }(&i)
  10. }
  11. wg.Wait()
  12. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注