亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

goroutine 是創建深拷貝還是淺拷貝?

goroutine 是創建深拷貝還是淺拷貝?

Go
森林海 2022-01-17 20:11:57
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”?如果我的 goroutine 是這樣的:go func() {    time.Sleep(10 * time.Second)    fmt.Println(myTest.name)}這個 goroutine 休眠了 10 秒,那么當 main 函數在 10 秒內改變“myTest”的值時,goroutine 會做什么呢?
查看完整描述

2 回答

?
MYYA

TA貢獻1868條經驗 獲得超4個贊

Go 中沒有“深拷貝”的概念,一切都是按值傳遞的。

不,你的樣本甚至不是一個淺拷貝你傳遞了一個指針(字符串的地址):

如果你改變myTest.name了main函數,那么你在改變之后再次打印它,你會看到它會改變,請看這個證明示例代碼:


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這樣定義:


type person struct {

    name  string

    id    int

    phone int

}  

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


關于你的主要問題,你可以像這樣自己測試:


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,因此它不是副本。

如果您需要這樣的復制調用:


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()

}


查看完整回答
反對 回復 2022-01-17
?
滄海一幻覺

TA貢獻1824條經驗 獲得超5個贊

Go 中沒有“深拷貝”的概念,一切都是按值傳遞的。


在您的實例中,這不是副本,您直接引用變量,如果您想要副本執行以下操作:


myTest := myTest

time.Sleep(10 * time.Second)

fmt.Println(myTest.name)


查看完整回答
反對 回復 2022-01-17
  • 2 回答
  • 0 關注
  • 162 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號