首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >转到范围切片和goroutine方法调用,后面的逻辑。

转到范围切片和goroutine方法调用,后面的逻辑。
EN

Stack Overflow用户
提问于 2015-06-01 15:19:55
回答 1查看 620关注 0票数 1

代码如下:

代码语言:javascript
复制
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)
    }

我知道代码是错误的,因为for循环变量在for-range循环中被重用。

当goroutine有机会发射时,v的值可能已经被修改了。所以打印结果将是"three,three,three"

但当我们将数据变量修改为另一个声明时,如下所示:

代码语言:javascript
复制
data := []*field{{"one"},{"two"},{"three"}}

打印结果将是"one ,two,three"

我不知道为什么。指针对此有什么影响或任何不同的机制吗?

我从这篇文章上读到这个。但海报没有说明原因。或者只是个意外,输出是对的。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-06-01 15:32:26

在第一个循环中,vfield项的值。因为v是可寻址的,所以它被自动引用为print()方法的指针接收器。因此,v.print()使用v本身的地址,并且该地址的内容在循环的每次迭代中都被覆盖。

当您将声明更改为使用*field时,v现在是指向field值的指针。在本例中调用v.print()时,您正在对v指向的值进行操作,该值存储在data中,而对v的覆盖没有任何效果。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30577212

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档