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 飲用的變量發生逃逸
相關文章
相關標籤/搜索