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 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改
  • ¥20 wireshark抓不到vlan
  • ¥20 关于#stm32#的问题:需要指导自动酸碱滴定仪的原理图程序代码及仿真
  • ¥20 设计一款异域新娘的视频相亲软件需要哪些技术支持