激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Golang - 淺析Go語言中的Range關鍵字

淺析Go語言中的Range關鍵字

2020-05-03 12:45daisy Golang

Range是go語言中很獨特的一個關鍵詞,也相當好用。下面就跟著小編來再聊聊這個Range關鍵字,有需要的朋友們可以參考借鑒。

前言

相信用過Range的朋友們都知道,Go語言中的range關鍵字使用起來非常的方便,它允許你遍歷某個slice或者map,并通過兩個參數(indexvalue),分別獲取到slice或者map中某個元素所在的index以及其值。

比如像這樣的用法:

?
1
2
3
4
for index, value := range mySlice {
 fmt.Println("index: " + index)
 fmt.Println("value: " + value)
}

上面的例子足夠清晰的描述了range的用法,實際上在使用range關鍵字的時候,還有一些需要特別注意的地方,有一些新手很容易入的”坑”。

為了說明這些”坑”,我們可以從下面這個稍復雜的例子說起:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
type Foo struct {
 bar string
}
func main() {
 list := []Foo{
 {"A"},
 {"B"},
 {"C"},
 }
 list2 := make([]*Foo, len(list))
 for i, value := range list {
 list2[i] = &value
 }
 fmt.Println(list[0], list[1], list[2])
 fmt.Println(list2[0], list2[1], list2[2])
}

在這個例子中,我們干了下面的一些事情:

     1、定義了一個叫做Foo的結構,里面有一個叫bar的field。隨后,我們創建了一個基于Foo結構體的slice,名字叫list

     2、我們還創建了一個基于Foo結構體指針類型的slice,叫做list2

     3、在一個for循環中,我們試圖遍歷list中的每一個元素,獲取其指針地址,并賦值到list2中index與之對應的位置。

     4、最后,分別輸出list與list2中的每個元素

從代碼來看,理所當然,我們期望得到的結果應該是這樣:

?
1
2
{A} {B} {C}
&{A} &{B} &{C}

但是結果卻出乎意料,程序的輸出是這樣的:

?
1
2
{A} {B} {C}
&{C} &{C} &{C}

從結果來看,仿佛list2中的三個元素,都指向了list中的最后一個元素。這是為什么呢?問題就出在上面那一段for…range循環中。

在Go的for…range循環中,Go始終使用值拷貝的方式代替被遍歷的元素本身,簡單來說,就是for…range中那個value,是一個值拷貝,而不是元素本身。這樣一來,當我們期望用&獲取元素的指針地址時,實際上只是取到了value這個臨時變量的指針地址,而非list中真正被遍歷到的某個元素的指針地址。而在整個for…range循環中,value這個臨時變量會被重復使用,所以,在上面的例子中,list2被填充了三個相同的指針地址,并且這三個地址都指向value,而在最后一次循環中,value被賦與了{c}的指針地址。因此,list2輸出的時候顯示出了三個&{c}

同樣的,下面的寫法,跟for…range的例子如出一轍:

?
1
2
3
4
5
var value Foo
for var i := 0; i < len(list); i++ {
 value = list[i]
 list2[i] = &value
}

如果我們輸出list2的三個元素,結果同樣是: &{C} &{C} &{C}

那么,怎樣才是正確的寫法呢?我們應該用index來訪問for…range中真實的元素,并獲取其指針地址:

?
1
2
3
for i, _ := range list {
 list2[i] = &list[i]
}

這樣,輸出list2中的元素,就能得到我們想要的結果(&{A} &{B} &{C})了。

實驗代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package main
 
import "fmt"
 
type Foo struct {
 bar string
}
 
func main() {
 list := []Foo{
 {"A"},
 {"B"},
 {"C"},
 }
 
 list2 := make([]*Foo, len(list))
 
 //錯誤的例子
 for i, value := range list {
 list2[i] = &value
 }
 
 //正確的例子
 //for i, _ := range list {
 // list2[i] = &list[i]
 //}
 
 fmt.Println(list[0], list[1], list[2])
 fmt.Println(list2[0], list2[1], list2[2])
}

了解了range的正確使用姿勢,那么我們下面這個例子也能迎刃而解了:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package main
import "fmt"
type MyType struct {
 field string
}
func main() {
 var array [10]MyType
 for _, e := range array {
 e.field = "foo"
 }
 for _, e := range array {
 fmt.Println(e.field)
 fmt.Println("--")
 }
}

平常寫代碼最常見的場景,就是我們需要在一個循環中修改被遍歷元素的值。比如上面這個例子,我們希望能使用for…range循環,一次性將array中每個元素的field設置為”foo”。同樣,因為range值拷貝的緣故,上面的程序什么都不會輸出……

而正確的做法是:

?
1
2
3
for i, _ := range array {
 array[i].field = "foo"
}

通過index訪問每個元素,并修改其field,這樣,就能輸出一堆”foo”了……

實驗代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package main
 
import "fmt"
 
type MyType struct {
 field string
}
 
func main() {
 var array [10]MyType
 
 for i, _ := range array {
 array[i].field = "foo"
 }
 
 for _, e := range array {
 fmt.Println(e.field)
 }
}

總結

以上就是關于Go語言中Range關鍵字的全部內容,這篇文章介紹的還是很詳細的,相信本文會對大家學習Go語言具有一定的參考價值,如果有疑問大家可以留言交流,小編會盡快給大家回復的,也請大家繼續支持服務器之家。

延伸 · 閱讀

精彩推薦
  • Golanggolang的httpserver優雅重啟方法詳解

    golang的httpserver優雅重啟方法詳解

    這篇文章主要給大家介紹了關于golang的httpserver優雅重啟的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,...

    helight2992020-05-14
  • GolangGolang中Bit數組的實現方式

    Golang中Bit數組的實現方式

    這篇文章主要介紹了Golang中Bit數組的實現方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧...

    天易獨尊11682021-06-09
  • GolangGolang通脈之數據類型詳情

    Golang通脈之數據類型詳情

    這篇文章主要介紹了Golang通脈之數據類型,在編程語言中標識符就是定義的具有某種意義的詞,比如變量名、常量名、函數名等等,Go語言中標識符允許由...

    4272021-11-24
  • Golanggolang 通過ssh代理連接mysql的操作

    golang 通過ssh代理連接mysql的操作

    這篇文章主要介紹了golang 通過ssh代理連接mysql的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧...

    a165861639710342021-03-08
  • Golanggolang json.Marshal 特殊html字符被轉義的解決方法

    golang json.Marshal 特殊html字符被轉義的解決方法

    今天小編就為大家分享一篇golang json.Marshal 特殊html字符被轉義的解決方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧 ...

    李浩的life12792020-05-27
  • Golanggolang如何使用struct的tag屬性的詳細介紹

    golang如何使用struct的tag屬性的詳細介紹

    這篇文章主要介紹了golang如何使用struct的tag屬性的詳細介紹,從例子說起,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看...

    Go語言中文網11352020-05-21
  • Golanggo語言制作端口掃描器

    go語言制作端口掃描器

    本文給大家分享的是使用go語言編寫的TCP端口掃描器,可以選擇IP范圍,掃描的端口,以及多線程,有需要的小伙伴可以參考下。 ...

    腳本之家3642020-04-25
  • Golanggo日志系統logrus顯示文件和行號的操作

    go日志系統logrus顯示文件和行號的操作

    這篇文章主要介紹了go日志系統logrus顯示文件和行號的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧...

    SmallQinYan12302021-02-02
主站蜘蛛池模板: 羞羞的视频免费观看 | 99最新地址 | 午夜视频亚洲 | 欧美一级色片 | 欧美日韩亚洲一区二区三区 | 久久精品视频首页 | 国产精品99精品 | 99国产精品欲a | 黄视频网站免费在线观看 | 国产成人在线看 | 免费观看9x视频网站在线观看 | 综合99| 欧美日韩免费看 | 最新中文字幕免费视频 | 欧美一级黄色免费 | 久久精品一二三区 | 久久不雅视频 | 美女污污在线观看 | 久久久久久久久久久av | 天天天干夜夜夜操 | 巨乳毛片| 中国漂亮护士一级a毛片 | 久久久久国产一区二区三区不卡 | 日本aⅴ在线 | 日本高清黄色片 | 久久精品亚洲成在人线av网址 | 91精品国产99久久久久久红楼 | 日本网站一区 | 色屁屁xxxxⅹ在线视频 | 久久久久国产精品久久久久 | 国产一区二区三区四 | 久久精品日产高清版的功能介绍 | 最近国产中文字幕 | 黄色一级视频 | 国产精品性夜天天视频 | 色骚综合 | 久久经典国产视频 | 国产一区二区在线免费观看 | 中文字幕国产欧美 | 精品一区二区三区毛片 | 999久久久免费视频 久久精品国产精品亚洲 |