Golang 中国

为什么这两段代码的输出会不一样?

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)
    //goroutines print: three, three, three
}
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)
}

//goroutines print: one, two, three
4 回复
oneofwower
#1 oneofwower • 2018-03-05 13:11

https://gocn.io/question/856

这里有个完全类似的问题,但看了感觉还不是很明白

oneofwower
#2 oneofwower • 2018-03-05 13:17
nulijiabei
#3 nulijiabei • 2018-03-05 13:38
package main

import (
    "fmt"
    "time"
)

type field struct {
    name string
}

func (p *field) print() {
    fmt.Printf("%p %s\n", p, p.name)
}

func TestClosure() {

    // data := []*field{{"one"}, {"two"}, {"three"}}
    one := new(field)
    one.name = "one"
    two := new(field)
    two.name = "two"
    three := new(field)
    three.name = "three"

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

    for _, v := range data {
        go v.print()
    }

    time.Sleep(3 * time.Second)
}

func TestClosure1() {

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

    var one field
    one.name = "one"
    var two field
    two.name = "two"
    var three field
    three.name = "three"

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

    for _, v := range data {
        go v.print()
    }

    time.Sleep(3 * time.Second)
}

func TestClosure2() {

    // data := []*field{{"one"}, {"two"}, {"three"}}
    one := new(field)
    one.name = "one"
    two := new(field)
    two.name = "two"
    three := new(field)
    three.name = "three"

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

    //    for _, v := range data {
    //        go func() {
    //            v.print()
    //        }()
    //    }

    for _, v := range data {
        go func(x *field) {
            x.print()
        }(v)
    }

    time.Sleep(3 * time.Second)
}

func main() {
    TestClosure()
    fmt.Println("----")
    TestClosure1()
    fmt.Println("----")
    TestClosure2()
}
linker
#4 linker • 2018-03-05 15:55

我写过一篇Blog 专门讲这个问题。
https://my.oschina.net/linker/blog/817238

需要 登录 后方可回复, 如果你还没有账号你可以 注册 一个帐号。