乐趣区

关于golang:Go-使用记录

  1. for range 鲜为人知的坑,其实以前用 php 的时候遇到过,Java 没有这个问题

    // 因为 range 的时候,会创立一个长期变量 v 来承受 data 的遍历值
    // 而不是你想的 append(&data[0], $data[1], ...)
    data := []int{1,2,3}
    result := []*int{}
    for _, v := range data {result = append(result, &v)
    fmt.Println(&v) // 0xc0000ac008,0xc0000ac008,0xc0000ac008
    }
    
    for _, v := range result {fmt.Println(*v)  // [3,3,3]
    }
    
    // 正确处理形式
    data := []int{1,2,3}
    result := []*int{}
    for i, v := range data {result = append(result, &data[i])
    }
    
    for _, v := range result {fmt.Println(*v)
    }
  2. 我的项目中函数返回值更多用的是构造体,而不是构造体指针。尽管这会进步内存拷贝开销,但另一方面能够升高 gc 压力。因为返回值如果用指针,那么变量会存储到堆,而不是栈,也就是产生了变量逃逸。
    变量逃逸状况:
    (1)函数中 new 或者字面量创立进去的变量,如果取变量指针作为函数返回值,那么该变量产生逃逸
    (2)逃逸变量援用的指针逃逸
    (3)被指针类型的 slice,map,chan 饮用的变量产生逃逸
退出移动版