Go 使用记录

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

    // 由于 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 饮用的变量发生逃逸
相关文章
相关标签/搜索