GO語言容器

//GO語言容器

/*************************************************************************/
/* --> 一炎咖、數(shù)組的聲明 */
var 數(shù)組變量名 [元素數(shù)量]Type // 聲明數(shù)組
var a [3]int = [3]int{1, 2, 3}
q := [...]int{1, 2, 3} // 在數(shù)組長度的位置出現(xiàn)“...”省略號凡橱,則表示數(shù)組的長度是根據(jù)初始化值的個數(shù)來計算
p := [3]int{1, 2, 3}
p = [4]int{1, 2, 3, 4} // 編譯錯誤:無法將 [4]int 賦給 [3]int

a := [2]int{1, 2}
b := [...]int{1, 2}
c := [2]int{1, 3}
fmt.Println(a == b, a == c, b == c) // "true false false"
d := [3]int{1, 2}
fmt.Println(a == d) // 編譯錯誤:無法比較 [2]int == [3]int

var team [3]string // 遍歷訪問每一個元素
team[0] = "hammer"
team[1] = "soldier"
team[2] = "mum"
for k, v := range team {
fmt.Println(k, v)
}

/*************************************************************************/
/* --> 二奄侠、多維數(shù)組*/
// Go語言中允許使用多維數(shù)組,因為數(shù)組屬于值類型,所以多維數(shù)組的所有維度都會在創(chuàng)建時自動初始化零值,多維數(shù)組尤其適合管理具有父子關系或者與坐標系相關聯(lián)的數(shù)據(jù)桦沉。

var array_name [size1][size2]...[sizen] array_type // 聲明多維數(shù)組

var array [4][2]int // 聲明一個二維整型數(shù)組片择,兩個維度的長度分別是 4 和 2
array = [4][2]int{{10, 11}, {20, 21}, {30, 31}, {40, 41}} // 使用數(shù)組字面量來聲明并初始化一個二維整型數(shù)組
array = [4][2]int{1: {20, 21}, 3: {40, 41}} // 聲明并初始化數(shù)組中索引為 1 和 3 的元素
array = [4][2]int{1: {0: 20}, 3: {1: 41}} // 聲明并初始化數(shù)組中指定的元素

var array1 [2][2]int = [2][2]int{{1,11}, {2,22}}
var array2 [2]int = array1[1] // 將array1中的索引為1的維度復制到一個同類型的數(shù)組 11,22
var array3 int = array1[1][0] // 將array1中指定整型值復制到新的整型變量中 1

/*************************************************************************/
/* --> 三潜的、切片slice*/
// 切片默認指向一段連續(xù)內存區(qū)域,可以是數(shù)組字管,也可以是切片本身
slice [開始位置 : 結束位置] // 從連續(xù)內存區(qū)域生成切片啰挪,以位置索引計算

var a = [3]int{1, 2, 3}
fmt.Println(a, a[1:2]) // 輸出結果:[1 2 3] [2]
fmt.Println(a, a[:]) // 當開始和結束位置索引均為空時,生成的切片將和原切片在數(shù)據(jù)內容上一致
fmt.Println(a,a[0,0]) // 重置切片嘲叔,結果為空列表

var strList []string // 聲明字符串切片

make( []Type, size, cap ) // 使用make()函數(shù)構造切片
// type是指切片元素類型亡呵。size指分配多少元素。cap指預分配的元素數(shù)硫戈,這個值設定不影響size锰什,只是提前分配空間,降低多次分配造成的性能問題
// 使用 make() 函數(shù)生成的切片一定發(fā)生了內存分配操作丁逝,但給定開始與結束位置(包括切片復位)的切片只是將新的切片結構指向已經(jīng)分配好的內存區(qū)域汁胆,設定開始與結束位置,不會發(fā)生內存分配操作霜幼。

/*************************************************************************/
/* --> 四嫩码、為切片添加元素*/
var a []int
a = append(a, 1) // 追加1個元素
a = append(a, 1, 2, 3) // 追加多個元素, 手寫解包方式
// 在使用 append() 函數(shù)為切片動態(tài)添加元素時,如果空間不足以容納足夠多的元素罪既,切片就會進行“擴容”铸题,此時新切片的長度會發(fā)生改變

var a = []int{1,2,3}
a = append([]int{0}, a...) // 在開頭添加1個元素
a = append([]int{-3,-2,-1}, a...) // 在開頭添加1個切片
// 在切片開頭添加元素一般都會導致內存的重新分配,而且會導致已有元素全部被復制 1 次琢感,因此丢间,從切片的開頭添加元素的性能要比從尾部追加元素的性能差很多

var a []int
a = append(a[:i], append([]int{x}, a[i:]...)...) // 在第i個位置插入x
a = append(a[:i], append([]int{1,2,3}, a[i:]...)...) // 在第i個位置插入切片

/*************************************************************************/
/* --> 五、切片復制*/
copy( destSlice, srcSlice []T) int

slice1 := []int{1, 2, 3, 4, 5}
slice2 := []int{5, 4, 3}
copy(slice2, slice1) // 只會復制slice1的前3個元素到slice2中
copy(slice1, slice2) // 只會復制slice2的3個元素到slice1的前3個位置

/*************************************************************************/
/* --> 六驹针、從切片中刪除元素/
/

Go語言并沒有對刪除切片元素提供專用的語法或者接口烘挫,需要使用切片本身的特性來刪除元素,根據(jù)要刪除元素的位置有三種情況柬甥,
分別是從開頭位置刪除饮六、從中間位置刪除和從尾部刪除,其中刪除切片尾部的元素速度最快暗甥。
*/
a = []int{1, 2, 3}
a = a[1:] // 刪除開頭1個元素
a = a[N:] // 刪除開頭N個元素

a = []int{1, 2, 3}
a = append(a[:0], a[1:]...) // 刪除開頭1個元素
a = append(a[:0], a[N:]...) // 刪除開頭N個元素

a = []int{1, 2, 3}
a = a[:copy(a, a[1:])] // 刪除開頭1個元素
a = a[:copy(a, a[N:])] // 刪除開頭N個元素

// Go語言中刪除切片元素的本質是喜滨,以被刪除元素為分界點,將前后兩個部分的內存重新連接起來
func main() {
seq := []string{"a", "b", "c", "d", "e"}
// 指定刪除位置
index := 2
// 查看刪除位置之前的元素和之后的元素
fmt.Println(seq[:index], seq[index+1:]) // [a b] [d e]
// 將刪除點前后的元素連接起來
seq = append(seq[:index], seq[index+1:]...)
fmt.Println(seq) // [a b d e]
}

/*************************************************************************/
/* --> 七撤防、range虽风,循環(huán)迭代切片*/
// 創(chuàng)建一個整型切片,并賦值
slice := []int{10, 20, 30, 40}
// 迭代每一個元素,并顯示其值
for index, value := range slice {
fmt.Printf("Index: %d Value: %d\n", index, value)
}

// range 返回的是每個元素的副本辜膝,而不是直接返回對該元素的引用
// 創(chuàng)建一個整型切片无牵,并賦值
slice := []int{10, 20, 30, 40}
// 迭代每個元素,并顯示值和地址
for index, value := range slice {
fmt.Printf("Value: %d Value-Addr: %X ElemAddr: %X\n", value, &value, &slice[index])
}
/*
Value: 10 Value-Addr: 10500168 ElemAddr: 1052E100
Value: 20 Value-Addr: 10500168 ElemAddr: 1052E104
Value: 30 Value-Addr: 10500168 ElemAddr: 1052E108
Value: 40 Value-Addr: 10500168 ElemAddr: 1052E10C
*/

/*************************************************************************/
/* --> 八厂抖、多維切片*/
// 聲明一個二維整型切片并賦值
slice := [][]int{{10}, {100, 200}}
// 為第一個切片追加值為 20 的元素
slice[0] = append(slice[0], 20)

/*************************************************************************/
/* --> 九茎毁、map 映射/
// 類似于字典
// 和數(shù)組不同,map 可以根據(jù)新增的 key-value 動態(tài)的伸縮
var mapname map[keytype]valuetype // 聲明方式忱辅,keytype指鍵的類型七蜘,valuetype指鍵對應值的類型
func main() {
var mapLit map[string]int
//var mapCreated map[string]float32
var mapAssigned map[string]int // 聲明
mapLit = map[string]int{"one": 1, "two": 2} // 初始化
mapCreated := make(map[string]float32) // 初始化
mapAssigned = mapLit
mapCreated["key1"] = 4.5
mapCreated["key2"] = 3.14159
mapAssigned["two"] = 3
fmt.Printf("Map literal at "one" is: %d\n", mapLit["one"])
fmt.Printf("Map created at "key2" is: %f\n", mapCreated["key2"])
fmt.Printf("Map assigned at "two" is: %d\n", mapLit["two"])
fmt.Printf("Map literal at "ten" is: %d\n", mapLit["ten"])
}
/

1、mapCreated 的創(chuàng)建方式mapCreated := make(map[string]float)等價于mapCreated := map[string]float{}
2墙懂、mapAssigned 是 mapList 的引用橡卤,對 mapAssigned 的修改也會影響到 mapLit 的值
3、可以使用 make()损搬,但不能使用 new() 來構造 map碧库,如果錯誤的使用 new() 分配了一個引用對象,
會獲得一個空引用的指針巧勤,相當于聲明了一個未初始化的變量并且取了它的地址:mapCreated := new(map[string]float)
4嵌灰、
*/

// 遍歷同樣使用range或者for循環(huán)
// 使用delete()函數(shù)從map中刪除鍵值對
delete(map, 鍵)

// 清空map中的所有元素,GO語言中沒有為map提供任何清空的函數(shù)颅悉,唯一的辦法就是重新make一個新的map

/*************************************************************************/
/* --> 十沽瞭、sync.Map 在并發(fā)環(huán)境中使用的map/
// Go語言中的 map 在并發(fā)情況下,只讀是線程安全的签舞,同時讀寫是線程不安全的
// sync.Map相對于map性能有所損失秕脓,所以柒瓣,在非并發(fā)的情況下使用map比較好
// 如果在非并發(fā)的情況下使用map的同時使用鎖儒搭,性能則不如sync.Map
sync.Map // 和map不同,sync.Map是sync包下的特殊結構
/

sync.Map有以下幾點特性
1芙贫、無需初始化搂鲫,直接聲明即可
2、sync.Map不能使用map的方式進行取值和設置等操作磺平,俄日是使用sync.Map的方法進行調用
Store表示存儲魂仍,Load表示獲取。Delete表示刪除
3拣挪、使用Range配合一個回調函數(shù)進行遍歷操作擦酌,通過回調函數(shù)返回內部遍歷出來的值,
Range參數(shù)中回調函數(shù)的返回值在需要繼續(xù)迭代遍歷時菠劝,返回true赊舶,終止迭代遍歷時,返回false
/
func main() {
var scene sync.Map
// 將鍵值對保存到sync.Map
scene.Store("greece", 97)
scene.Store("london", 100)
scene.Store("egypt", 200)
// 從sync.Map中根據(jù)鍵取值
fmt.Println(scene.Load("london")) // 100 true
// 根據(jù)鍵刪除對應的鍵值對
scene.Delete("london")
// 遍歷所有sync.Map中的鍵值對
scene.Range(func(k, v interface{}) bool {
fmt.Println("iterate:", k, v) // iterate: egypt 200 iterate: greece 97
return true
})
}
/

Range方法可以遍歷sync.Map,但遍歷需要提供一個匿名函數(shù)笼平,參數(shù)為 k园骆、v,類型為 interface{}寓调,
每次 Range() 在遍歷一個元素時锌唾,都會調用這個匿名函數(shù)把結果返回。
Range 參數(shù)中回調函數(shù)的返回值在需要繼續(xù)迭代遍歷時夺英,返回 true晌涕,終止迭代遍歷時,返回 false
*/

/*************************************************************************/
/* --> 十一痛悯、列表/
/

1渐排、列表初始化,分別可以使用New()函數(shù)和var關鍵字灸蟆,兩者效果一致
2驯耻、列表與切片和map不同的是,列表沒有具體元素類型的限制炒考。風險:放入一個interface{}類型的值可缚,
取出后如果將interface{}轉換為其他類型將會發(fā)生宕機
3、go語言中的列表為雙鏈表類型的斋枢,支持從隊列前后插入元素帘靡,PushFront和PushBack
4、上面兩個方法都會返回一個*list.Element結構瓤帚,如果需要刪除之前插入的元素描姚,則只能通過
*list.Element配合Remove()方法刪除
*/
l := list.New() // 初始化一個空列表
l.PushBack("fist") // 將字符串插入列表尾部
l.PushFront(67) // 將字符串插入列表頭部

func main() {
l := list.New()

l.PushBack("canon")  // 尾部添加

l.PushFront(67)  // 頭部添加

element := l.PushBack("fist")  // 尾部添加后保存元素句柄

l.InsertAfter("high", element)  // 在fist之后添加high

l.InsertBefore("noon", element)  // 在fist之前添加noon

l.Remove(element)  // 移除element對應的元素

}

// 遍歷列表
l := list.New()
l.PushBack("canon") // 尾部添加
l.PushFront(67) // 頭部添加
for i := l.Front(); i != nil; i = i.Next() {
fmt.Println(i.Value)
}
/*
使用 for 語句進行遍歷,其中 i:=l.Front() 表示初始賦值戈次,只會在一開始執(zhí)行一次轩勘,
每次循環(huán)會進行一次 i != nil 語句判斷,如果返回 false怯邪,表示退出循環(huán)绊寻,反之則會執(zhí)行 i = i.Next()
*/

/*************************************************************************/
/* --> 十二、make和new關鍵字的區(qū)別及實現(xiàn)原理*/
// new 函數(shù)悬秉,它返回的永遠是類型的指針澄步,指針指向分配類型的內存地址
// 內置類型數(shù)據(jù)分配內存
var sum *int
sum = new(int) //分配空間
sum = 98
fmt.Println(
sum)

// 自定義類型new
type Student struct {
name string
age int
}
var s *Student // 聲明一個指針s
s = new(Student) //分配空間
s.name ="dequan"

// make只用于 chan、map 以及 slice 的內存創(chuàng)建和泌,而且它返回的類型就是這三個類型本身村缸,而不是他們的指針類型

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市武氓,隨后出現(xiàn)的幾起案子梯皿,更是在濱河造成了極大的恐慌搪柑,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件索烹,死亡現(xiàn)場離奇詭異工碾,居然都是意外死亡,警方通過查閱死者的電腦和手機百姓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進店門渊额,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人垒拢,你說我怎么就攤上這事旬迹。” “怎么了求类?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵奔垦,是天一觀的道長。 經(jīng)常有香客問我尸疆,道長椿猎,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任寿弱,我火速辦了婚禮犯眠,結果婚禮上,老公的妹妹穿的比我還像新娘症革。我一直安慰自己筐咧,他們只是感情好,可當我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布噪矛。 她就那樣靜靜地躺著量蕊,像睡著了一般。 火紅的嫁衣襯著肌膚如雪艇挨。 梳的紋絲不亂的頭發(fā)上残炮,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天,我揣著相機與錄音雷袋,去河邊找鬼吉殃。 笑死辞居,一個胖子當著我的面吹牛楷怒,可吹牛的內容都是我干的。 我是一名探鬼主播瓦灶,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼鸠删,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了贼陶?” 一聲冷哼從身側響起刃泡,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤巧娱,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后烘贴,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體禁添,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年桨踪,在試婚紗的時候發(fā)現(xiàn)自己被綠了老翘。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡锻离,死狀恐怖铺峭,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情汽纠,我是刑警寧澤卫键,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站虱朵,受9級特大地震影響莉炉,放射性物質發(fā)生泄漏。R本人自食惡果不足惜碴犬,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一呢袱、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧翅敌,春花似錦羞福、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至遭顶,卻和暖如春张峰,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背棒旗。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工喘批, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人铣揉。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓饶深,卻偏偏與公主長得像,于是被迫代替她去往敵國和親逛拱。 傳聞我的和親對象是個殘疾皇子敌厘,可洞房花燭夜當晚...
    茶點故事閱讀 44,843評論 2 354

推薦閱讀更多精彩內容