首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >戈鲁丁是制造深拷贝还是浅拷贝?

戈鲁丁是制造深拷贝还是浅拷贝?
EN

Stack Overflow用户
提问于 2016-06-23 06:38:12
回答 2查看 807关注 0票数 2
代码语言:javascript
复制
var person struct {
    name string
    id   int
    phone int
}

func main () {
    var myTest person
    //construct the variable 
    ...


    go func() {
        fmt.Println(myTest.name)
    }()
}

goroutine从主函数中深复制变量"myTest“吗?

如果我的猩猩像这样:

代码语言:javascript
复制
go func() {
    time.Sleep(10 * time.Second)
    fmt.Println(myTest.name)
}

这只猩猩睡眠10秒,所以当主功能在10秒内改变"myTest“的值时,它会做什么呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-06-23 06:59:01

在go中没有“深拷贝”的概念,一切都是通过价值传递的。

不,您的示例甚至不是一个浅拷贝,您传递了一个指针(字符串地址):

如果您在myTest.name函数中更改了main,那么在该更改之后再次打印它--您将看到它将发生变化,请参见下面的示例代码:

代码语言:javascript
复制
package main

import (
    "fmt"
    "sync"
    "time"
)

type person struct {
    name  string
    id    int
    phone int
}

var wg sync.WaitGroup

func main() {
    myTest := person{"Alex", 22, 123}
    fmt.Printf("%T : %[1]v %v\n", myTest.name, &myTest.name) // string : Alex 0xc042006740
    wg.Add(1)
    go func() {
        fmt.Printf("%T : %[1]v %v\n", myTest.name, &myTest.name) // string : Alex 0xc042006740
        time.Sleep(500 * time.Millisecond)
        fmt.Printf("%T : %[1]v %v\n", myTest.name, &myTest.name) // string : J 0xc042006740
        wg.Done()
    }()
    time.Sleep(100 * time.Millisecond)
    myTest.name = "J"
    wg.Wait()
}

首先像这样定义person struct

代码语言:javascript
复制
type person struct {
    name  string
    id    int
    phone int
}  

第二,使用sync.WaitGroup等待goroutine完成。

关于你的主要问题,你可以自己测试一下:

代码语言:javascript
复制
package main

import (
    "fmt"
    "sync"
    "time"
)

type person struct {
    name  string
    id    int
    phone int
}

var wg sync.WaitGroup

func main() {
    myTest := person{"Alex", 22, 123}
    wg.Add(1)
    go func() {
        fmt.Printf("%T : %[1]v\n", myTest.name) // string : Alex
        time.Sleep(500 * time.Millisecond)
        fmt.Printf("%T : %[1]v\n", myTest.name) // string : J
        wg.Done()
    }()
    time.Sleep(100 * time.Millisecond)
    myTest.name = "J"
    wg.Wait()
}

因此,正如您在这个示例中看到的,字符串name内容在主要函数中的变化反映为goroutine,所以它不是一个副本。

如果您需要这样的副本呼叫:

代码语言:javascript
复制
package main

import (
    "fmt"
    "sync"
    "time"
)

type person struct {
    name  string
    id    int
    phone int
}

var wg sync.WaitGroup

func main() {
    myTest := person{"Alex", 22, 123}
    wg.Add(1)
    go func(name string) {
        fmt.Printf("%T : %[1]v\n", name) // string : Alex
        time.Sleep(500 * time.Millisecond)
        fmt.Printf("%T : %[1]v\n", name) // string : Alex
        wg.Done()
    }(myTest.name)
    time.Sleep(100 * time.Millisecond)
    myTest.name = "J"
    wg.Wait()
}

见:Is it correct to ref a var inside golang func?

票数 5
EN

Stack Overflow用户

发布于 2016-06-23 06:58:28

在go中没有“深拷贝”的概念,一切都是通过价值传递的。

在您的实例中,这不是副本,而是直接引用变量,如果希望复制,请执行以下操作:

代码语言:javascript
复制
myTest := myTest
time.Sleep(10 * time.Second)
fmt.Println(myTest.name)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37983977

复制
相关文章

相似问题

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