欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Go基礎(chǔ)系列:Go切片(分片)slice詳解

 更新時(shí)間:2022年04月16日 16:23:56   作者:駿馬金龍  
這篇文章主要介紹了Go語(yǔ)言中的切片(分片)slice詳細(xì)說(shuō)明?,需要的朋友可以參考下

slice表示切片(分片),例如對(duì)一個(gè)數(shù)組進(jìn)行切片,取出數(shù)組中的一部分值。在現(xiàn)代編程語(yǔ)言中,slice(切片)幾乎成為一種必備特性,它可以從一個(gè)數(shù)組(列表)中取出任意長(zhǎng)度的子數(shù)組(列表),為操作數(shù)據(jù)結(jié)構(gòu)帶來(lái)非常大的便利性,如python、perl等都支持對(duì)數(shù)組的slice操作,甚至perl還支持對(duì)hash數(shù)據(jù)結(jié)構(gòu)的slice。

但Go中的slice和這些語(yǔ)言的slice不太一樣,前面所說(shuō)的語(yǔ)言中,slice是一種切片的操作,切片后返回一個(gè)新的數(shù)據(jù)對(duì)象。而Go中的slice不僅僅是一種切片動(dòng)作,還是一種數(shù)據(jù)結(jié)構(gòu)(就像數(shù)組一樣)。

slice的存儲(chǔ)結(jié)構(gòu)

Go中的slice依賴(lài)于數(shù)組,它的底層就是數(shù)組,所以數(shù)組具有的優(yōu)點(diǎn),slice都有。且slice支持可以通過(guò)append向slice中追加元素,長(zhǎng)度不夠時(shí)會(huì)動(dòng)態(tài)擴(kuò)展,通過(guò)再次slice切片,可以得到得到更小的slice結(jié)構(gòu),可以迭代、遍歷等。

實(shí)際上slice是這樣的結(jié)構(gòu):先創(chuàng)建一個(gè)有特定長(zhǎng)度和數(shù)據(jù)類(lèi)型的底層數(shù)組,然后從這個(gè)底層數(shù)組中選取一部分元素,返回這些元素組成的集合(或容器),并將slice指向集合中的第一個(gè)元素。換句話(huà)說(shuō),slice自身維護(hù)了一個(gè)指針屬性,指向它底層數(shù)組中的某些元素的集合。

例如,初始化一個(gè)slice數(shù)據(jù)結(jié)構(gòu):

my_slice := make([]int, 3,5)

// 輸出slice
fmt.Println(my_slice)    // 輸出:[0 0 0]

這表示先聲明一個(gè)長(zhǎng)度為5、數(shù)據(jù)類(lèi)型為int的底層數(shù)組,然后從這個(gè)底層數(shù)組中從前向后取3個(gè)元素(即index從0到2)作為slice的結(jié)構(gòu)。

如下圖:

每一個(gè)slice結(jié)構(gòu)都由3部分組成:容量(capacity)、長(zhǎng)度(length)和指向底層數(shù)組某元素的指針,它們各占8字節(jié)(1個(gè)機(jī)器字長(zhǎng),64位機(jī)器上一個(gè)機(jī)器字長(zhǎng)為64bit,共8字節(jié)大小,32位架構(gòu)則是32bit,占用4字節(jié)),所以任何一個(gè)slice都是24字節(jié)(3個(gè)機(jī)器字長(zhǎng))。

  • Pointer:表示該slice結(jié)構(gòu)從底層數(shù)組的哪一個(gè)元素開(kāi)始,該指針指向該元素
  • Capacity:即底層數(shù)組的長(zhǎng)度,表示這個(gè)slice目前最多能擴(kuò)展到這么長(zhǎng)
  • Length:表示slice當(dāng)前的長(zhǎng)度,如果追加元素,長(zhǎng)度不夠時(shí)會(huì)擴(kuò)展,最大擴(kuò)展到Capacity的長(zhǎng)度(不完全準(zhǔn)確,后面數(shù)組自動(dòng)擴(kuò)展時(shí)解釋),所以L(fǎng)ength必須不能比Capacity更大,否則會(huì)報(bào)錯(cuò)

對(duì)上面創(chuàng)建的slice來(lái)說(shuō),它的長(zhǎng)度為3,容量為5,指針指向底層數(shù)組的index=0。

可以通過(guò)len()函數(shù)獲取slice的長(zhǎng)度,通過(guò)cap()函數(shù)獲取slice的Capacity。

my_slice := make([]int,3,5)

fmt.Println(len(my_slice))  // 3
fmt.Println(cap(my_slice))  // 5

還可以直接通過(guò)print()或println()函數(shù)去輸出slice,它將得到這個(gè)slice結(jié)構(gòu)的屬性值,也就是length、capacity和pointer:

my_slice := make([]int,3,5)
println(my_slice)      // [3/5]0xc42003df10

[3/5]表示length和capacity,0xc42003df10表示指向的底層數(shù)組元素的指針。

務(wù)必記住slice的本質(zhì)是[x/y]0xADDR,記住它將在很多地方有助于理解slice的特性。另外,個(gè)人建議,雖然slice的本質(zhì)不是指針,但仍然可以將它看作是一種包含了另外兩種屬性的不純粹的指針,也就是說(shuō),直接認(rèn)為它是指針。其實(shí)不僅slice如此,map也如此。

創(chuàng)建、初始化、訪(fǎng)問(wèn)slice

有幾種創(chuàng)建slice數(shù)據(jù)結(jié)構(gòu)的方式。

一種是使用make():

// 創(chuàng)建一個(gè)length和capacity都等于5的slice
slice := make([]int,5)

// length=3,capacity=5的slice
slice := make([]int,3,5)

make()比new()函數(shù)多一些操作,new()函數(shù)只會(huì)進(jìn)行內(nèi)存分配并做默認(rèn)的賦0初始化,而make()可以先為底層數(shù)組分配好內(nèi)存,然后從這個(gè)底層數(shù)組中再額外生成一個(gè)slice并初始化。另外,make只能構(gòu)建slice、map和channel這3種結(jié)構(gòu)的數(shù)據(jù)對(duì)象,因?yàn)樗鼈兌贾赶虻讓訑?shù)據(jù)結(jié)構(gòu),都需要先為底層數(shù)據(jù)結(jié)構(gòu)分配好內(nèi)存并初始化。

還可以直接賦值初始化的方式創(chuàng)建slice:

// 創(chuàng)建長(zhǎng)度和容量都為4的slice,并初始化賦值
color_slice := []string{"red","blue","black","green"}

// 創(chuàng)建長(zhǎng)度和容量為100的slice,并為第100個(gè)元素賦值為3
slice := []int{99:3}

注意區(qū)分array和slice:

// 創(chuàng)建長(zhǎng)度為3的int數(shù)組
array := [3]int{10, 20, 30}

// 創(chuàng)建長(zhǎng)度和容量都為3的slice
slice := []int{10, 20, 30}

由于slice底層是數(shù)組,所以可以使用索引的方式訪(fǎng)問(wèn)slice,或修改slice中元素的值:

// 創(chuàng)建長(zhǎng)度為5、容量為5的slice
my_slice := []int{11,22,33,44,55}

// 訪(fǎng)問(wèn)slice的第2個(gè)元素
print(my_slice[1])

// 修改slice的第3個(gè)元素的值
my_slice[2] = 333

由于slice的底層是數(shù)組,所以訪(fǎng)問(wèn)my_slice[1]實(shí)際上是在訪(fǎng)問(wèn)它的底層數(shù)組的對(duì)應(yīng)元素。slice能被訪(fǎng)問(wèn)的元素只有l(wèi)ength范圍內(nèi)的元素,那些在length之外,但在capacity之內(nèi)的元素暫時(shí)還不屬于slice,只有在slice被擴(kuò)展時(shí)(見(jiàn)下文append),capacity中的元素才被納入length,才能被訪(fǎng)問(wèn)。

nil slice和空slice

當(dāng)聲明一個(gè)slice,但不做初始化的時(shí)候,這個(gè)slice就是一個(gè)nil slice。

// 聲明一個(gè)nil slice
var nil_slice []int

nil slice表示它的指針為nil,也就是這個(gè)slice不會(huì)指向哪個(gè)底層數(shù)組。也因此,nil slice的長(zhǎng)度和容量都為0。

|--------|---------|----------|
|  nil   |   0     |     0    |
|  ptr   | Length  | Capacity |
|--------|---------|----------|

還可以創(chuàng)建空slice(Empty Slice),空slice表示長(zhǎng)度為0,容量為0,但卻有指向的slice,只不過(guò)指向的底層數(shù)組暫時(shí)是長(zhǎng)度為0的空數(shù)組。

// 使用make創(chuàng)建
empty_slice := make([]int,0)

// 直接創(chuàng)建
empty_slice := []int{}

Empty Slice的結(jié)構(gòu)如下:

|--------|---------|----------|
|  ADDR  |   0     |     0    |
|  ptr   | Length  | Capacity |
|--------|---------|----------|

雖然nil slice和Empty slice的長(zhǎng)度和容量都為0,輸出時(shí)的結(jié)果都是[],且都不存儲(chǔ)任何數(shù)據(jù),但它們是不同的。nil slice不會(huì)指向底層數(shù)組,而空slice會(huì)指向底層數(shù)組,只不過(guò)這個(gè)底層數(shù)組暫時(shí)是空數(shù)組。

可以使用println()來(lái)輸出驗(yàn)證:

package main

func main() {
    var nil_s []int
    empty_s:= []int{}
    println(nil_s)
    println(empty_s)
}

輸出結(jié)果:

[0/0]0x0
[0/0]0xc042085f50

當(dāng)然,無(wú)論是nil slice還是empty slice,都可以對(duì)它們進(jìn)行操作,如append()函數(shù)、len()函數(shù)和cap()函數(shù)。

對(duì)slice進(jìn)行切片

可以從slice中繼續(xù)切片生成一個(gè)新的slice,這樣能實(shí)現(xiàn)slice的縮減。

對(duì)slice切片的語(yǔ)法為:

SLICE[A:B]
SLICE[A:B:C]

其中A表示從SLICE的第幾個(gè)元素開(kāi)始切,B控制切片的長(zhǎng)度(B-A),C控制切片的容量(C-A),如果沒(méi)有給定C,則表示切到底層數(shù)組的最尾部。

還有幾種簡(jiǎn)化形式:

SLICE[A:]  // 從A切到最尾部
SLICE[:B]  // 從最開(kāi)頭切到B(不包含B)
SLICE[:]   // 從頭切到尾,等價(jià)于復(fù)制整個(gè)SLICE

例如:

my_slice := []int{11,22,33,44,55}

// 生成新的slice,從第二個(gè)元素取,切取的長(zhǎng)度為2
new_slice := my_slice[1:3]

注意,截取時(shí)"左閉右開(kāi)"。所以上面new_slice是從my_slice的index=1開(kāi)始截取,截取到index=3為止,但不包括index=3這個(gè)元素。所以,新的slice是由my_slice中的第2個(gè)元素、第3個(gè)元素組成的新的數(shù)據(jù)結(jié)構(gòu),長(zhǎng)度為2。

以下是slice切片生成新的slice后的結(jié)構(gòu):

不難發(fā)現(xiàn),一個(gè)底層數(shù)組,可以生成無(wú)數(shù)個(gè)slice,且對(duì)于new_slice而言,它并不知道底層數(shù)組index=0的那個(gè)元素。

還可以控制切片時(shí)新slice的容量:

my_slice := []int{11,22,33,44,55}

// 從第二個(gè)元素取,切取的長(zhǎng)度為2,容量也為2
new_slice := my_slice[1:3:3]

這時(shí)新slice的length等于capacity,底層數(shù)組的index=4、5將對(duì)new_slice永不可見(jiàn),即使后面對(duì)new_slice進(jìn)行append()導(dǎo)致底層數(shù)組擴(kuò)容也仍然不可見(jiàn)。具體見(jiàn)下文。

由于多個(gè)slice共享同一個(gè)底層數(shù)組,所以當(dāng)修改了某個(gè)slice中的元素時(shí),其它包含該元素的slice也會(huì)隨之改變,因?yàn)閟lice只是一個(gè)指向底層數(shù)組的指針(只不過(guò)這個(gè)指針不純粹,多了兩個(gè)額外的屬性length和capacity),實(shí)際上修改的是底層數(shù)組的值,而底層數(shù)組是被共享的。

當(dāng)同一個(gè)底層數(shù)組有很多slice的時(shí)候,一切將變得混亂不堪,因?yàn)槲覀儾豢赡苡涀≌l(shuí)在共享它,通過(guò)修改某個(gè)slice的元素時(shí),將也會(huì)影響那些可能我們不想影響的slice。所以,需要一種特性,保證各個(gè)slice的底層數(shù)組互不影響,相關(guān)內(nèi)容見(jiàn)下面的"擴(kuò)容"。

copy()函數(shù)

可以將一個(gè)slice拷貝到另一個(gè)slice中。

$ go doc builtin copy
func copy(dst, src []Type) int

這表示將src slice拷貝到dst slice,src比dst長(zhǎng),就截?cái)啵瑂rc比dst短,則只拷貝src那部分。

copy的返回值是拷貝成功的元素?cái)?shù)量,所以也就是src slice或dst slice中最小的那個(gè)長(zhǎng)度。

例如:

s1 := []int{11, 22, 33}
s2 := make([]int, 5)
s3 := make([]int,2)

num := copy(s2, s1)
copy(s3,s1)

fmt.Println(num)   // 3
fmt.Println(s2)    // [11,22,33,0,0]
fmt.Println(s3)    // [11,22]

此外,copy還能將字符串拷貝到byte slice中,因?yàn)樽址畬?shí)際上就是[]byte。

func main() {
	s1 := []byte("Hello")
	num := copy(s1, "World")
	fmt.Println(num)
	fmt.Println(s1)    // 輸出[87 111 114 108 100 32]
	fmt.Println(string(s1))  //輸出"World"
}

append()函數(shù)

可以使用append()函數(shù)對(duì)slice進(jìn)行擴(kuò)展,因?yàn)樗芳釉氐絪lice中,所以一定會(huì)增加slice的長(zhǎng)度。

但必須注意,append()的結(jié)果必須被使用。所謂被使用,可以將其輸出、可以賦值給某個(gè)slice。如果將append()放在空上下文將會(huì)報(bào)錯(cuò):append()已評(píng)估,但未使用。同時(shí)這也說(shuō)明,append()返回一個(gè)新的slice,原始的slice會(huì)保留不變。

例如:

my_slice := []int{11,22,33,44,55}
new_slice := my_slice[1:3]

// append()追加一個(gè)元素2323,返回新的slice
app_slice := append(new_slice,2323)

上面的append()在new_slice的后面增加了一個(gè)元素2323,所以app_slice[2]=2323。但因?yàn)檫@些slice共享同一個(gè)底層數(shù)組,所以2323也會(huì)反映到其它slice中。

現(xiàn)在的數(shù)據(jù)結(jié)構(gòu)圖如下:

當(dāng)然,如果append()的結(jié)果重新賦值給new_slice,則new_slice會(huì)增加長(zhǎng)度。

同樣,由于string的本質(zhì)是[]byte,所以string可以append到byte slice中:

s1 := []byte("Hello")
s2 := append(s1, "World"...)
fmt.Println(string(s2))   // 輸出:HelloWorld

擴(kuò)容

當(dāng)slice的length已經(jīng)等于capacity的時(shí)候,再使用append()給slice追加元素,會(huì)自動(dòng)擴(kuò)展底層數(shù)組的長(zhǎng)度。

底層數(shù)組擴(kuò)展時(shí),會(huì)生成一個(gè)新的底層數(shù)組。所以舊底層數(shù)組仍然會(huì)被舊slice引用,新slice和舊slice不再共享同一個(gè)底層數(shù)組

func main() {
    my_slice := []int{11,22,33,44,55}
    new_slice := append(my_slice,66)

    my_slice[3] = 444   // 修改舊的底層數(shù)組

    fmt.Println(my_slice)   // [11 22 33 444 55]
    fmt.Println(new_slice)  // [11 22 33 44 55 66]

    fmt.Println(len(my_slice),":",cap(my_slice))     // 5:5
    fmt.Println(len(new_slice),":",cap(new_slice))   // 6:10
}

從上面的結(jié)果上可以發(fā)現(xiàn),底層數(shù)組被擴(kuò)容為10,且是新的底層數(shù)組。

實(shí)際上,當(dāng)?shù)讓訑?shù)組需要擴(kuò)容時(shí),會(huì)按照當(dāng)前底層數(shù)組長(zhǎng)度的2倍進(jìn)行擴(kuò)容,并生成新數(shù)組。如果底層數(shù)組的長(zhǎng)度超過(guò)1000時(shí),將按照25%的比率擴(kuò)容,也就是1000個(gè)元素時(shí),將擴(kuò)展為1250個(gè),不過(guò)這個(gè)增長(zhǎng)比率的算法可能會(huì)隨著go版本的遞進(jìn)而改變。

實(shí)際上,上面的說(shuō)法應(yīng)該改一改:當(dāng)capacity需要擴(kuò)容時(shí),會(huì)按照當(dāng)前capacity的2倍對(duì)數(shù)組進(jìn)行擴(kuò)容?;蛘哒f(shuō),是按照slice的本質(zhì)[x/y]0xADDR的容量y來(lái)判斷如何擴(kuò)容的。之所以要特別強(qiáng)調(diào)這兩種不同,是因?yàn)楹苋菀赘慊臁?/p>

例如,擴(kuò)容的對(duì)象是底層數(shù)組的真子集時(shí):

my_slice := []int{11,22,33,44,55}

// 限定長(zhǎng)度和容量,且讓長(zhǎng)度和容量相等
new_slice := my_slice[1:3:3]   // [22 33]

// 擴(kuò)容
app_slice := append(new_slice,4444)

上面的new_slice的容量為2,并沒(méi)有對(duì)應(yīng)到底層數(shù)組的最結(jié)尾,所以new_slicemy_slice的一個(gè)真子集。這時(shí)對(duì)new_slice擴(kuò)容,將生成一個(gè)新的底層數(shù)組,新的底層數(shù)組容量為4,而不是10。如下圖:

因?yàn)閯?chuàng)建了新的底層數(shù)組,所以修改不同的slice,將不會(huì)互相影響。為了保證每次都是修改各自的底層數(shù)組,通常會(huì)切出僅一個(gè)長(zhǎng)度、僅一個(gè)容量的新slice,這樣只要對(duì)它進(jìn)行任何一次擴(kuò)容,就會(huì)生成一個(gè)新的底層數(shù)組,從而讓每個(gè)slice的底層數(shù)組都獨(dú)立

my_slice := []int{11,22,33,44,55}

new_slice := my_slice[2:3:3]
app_slice := append(new_slice,3333)

事實(shí)上,這還是會(huì)出現(xiàn)共享的幾率,因?yàn)闆](méi)有擴(kuò)容時(shí),那個(gè)唯一的元素仍然是共享的,修改它肯定會(huì)影響至少1個(gè)slice,只有切出長(zhǎng)度為0,容量為0的slice,才能完全保證獨(dú)立性,但這和新創(chuàng)建一個(gè)slice沒(méi)有區(qū)別。

合并slice

slice和數(shù)組其實(shí)一樣,都是一種值,可以將一個(gè)slice和另一個(gè)slice進(jìn)行合并,生成一個(gè)新的slice。

合并slice時(shí),只需將append()的第二個(gè)參數(shù)后加上...即可,即append(s1,s2...)表示將s2合并在s1的后面,并返回新的slice。

s1 := []int{1,2}
s2 := []int{3,4}

s3 := append(s1,s2...)

fmt.Println(s3)  // [1 2 3 4]

注意append()最多允許兩個(gè)參數(shù),所以一次性只能合并兩個(gè)slice。但可以取巧,將append()作為另一個(gè)append()的參數(shù),從而實(shí)現(xiàn)多級(jí)合并。例如,下面的合并s1和s2,然后再和s3合并,得到s1+s2+s3合并后的結(jié)果。

sn := append(append(s1,s2...),s3...)

slice遍歷迭代

slice是一個(gè)集合,所以可以進(jìn)行迭代。

range關(guān)鍵字可以對(duì)slice進(jìn)行迭代,每次返回一個(gè)index和對(duì)應(yīng)的元素值。可以將range的迭代結(jié)合for循環(huán)對(duì)slice進(jìn)行遍歷。

package main

func main() {
    s1 := []int{11,22,33,44}
    for index,value := range s1 {
        println("index:",index," , ","value",value)
    }
}

輸出結(jié)果:

index: 0  ,  value 11
index: 1  ,  value 22
index: 2  ,  value 33
index: 3  ,  value 44

傳遞slice給函數(shù)

前面說(shuō)過(guò),雖然slice實(shí)際上包含了3個(gè)屬性,它的數(shù)據(jù)結(jié)構(gòu)類(lèi)似于[3/5]0xc42003df10,但仍可以將slice看作一種指針。這個(gè)特性直接體現(xiàn)在函數(shù)參數(shù)傳值上。

Go中函數(shù)的參數(shù)是按值傳遞的,所以調(diào)用函數(shù)時(shí)會(huì)復(fù)制一個(gè)參數(shù)的副本傳遞給函數(shù)。如果傳遞給函數(shù)的是slice,它將復(fù)制該slice副本給函數(shù),這個(gè)副本實(shí)際上就是[3/5]0xc42003df10,所以傳遞給函數(shù)的副本仍然指向源slice的底層數(shù)組。

換句話(huà)說(shuō),如果函數(shù)內(nèi)部對(duì)slice進(jìn)行了修改,有可能會(huì)直接影響函數(shù)外部的底層數(shù)組,從而影響其它slice。但并不總是如此,例如函數(shù)內(nèi)部對(duì)slice進(jìn)行擴(kuò)容,擴(kuò)容時(shí)生成了一個(gè)新的底層數(shù)組,函數(shù)后續(xù)的代碼只對(duì)新的底層數(shù)組操作,這樣就不會(huì)影響原始的底層數(shù)組。

例如:

package main

import "fmt"

func main() {
    s1 := []int{11, 22, 33, 44}
    foo(s1)
    fmt.Println(s1[1])     // 輸出:23
}

func foo(s []int) {
    for index, _ := range s {
        s[index] += 1
    }
}

上面將輸出23,因?yàn)閒oo()直接操作原始的底層數(shù)組,對(duì)slice的每個(gè)元素都加1。

slice和內(nèi)存浪費(fèi)問(wèn)題

由于slice的底層是數(shù)組,很可能數(shù)組很大,但slice所取的元素?cái)?shù)量卻很小,這就導(dǎo)致數(shù)組占用的絕大多數(shù)空間是被浪費(fèi)的。

特別地,垃圾回收器(GC)不會(huì)回收正在被引用的對(duì)象,當(dāng)一個(gè)函數(shù)直接返回指向底層數(shù)組的slice時(shí),這個(gè)底層數(shù)組將不會(huì)隨函數(shù)退出而被回收,而是因?yàn)閟lice的引用而永遠(yuǎn)保留,除非返回的slice也消失。

因此,當(dāng)函數(shù)的返回值是一個(gè)指向底層數(shù)組的數(shù)據(jù)結(jié)構(gòu)時(shí)(如slice),應(yīng)當(dāng)在函數(shù)內(nèi)部將slice拷貝一份保存到一個(gè)使用自己底層數(shù)組的新slice中,并返回這個(gè)新的slice。這樣函數(shù)一退出,原來(lái)那個(gè)體積較大的底層數(shù)組就會(huì)被回收,保留在內(nèi)存中的是小的slice。

更多關(guān)于Go語(yǔ)言切片(分片)slice的技術(shù)文章請(qǐng)查看下面的相關(guān)鏈接

相關(guān)文章

  • Go語(yǔ)言中序列化與反序列化示例詳解

    Go語(yǔ)言中序列化與反序列化示例詳解

    我們的數(shù)據(jù)對(duì)象要在網(wǎng)絡(luò)中傳輸或保存到文件,就需要對(duì)其編碼和解碼動(dòng)作,Go語(yǔ)言當(dāng)然也支持所有這些編碼格式,下面這篇文章主要給大家介紹了關(guān)于Go語(yǔ)言中序列化與反序列化的相關(guān)資料,需要的朋友可以參考下
    2022-07-07
  • go語(yǔ)言 全局變量和局部變量實(shí)例

    go語(yǔ)言 全局變量和局部變量實(shí)例

    這篇文章主要介紹了go語(yǔ)言 全局變量和局部變量實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-12-12
  • goland 搭建 gin 框架的步驟詳解

    goland 搭建 gin 框架的步驟詳解

    這篇文章主要介紹了goland 搭建 gin 框架的相關(guān)知識(shí),本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-11-11
  • Golang實(shí)現(xiàn)按比例切分流量的示例詳解

    Golang實(shí)現(xiàn)按比例切分流量的示例詳解

    我們?cè)谶M(jìn)行灰度發(fā)布時(shí),往往需要轉(zhuǎn)發(fā)一部分流量到新上線(xiàn)的服務(wù)上,進(jìn)行小規(guī)模的驗(yàn)證,隨著功能的不斷完善,我們也會(huì)逐漸增加轉(zhuǎn)發(fā)的流量,這就需要按比例去切分流量,那么如何實(shí)現(xiàn)流量切分呢,接下來(lái)小編就給大家詳細(xì)的介紹一下實(shí)現(xiàn)方法,需要的朋友可以參考下
    2023-09-09
  • 一文帶你掌握Go語(yǔ)言并發(fā)模式中的Context的上下文管理

    一文帶你掌握Go語(yǔ)言并發(fā)模式中的Context的上下文管理

    在?Go?的日常開(kāi)發(fā)中,Context?上下文對(duì)象無(wú)處不在,無(wú)論是處理網(wǎng)絡(luò)請(qǐng)求、數(shù)據(jù)庫(kù)操作還是調(diào)用?RPC?等場(chǎng)景,那你真的熟悉它的正確用法嗎,隨著本文一探究竟吧
    2023-05-05
  • golang gin 監(jiān)聽(tīng)rabbitmq隊(duì)列無(wú)限消費(fèi)的案例代碼

    golang gin 監(jiān)聽(tīng)rabbitmq隊(duì)列無(wú)限消費(fèi)的案例代碼

    這篇文章主要介紹了golang gin 監(jiān)聽(tīng)rabbitmq隊(duì)列無(wú)限消費(fèi),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-12-12
  • golang gin 框架 異步同步 goroutine 并發(fā)操作

    golang gin 框架 異步同步 goroutine 并發(fā)操作

    這篇文章主要介紹了golang gin 框架 異步同步 goroutine 并發(fā)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-12-12
  • Golang flag包的具體使用

    Golang flag包的具體使用

    本文主要介紹了Golang flag包的具體使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • 使用Go?http重試請(qǐng)求的示例

    使用Go?http重試請(qǐng)求的示例

    開(kāi)發(fā)中對(duì)于http請(qǐng)求是經(jīng)常遇到,一般可能網(wǎng)絡(luò)延遲或接口返回超時(shí),這篇文章主要介紹了使用Go?http重試請(qǐng)求的示例,需要的朋友可以參考下
    2022-08-08
  • 實(shí)現(xiàn)像php一樣方便的go ORM數(shù)據(jù)庫(kù)操作示例詳解

    實(shí)現(xiàn)像php一樣方便的go ORM數(shù)據(jù)庫(kù)操作示例詳解

    這篇文章主要為大家介紹了實(shí)現(xiàn)像php一樣方便的go ORM數(shù)據(jù)庫(kù)操作示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12

最新評(píng)論