duanqianwei2485 2015-06-01 15:19
浏览 45
已采纳

进行范围切片和goroutine方法调用,其背后的逻辑

The code is like the following:

package main

    import (
        "fmt"
        "time"
    )

    type field struct {
        name string
    }

    func (p *field) print() {
        fmt.Println(p.name)
    }

    func main() {
        data := []field{{"one"},{"two"},{"three"}}
        for _,v := range data {
            go v.print()
        }
        time.Sleep(3 * time.Second)
    }

I know that the code is wrong,because the for loop variable is reused in the for-range loop.

When the goroutine has got the chance to launch,the value of v might has been modified. so the print result will be "three,three,three".

But when we modify the data variable into another declaration as:

data := []*field{{"one"},{"two"},{"three"}}

the print result will be "one ,two,three".

I didn't get the point of why. Does the pointer make any difference or any different mechanism is on this?

I read this from this article. But the poster didn't not tell why. Or it's just a incident the output is right.

  • 写回答

1条回答 默认 最新

  • dsgnze6572 2015-06-01 15:32
    关注

    In the first loop, v is the value of a field item. Because v is addressable, it is automatically referenced as the pointer receiver for the print() method. So v.print() is using the address of v itself, and the contents of that address is overwritten each iteration of the loop.

    When you change the declaration to use a *field, v is now a pointer to a field value. When you call v.print() in this case, you are operating on the value that v points to, which is stored in data, and the overwriting of v has no effect.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 Vue3 大型图片数据拖动排序
  • ¥15 划分vlan后不通了
  • ¥15 GDI处理通道视频时总是带有白色锯齿
  • ¥20 用雷电模拟器安装百达屋apk一直闪退
  • ¥15 算能科技20240506咨询(拒绝大模型回答)
  • ¥15 自适应 AR 模型 参数估计Matlab程序
  • ¥100 角动量包络面如何用MATLAB绘制
  • ¥15 merge函数占用内存过大
  • ¥15 使用EMD去噪处理RML2016数据集时候的原理
  • ¥15 神经网络预测均方误差很小 但是图像上看着差别太大