日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
一篇文章帶你了解Go語(yǔ)言基礎(chǔ)之切片補(bǔ)充

前言

make疑云

我們知道,可以通過(guò)make創(chuàng)建切片。

var names = make([]string,10,10)

這句話表示動(dòng)態(tài)創(chuàng)建了一個(gè)切片,切片中的元素?cái)?shù)量為10個(gè),切片的容量也為10個(gè)。

你有疑惑嗎???

切片的數(shù)量和容量是什么???

他倆什么關(guān)系???

切片本質(zhì)

其實(shí)切片,終究是一個(gè)存儲(chǔ)數(shù)據(jù)的一個(gè)東西,目前知道數(shù)組是可以存儲(chǔ)東西的。

其實(shí)切片的本質(zhì),還是數(shù)組,只不過(guò)是Go幫助我們做了一些封裝,可以方便的對(duì)切片里面的數(shù)據(jù)增刪改查。

例如:

package main

import "fmt"

func main() {
var names = make([]int, 4, 10)
//int類型默認(rèn)值是0
fmt.Println(names, len(names), cap(names)) //結(jié)果:[0 0 0 0] 4 10
}

理解圖。

沒(méi)錯(cuò),本質(zhì)就是指向了一個(gè)長(zhǎng)一點(diǎn)的數(shù)組。

但是這個(gè)數(shù)組是會(huì)自動(dòng)擴(kuò)容的,當(dāng)容量(cap)append滿了之后,會(huì)自動(dòng)擴(kuò)容。

現(xiàn)在,我們就知道m(xù)ake里面參數(shù)的意義了。

注意:在Go中,推薦使用make創(chuàng)建切片,并且在創(chuàng)建時(shí),需要考慮容量,盡可能不觸發(fā)容量自動(dòng)擴(kuò)容機(jī)制,提高性能。

為什么切片append之后,前面會(huì)有空格

在上一章中,大概有這樣一段代碼。


package main

import "fmt"

func main() {
var names = make([]int,5,10)
names = append(names,11,23,231)
fmt.Println(names)//[0 0 0 0 0 11 23 231]
}

append之后,前面會(huì)有很多0,這是怎么回事。

解釋:

在通過(guò)make創(chuàng)建切片時(shí),第二個(gè)參數(shù)是切片元素的數(shù)量。

上述代碼切片第二個(gè)參數(shù)是5,表示在創(chuàng)建切片時(shí),前5個(gè)就已經(jīng)有值了,只不過(guò)是int默認(rèn)值0。

所以再append時(shí),是再原有的基礎(chǔ)上,添加值的,直到cap滿了之后,觸發(fā)擴(kuò)容機(jī)制。

如圖所示。

現(xiàn)在,清晰了吧?

那怎么append時(shí),從0開(kāi)始呢???

這不是很簡(jiǎn)單,直接讓第二個(gè)參數(shù)為0。

var names = make([]int,0,10)
//結(jié)果:[11 23 231]

如圖所示。

好了,這個(gè),懂了吧,怎么繼續(xù)哈。

為什么不推薦使用var []類型方式創(chuàng)建切片

我們上述一直在提一個(gè)詞,自動(dòng)擴(kuò)容。

我們來(lái)看這樣一段普通的代碼。

package main

import "fmt"

func main() {
var names []int
//地址:0x0,長(zhǎng)度(len):0,容量(cap):0
fmt.Printf("地址:%p,長(zhǎng)度(len):%d,容量(cap):%d\n", names, len(names), cap(names))
names = append(names, 1, 2, 3)

//地址:0xc000010380,長(zhǎng)度(len):3,容量(cap):4
fmt.Printf("地址:%p,長(zhǎng)度(len):%d,容量(cap):%d\n", names, len(names), cap(names))
}

雖然按照這種方法,使用append動(dòng)態(tài)添加是沒(méi)問(wèn)題的。

在不使用make聲明數(shù)組時(shí),len和cap都是0,并且地址也是一個(gè)值。

通過(guò)append之后,可以明顯看到,地址發(fā)生了改變,因?yàn)橛种匦律暾?qǐng)了數(shù)組,切片重新指向新的數(shù)組。

len和cap也發(fā)生了變化。

copy復(fù)制切片

package main

import "fmt"

func main() {
var names1 = make([]string, 0, 10)
names1 = append(names1, "張三")
names1 = append(names1, "李四")
var names2 = names1 //將names1賦值到names2
fmt.Println(names1, names2) //[張三 李四] [張三 李四]
names1[0] = "張三666"http://修改names下標(biāo)為0的值為 張三666
fmt.Println(names1, names2) //[張三666 李四] [張三666 李四]
//為什么修改names1的值,會(huì)影響names2的值????
}

為什么修改names1的值,會(huì)影響names2的值???

這個(gè),就又要回到內(nèi)存分布圖了,如圖所示。

我們說(shuō)過(guò)很多次,不管是打印,還是賦值等操作,只會(huì)操作棧上面存儲(chǔ)的值。

當(dāng)names2=names1時(shí),只會(huì)把names1棧上面的地址,給names2。

但是存的時(shí)堆上面的地址,終究還是指向了同一個(gè)堆。

所以修改names1時(shí),names2也修改了。

那如果不想出現(xiàn)上述問(wèn)題怎么辦???

解決辦法:使用copy

package main

import "fmt"

func main() {
var names1 = make([]string, 0, 10)
names1 = append(names1, "張三")
names1 = append(names1, "李四")
//定義一個(gè)names2切片用于接收,第二個(gè)參數(shù)要留空間,names1里面又幾個(gè)元素,names2第二個(gè)參數(shù)也要是幾
var names2 = make([]string, 2, 10)
copy(names2, names1)//將names1的值,賦值到names2
fmt.Println(names1, names2) //[張三 李四] [張三 李四]
names1[0] = "張三666"http://修改names下標(biāo)為0的值為 張三666
fmt.Println(names1, names2) //[張三666 李四] [張三 李四]
fmt.Printf("names1地址:%p names2地址:%p\n",names1,names2)
//names1地址:0xc00009a0a0 names2地址:0xc00009a140
}

內(nèi)存圖:

自動(dòng)擴(kuò)容機(jī)制

非常抱歉,我不會(huì) 。。。

總結(jié)

上述我們學(xué)習(xí)了Go基礎(chǔ)之切片補(bǔ)充。如果在操作過(guò)程中有任務(wù)問(wèn)題,記得在下面的討論區(qū)留言,我們看到會(huì)第一時(shí)間解決問(wèn)題。


本文標(biāo)題:一篇文章帶你了解Go語(yǔ)言基礎(chǔ)之切片補(bǔ)充
文章分享:http://m.5511xx.com/article/cdjdgce.html