您好,登錄后才能下訂單哦!
這篇文章主要介紹“Go語言容器的數組和切片如何使用”,在日常操作中,相信很多人在Go語言容器的數組和切片如何使用問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Go語言容器的數組和切片如何使用”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
序列容器存儲特定類型的數據元素。目前有 5 種序列容器的實現:
array
vector
deque
list
forward_list
這些序列容易可以用順序的方式保存數據,利用這些序列容易能夠編寫有效的代碼,重復使用標準庫的模塊化。
Go 語言中的數組類型有點類似 C++ 中的數據,Go 的數組初始化定義后,在編譯時就不會再變更。
定義數組的方式如下:
var a [10]int b := [5]string {"H", "e", "l", "l", "o"}
[n]T
類型就表示含有 n
個類型為 T
的數組,本例中就是 a 變量表示含有 10 個 int 類型的整型數組;b 變量表示含有 5 個 string 類型的字符串數組。 數組的長度作為其類型的一部分,因此數組的長度是無法調整的。
package main import "fmt" func main() { var a [10]int a[0] = 2022 a[1] = 2023 fmt.Println(a[0], a[1]) fmt.Println(a) b := [5]string {"H", "e", "l", "l", "o"} fmt.Println(b) }
運行結果如下:
你可能會好奇,Go 語言又沒有 C++ 中的 Vector 類型,為什么會舉出這個例子。
其實 Go 最初有一個 Vector 類型的實現,但在 2011 年 10 月 11 日,在 Go 語言的開發階段被刪除了。保留了現在的切片,而切片就變成了實際上更好的 Vector 實現。
一個數組有固定的大小,但切片是一個動態、靈活的數組元素的視圖,在實際中,切片比數組更為常見。
[]T
表示是一個具有類型 T
的元素切片,[]byte
是 byte slice,指元素為 byte 的 slice;[]string
是 string slice,指元素為 string 的 slice。
切片通過指定兩個切點 a[low : high]
,可以定義如下的 sliceExample
切片:
sliceExample := []string{"Say", "Hello", "to", "you"}
切片對比數組的最大優點就是:可以隨著增加和刪除來增加或減少容器的大小。我們來看一個例子:
package main import "fmt" // remove i indexed item in a slice func remove(s []string, i int) []string { copy(s[i:], s[i+1:]) return s[:len(s)-1] } func main() { primes := [6]int{2, 3, 5, 7, 11, 13} var s []int = primes[1:4] fmt.Println(s) sliceExample := []string{"Say", "Hello", "to", "you"} sliceExample = append(sliceExample, ",My Gopher Friends~") fmt.Println("Append Slice: ", sliceExample) sliceExample = remove(sliceExample, 0) fmt.Println("After Removed Item: ", sliceExample) }
運行結果如下圖:
我們分享了 Go 語言提供的容器中的數組和切片,不管是數據還是切片,它們內部的數據類型必須是一致的(要么都是整型、要么都是字符串類型)。但數據的大小是固定,而切片可以根據元素的添加和減少動態調整容器大小。
Deque,即雙端隊列,是一個可以擴展的容器。擴展可以發生在容器的前面或后面。當隊列的頂部或尾部需要經常被引用時,經常使用雙端隊列。
下面的代碼塊顯示了 Go 雙端隊列 deque 的使用:
package main import ( "fmt" "github.com/gammazero/deque" ) func main() { var q deque.Deque[string] q.PushBack("I") q.PushBack("love") q.PushBack("learning") q.PushBack("Go") fmt.Println("隊列長度為: ", q.Len()) // Prints: 4 fmt.Println("隊首為元素:", q.Front()) // Prints: I fmt.Println("隊尾為元素: ", q.Back()) // Prints: Go q.PopFront() // remove "I" q.PopBack() // remove "Go" q.PushFront("Hello") q.PushBack("World") // Consume deque and print elements. for q.Len() != 0 { fmt.Println(q.PopFront()) } }
運行結果如圖:
List 在 Go 語言中有一個雙鏈表的實現,它位于內置標準庫 container/list
包中
我們可以直接使用這個鏈表的實現:
package main import ( "container/list" "fmt" ) func main() { // Create a new list and put some numbers in it. l1 := list.New() e4 := l1.PushBack(4) e1 := l1.PushFront(1) l1.InsertBefore(3, e4) l1.InsertAfter(2, e1) // now l1 is [1 2 3 4] // Iterate through list and print its contents. for e := l1.Front(); e != nil; e = e.Next() { fmt.Println(e.Value) } l1.MoveToBack(e1) // now l1 is [4 2 3 1] listLength := l1.Len() // length is 4 fmt.Printf("l1 type: %T\n", l1) fmt.Println("l1 length : :", listLength) for e := l1.Front(); e != nil; e = e.Next() { fmt.Println(e.Value) } }
運行結果為:
1
2
3
4
l1 type: *list.List
l1 length : : 4
2
3
4
1
最后介紹一下單鏈表,如果我們想實現的數據結構并沒有標準的容器集成,此時我們就可以通過自己根據要求來寫一個自己想要的容器類型,這里以頭插法的單鏈表舉例:
package main import "fmt" type SinglyLinkedList struct { head *LinkedListNode } type LinkedListNode struct { data string next *LinkedListNode } func (ll *SinglyLinkedList) Append(node *LinkedListNode) { if ll.head == nil { ll.head = node return } currentNode := ll.head for currentNode.next != nil { currentNode = currentNode.next } currentNode.next = node } func main() { ll := &SinglyLinkedList{} ll.Append(&LinkedListNode{data: "Hello"}) ll.Append(&LinkedListNode{data: "Gopher"}) for e := ll.head; e != nil; e = e.next { fmt.Println(e.data) } }
運行結果如圖:
到此,關于“Go語言容器的數組和切片如何使用”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。