最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Golang常見錯誤之值拷貝和for循環(huán)中的單一變量詳解

 更新時間:2017年11月19日 11:54:10   作者:wecatch  
這篇文章主要給大家介紹了關(guān)于Golang常見錯誤之值拷貝和for循環(huán)中單一變量的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。

前言

golang(中文名:go語言)是谷歌2009發(fā)布的第二款開源編程語言。Go語言專門針對多處理器系統(tǒng)應(yīng)用程序的編程進(jìn)行了優(yōu)化,使用Go編譯的程序可以媲美C或C++代碼的速度,而且更加安全、支持并行進(jìn)程。。如果你想知道得更多,請移步至官網(wǎng)golang官網(wǎng)

在 Go 中函數(shù)的調(diào)用是值拷貝 copy value,而且在 for 循環(huán)中 v 的變量始終是一個變量。如果 v 是 pointer,print 這個 method 接收的是指針的拷貝,for 循環(huán)體中每次迭代 v 的 pointer value 都是不同的,所以輸出不同。

在 Go 常見的錯誤一文中 http://devs.cloudimmunity.com/gotchas-and-common-mistakes-in-go-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
}

把 field slice 的類型改為 pointer 結(jié)果又不同:

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 {
 v := v
 go v.print()
 }

 time.Sleep(3 * time.Second)
 //goroutines print: one, two, three
}

這兩段代碼的差異究竟是如何導(dǎo)致結(jié)果的不同?

我對上面的代碼 for 循環(huán)中的部分進(jìn)行了一下改造,改造之后對應(yīng)的代碼分別是:

slice 是非指針

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

 for _,v := range data {
 pp := (*field).print
 go pp(&v) //非 pointer
 }

slice 是指針

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

 for _,v := range data {
 pp := (*field).print
 go pp(v) // pointer
 }

改造之后再去看原來的代碼就能看出最明顯的差異在 print 的這個 method 的 receiver 的傳遞上。

在 Go 中函數(shù)的調(diào)用是值拷貝 copy value,而且在 for 循環(huán)中 v 的變量始終是一個變量。

如果 v 是 pointer,print 這個 method 接收的是指針的拷貝,for 循環(huán)體中每次迭代 v 的 pointer value 都是不同的,所以輸出不同。

如果 v 是一個普通的 struct,for 循環(huán)體中每次迭代 &v 都是 v 這個變量本身的 pointer,也就是總是指向同一個 field,由于在很大程度上這段代碼中的 goroutine 都是在 for 結(jié)束之后才執(zhí)行,而此時 v 將會指向最后一個 field,也就是 {"three"},所以輸出相同。

有人說 one、two、three 的隨機(jī)輸出是因?yàn)?CPU 是多核的原因?qū)е碌?,如果改成單核就是順序輸出,這樣的說法并不是特別準(zhǔn)確。理論上來講 goroutine 的調(diào)度是有一定的隨機(jī)性的,也就是即使是單核輸出也有可能是隨機(jī)的,只是在運(yùn)行如此簡單的例子時一般機(jī)器環(huán)境都不會導(dǎo)致這 3 個簡單的 goroutine 出現(xiàn)交叉執(zhí)行。比如可以在 print 輸出之前模擬 io 繁忙的來達(dá)到即使是單核也可能是隨機(jī)輸出的目的。

 if rand.Intn(100) > 20 {
 time.Sleep(1 * time.Second)
 }

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。

相關(guān)文章

  • 使用Go語言開發(fā)短鏈接服務(wù)的方法

    使用Go語言開發(fā)短鏈接服務(wù)的方法

    短鏈接一般是通過映射關(guān)系,將長長的一串網(wǎng)址,映射到幾個字符的短鏈接上,建立好這種映射關(guān)系之后保存到數(shù)據(jù)庫里,用戶每次訪問短鏈接的時候,這篇文章主要介紹了使用Go語言開發(fā)一個短鏈接服務(wù),需要的朋友可以參考下
    2024-03-03
  • Go語言實(shí)現(xiàn)百萬級WebSocket連接架構(gòu)設(shè)計及服務(wù)優(yōu)化

    Go語言實(shí)現(xiàn)百萬級WebSocket連接架構(gòu)設(shè)計及服務(wù)優(yōu)化

    本文將詳細(xì)介紹如何在Go中構(gòu)建一個能夠支持百萬級WebSocket連接的服務(wù),包括系統(tǒng)架構(gòu)設(shè)計、性能優(yōu)化策略以及具體的實(shí)現(xiàn)步驟和代碼示例
    2024-01-01
  • golang 占位符和fmt常見輸出介紹

    golang 占位符和fmt常見輸出介紹

    這篇文章主要介紹了golang 占位符和fmt常見輸出介紹,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • Go計算某段代碼運(yùn)行所耗時間簡單實(shí)例

    Go計算某段代碼運(yùn)行所耗時間簡單實(shí)例

    這篇文章主要給大家介紹了關(guān)于Go計算某段代碼運(yùn)行所耗時間的相關(guān)資料,主要介紹了Golang記錄計算函數(shù)執(zhí)行耗時、運(yùn)行時間的一個簡單方法,文中給出了詳細(xì)的代碼示例,需要的朋友可以參考下
    2023-11-11
  • Go語言實(shí)現(xiàn)的簡單網(wǎng)絡(luò)端口掃描方法

    Go語言實(shí)現(xiàn)的簡單網(wǎng)絡(luò)端口掃描方法

    這篇文章主要介紹了Go語言實(shí)現(xiàn)的簡單網(wǎng)絡(luò)端口掃描方法,實(shí)例分析了Go語言網(wǎng)絡(luò)程序的實(shí)現(xiàn)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-02-02
  • go語言分布式id生成器及分布式鎖介紹

    go語言分布式id生成器及分布式鎖介紹

    這篇文章主要為大家介紹了go語言分布式id生成器及分布式鎖介紹,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04
  • Golang Map類型的使用(增刪查改)

    Golang Map類型的使用(增刪查改)

    在Go中,map是哈希表的引用,是一種key-value數(shù)據(jù)結(jié)構(gòu),本文主要介紹了Golang Map類型的使用,具有一定的參考價值,感興趣的可以了解一下
    2024-05-05
  • Go使用XORM操作MySQL的陷阱盤點(diǎn)分析

    Go使用XORM操作MySQL的陷阱盤點(diǎn)分析

    在?Go?語言開發(fā)中,大家為了方便,通常會選擇使用?ORM?操作數(shù)據(jù)庫,比如使用?XORM?或?GORM?操作?MySQL,本文我們來介紹一下使用?XORM[3]?操作?MySQL?可能會遇到的陷阱
    2023-11-11
  • golang定時器Timer的用法和實(shí)現(xiàn)原理解析

    golang定時器Timer的用法和實(shí)現(xiàn)原理解析

    這篇文章主要介紹了golang定時器Ticker,本文主要來看一下Timer的用法和實(shí)現(xiàn)原理,需要的朋友可以參考以下內(nèi)容
    2023-04-04
  • GO的鎖和原子操作的示例詳解

    GO的鎖和原子操作的示例詳解

    這篇文章主要為大家詳細(xì)介紹了Go語言中鎖和原子操作的相關(guān)資料,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)Go語言有一定的幫助,需要的可以參考一下
    2023-02-02

最新評論

枣强县| 贡觉县| 静乐县| 庄浪县| 综艺| 农安县| 南召县| 新竹县| SHOW| 车致| 香河县| 安平县| 迭部县| 海伦市| 上栗县| 常宁市| 信丰县| 汾阳市| 定边县| 甘洛县| 泰宁县| 景宁| 合川市| 新蔡县| 五大连池市| 台南县| 德格县| 义马市| 卓资县| 海南省| 吉林省| 永善县| 扶余县| 荃湾区| 温州市| 会泽县| 万荣县| 崇州市| 莎车县| 安图县| 通化市|