Golang學(xué)習(xí)筆記(四):array、slice、map
一.Array
在Go語(yǔ)言中,數(shù)組是一個(gè)值類(lèi)型(value type)
所有的值類(lèi)型變量在賦值和作為參數(shù)傳遞時(shí)都將產(chǎn)生一個(gè)復(fù)制動(dòng)作
如果作為函數(shù)的參數(shù)類(lèi)型,則在函數(shù)調(diào)用時(shí)參數(shù)發(fā)生數(shù)據(jù)復(fù)制,在函數(shù)體中無(wú)法修改傳入數(shù)組的內(nèi)容
數(shù)組相等用 = != 比較,不能用 < >
1.聲明&賦值
初始化
語(yǔ)法
var VarName [n]type // n>=0
e.g.
var a [5]int //[0 0 0 0 0]
var c [2][3]int //二維
var b int = [5]int{1,2,3,4,5} //聲明并初始化
a := [3]int{1,2,3}
b := [10]int{1,2,3} //前三個(gè)元素,其他為0
c := [20]int{19:1} //第20個(gè)元素初始化為1,其他默認(rèn)0
d := [...]int{4,5,6} //自動(dòng)計(jì)算長(zhǎng)度
e := [...]int{0:1, 1:2, 19:3} //自動(dòng)推斷
二維數(shù)組
doubleArray := [2][4]int{[4]int{1,2,3,4}, [4]int{5,6,7,8}}
easyArray := [2][4]int{{1,2,3,4}, {1,2,3,4}}
多維 [...][n] 前者可推斷,但是后者必須顯示賦值
數(shù)組的長(zhǎng)度是該數(shù)組類(lèi)型的一個(gè)內(nèi)置常量
arrLength := len(arr)
注意,數(shù)組長(zhǎng)度也是類(lèi)型的一部分,因此不同長(zhǎng)度數(shù)組為不同類(lèi)型(內(nèi)置常量)
即[3]int和[4]int是不同類(lèi)型,并且數(shù)組不能改變長(zhǎng)度
數(shù)組之間的賦值是值的賦值,即當(dāng)把一個(gè)數(shù)組作為參數(shù)傳入函數(shù)的時(shí)候,傳入的其實(shí)是該數(shù)組的副本(一次復(fù)制操作),而不是它的指針,如果要傳入指針,使用slice
2.元素訪問(wèn)
for i:=0; i < len(array); i++ {
fmt.Println(i, array[i])
}
for i, v := range array {
fmt.Println(i, v)
}
可以用new創(chuàng)建數(shù)組
p := new([10]int)
返回一個(gè)指向數(shù)組的指針
注意區(qū)分
指向數(shù)組的指針
a := [100]int{}
var p *[100]int = &a
指針數(shù)組
x, y = 1, 2
a := [...]*int{&x, &y}
二.Slice
數(shù)組切片就像一個(gè)指向數(shù)組的指針,但更復(fù)雜,實(shí)際上它擁有自己的數(shù)據(jù)結(jié)構(gòu),而不僅僅是指針(指向原生數(shù)組的指針 + 數(shù)組切片中元素個(gè)數(shù) + 數(shù)組切片已分配的存儲(chǔ)空間)
一個(gè)引用類(lèi)型,總是指向一個(gè)底層array,聲明可以向array一樣,只是不需要長(zhǎng)度
slice就像一個(gè)結(jié)構(gòu)體,包含三個(gè)元素
一個(gè)指針,指向數(shù)組中slice指定的開(kāi)始位置
長(zhǎng)度,即slice的長(zhǎng)度
最大長(zhǎng)度,也就是slice開(kāi)始位置到數(shù)組的最后位置的長(zhǎng)度
1.聲明&賦值
通過(guò)array創(chuàng)建
var myArray [10]int = [10]int{1,2,3,4,5,6,7,8,9,10}
var mySlice []int = myArray[:5]
a := [5]int{1,2,3,4,5}
b := a[2:4]
b := a[:4]
b := a[2:]
從數(shù)組或已存在的slice再次聲明
var ar [10]byte {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'}
var a, b []byte
a = ar[2:5]
b = ar[3:5]
直接創(chuàng)建
myslice1 := make([]int, 5)
myslice2 := make([]int, 5, 10) //初始個(gè)數(shù)5,預(yù)留10個(gè)元素的存儲(chǔ)空間
myslice3 := []int{1,2,3,4,5}
2.元素訪問(wèn)
for i:=0; i<len(mySlice); i++ {
fmt.Println(i, mySlice[i])
}
for i, v := range mySlice {
fmt.Println(i, v)
}
3.其他操作
大小和容量
len獲取slice的長(zhǎng)度
cap獲取slice的最大容量
動(dòng)態(tài)增減元素
append想slice里面追加一個(gè)或者多個(gè)元素,然后返回一個(gè)和slice一樣類(lèi)型的slice
//append
mySlice = append(mySlice, 1, 2, 3) //增加三個(gè)元素
mySlice = append(mySlice, mySlice2) //增加另一個(gè)
注意,append會(huì)改變slice所引用的數(shù)組的內(nèi)容,從而影響到引用統(tǒng)一數(shù)組的其他slice,
但當(dāng)slice中沒(méi)有剩余空間,此時(shí)動(dòng)態(tài)分配新的數(shù)組空間返回的slice數(shù)組指針將指向這個(gè)空間,
而原數(shù)組的內(nèi)容將保持不變,其他引用此數(shù)組的slice不受影響(坑,可能引入bug)
內(nèi)容復(fù)制
copy,從源slice的src中復(fù)制到目標(biāo)dst,并且返回復(fù)制元素的個(gè)數(shù)
copy(dst, source) //會(huì)按短的個(gè)數(shù)復(fù)制
slice1 := []int{1,2,3,4,5}
slice2 := []int{5,4,3}
copy(slice2, slice1) //復(fù)制slice1前三個(gè) 1 -> 2
copy(slice1, slice2) //復(fù)制slice2的前三個(gè) 2 -> 1
切片
默認(rèn)開(kāi)始位置0,ar[:n]等價(jià)于ar[0:n]
第二個(gè)序列默認(rèn)是數(shù)組長(zhǎng)度 ar[n:] 等價(jià)于 ar[n:len(ar)]
從一個(gè)數(shù)組直接獲取slice,可以是ar[:]
slice是引用類(lèi)型,所以當(dāng)改變其中元素的時(shí)候,其他的所有引用都會(huì)改變
aSlice = array[3:7]
bslice = aSlice[:3]
三.Map
Python中字典的概念
map是無(wú)序的,長(zhǎng)度不固定,內(nèi)置的len可以用于map,可以方便的修改
1.聲明&賦值
map[keyType]valueType
var m map[string] PersonInfo
m = make(map[string] personInfo[, 100])
var numbers map[string]int
or
numbers := make(map[string]int)
numbers["one"] = 1
初始化一個(gè)字典
2.元素訪問(wèn)
rating := map[string]float32 {"c":5, "Go":4.5}
csharpRating, ok := rating["C#"]
if ok {
fmt.Println("get the value")
} else{
fmt.Println("error")
}
3.基本操作
賦值
m["1234"] = PersonInfo{}
刪除
delete(m, "1234")
四.其他
make和new操作
make用于內(nèi)建類(lèi)型(map,slice,channel) 的內(nèi)存分配。
new用于各種類(lèi)型的內(nèi)存分配
new本質(zhì)上和其他語(yǔ)言中同名函數(shù)一樣, new(T)分配了零值填充的T類(lèi)型的內(nèi)存空間,并返回其地址,即一個(gè)*T類(lèi)型的值 即,返回一個(gè)指針,指向新分配的類(lèi)型T的零值
make(T, args),只能創(chuàng)建slice,map,channel,并返回一個(gè)有初始值(非零值)的T類(lèi)型,而不是*T。 本質(zhì)來(lái)講,導(dǎo)致這三個(gè)類(lèi)型有所不同的原因是,指向數(shù)據(jù)結(jié)構(gòu)的引用在使用前必須被初始化
相關(guān)文章
Go語(yǔ)言基礎(chǔ)知識(shí)總結(jié)(語(yǔ)法、變量、數(shù)值類(lèi)型、表達(dá)式、控制結(jié)構(gòu)等)
這篇文章主要介紹了Go語(yǔ)言基礎(chǔ)知識(shí)總結(jié)(語(yǔ)法、變量、數(shù)值類(lèi)型、表達(dá)式、控制結(jié)構(gòu)等),本文匯總了Go語(yǔ)言的入門(mén)知識(shí),需要的朋友可以參考下2014-10-10一文掌握Go語(yǔ)言并發(fā)編程必備的Mutex互斥鎖
Go 語(yǔ)言提供了 sync 包,其中包括 Mutex 互斥鎖、RWMutex 讀寫(xiě)鎖等同步機(jī)制,本篇博客將著重介紹 Mutex 互斥鎖的基本原理,需要的可以參考一下2023-04-04go語(yǔ)言接口的定義和實(shí)現(xiàn)簡(jiǎn)單分享
這篇文章主要介紹了go語(yǔ)言接口的定義和實(shí)現(xiàn)簡(jiǎn)單分享的相關(guān)資料,需要的朋友可以參考下2023-08-08一文詳解golang延時(shí)任務(wù)的實(shí)現(xiàn)
這篇文章主要為大家介紹了golang延時(shí)任務(wù)的實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03源碼分析Golang?log是如何實(shí)現(xiàn)的
go語(yǔ)言的log包提供了簡(jiǎn)單的日志記錄功能,允許開(kāi)發(fā)者在應(yīng)用程序中記錄重要的信息、錯(cuò)誤、警告等,log包是Go標(biāo)準(zhǔn)庫(kù)的一部分,因此,使用它不需要安裝額外的第三方庫(kù),本文給大家源碼分析了Golang?log是如何實(shí)現(xiàn)的,需要的朋友可以參考下2024-03-03