Golang比較兩個slice是否相等的問題
1、為什么在Golang中無法直接使用==來比較兩個slice?
和數(shù)組不同的是,slice無法做比較,因此不能使用==來測試兩個slice是否擁有相同的元素。這里主要是兩個原因:
首先和數(shù)組元素不同,slice元素是非直接的,有可能slice可以包含它自身。雖然有辦法處理這種特殊情況,但是始終沒有一種方法是簡單、高效、直觀的;
其次,因為slice的元素不是直接的,所以如果底層數(shù)組元素改變,同一個slice在不同的時間會有不同的元素;
2、如何實現(xiàn)兩個slice的比較呢?
標(biāo)準(zhǔn)庫里面提供了高度優(yōu)化的函數(shù)bytes.Equal來比較兩個字節(jié)類型的slice([]byte)
2.1 深度比較
自己寫一個方法,首先比較兩個slice的長度,再比較兩個slice對應(yīng)位置元素是否相等。
package main
import (
?? ?"fmt"
)
func main() {
?? ?slice1 := []int{1, 3, 4}
?? ?slice2 := []int{1, 2, 4}
?? ?fmt.Printf("Expect:false\tOutput:%v\n", equal(slice1, slice2)) // Expect:false ? ?Output:false
?? ?slice1 = []int{1, 2, 4}
?? ?slice2 = []int{1, 2, 4}
?? ?fmt.Printf("Expect:true\tOutput:%v\n", equal(slice1, slice2)) // Expect:true ? ? Output:true
}
func equal(slice1, slice2 []int) bool {
?? ?// 比較長度
?? ?if len(slice1) != len(slice2) {
?? ??? ?return false
?? ?}
?? ?// 比較對應(yīng)位置的元素是否相同
?? ?for i := 0; i < len(slice1); i++ {
?? ??? ?if slice1[i] != slice2[i] {
?? ??? ??? ?return false
?? ??? ?} else {
?? ??? ??? ?continue
?? ??? ?}
?? ?}
?? ?return true
}2.2 使用reflect.DeepEqual函數(shù)
使用反射包中提供的DeepEqual可以更加簡潔的實現(xiàn)。另外有些時候我們需要對結(jié)構(gòu)體對象進行比較的時候,我們可以使用該函數(shù)
package main
import (
?? ?"fmt"
?? ?"reflect"
)
func main() {
?? ?slice1 := []int{1, 3, 4}
?? ?slice2 := []int{1, 2, 4}
?? ?fmt.Printf("Expect:false\tOutput:%v\n", reflect.DeepEqual(slice1, slice2))
?? ?// fmt.Printf("Expect:false\tOutput:%v\n", equal(slice1, slice2))
?? ?slice1 = []int{1, 2, 4}
?? ?slice2 = []int{1, 2, 4}
?? ?fmt.Printf("Expect:true\tOutput:%v\n", reflect.DeepEqual(slice1, slice2))
?? ?// fmt.Printf("Expect:true\tOutput:%v\n", equal(slice1, slice2))
}3、擴展:如何在map中讓slice充當(dāng)key???
由于散列表(Golang中map的底層實現(xiàn)原理)僅對元素做淺拷貝,這就要求散列表里面的鍵在散列表的整個生命周期內(nèi)必須保持不變。因此正常情況下,我們無法讓一個slice作為一個map的鍵,但是如果有這樣的業(yè)務(wù)需要我們怎么來實現(xiàn)呢?
本質(zhì)上,其實是將slice按其字面轉(zhuǎn)化為string
%q 該值對應(yīng)的單引號括起來的go語法字符字面值,必要時會采用安全的轉(zhuǎn)義表示
package main
import "fmt"
// "reflect"
type MyMap map[string]int
func (mm MyMap) Add(list []string) {
?? ?mm[k(list)]++
}
func (mm MyMap) Count(list []string) int {
?? ?return mm[k(list)]
}
func k(list []string) string {
?? ?return fmt.Sprintf("%q", list)
}
func main() {
?? ?slice1 := []string{"1", "3", "4"}
?? ?slice2 := []string{"1", "3", "4"}
?? ?slice3 := []string{"1", "2", "4"}
?? ?m := make(MyMap)
?? ?m.Add(slice1)
?? ?m.Add(slice2)
?? ?m.Add(slice3)
?? ?fmt.Printf("Expect:1\tOutput:%v\n", m.Count(slice2)) // Expect:1 ? ? ? ?Output:1
?? ?fmt.Printf("Expect:2\tOutput:%v\n", m.Count(slice1)) // Expect:2 ? ? ? ?Output:2
?? ?fmt.Printf("%v\n", m) // map[["1" "2" "4"]:1 ["1" "3" "4"]:2]
}到此這篇關(guān)于Golang比較兩個slice是否相等的問題的文章就介紹到這了,更多相關(guān)Golang比較兩個slice相等內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決Go語言中高頻次和高并發(fā)下隨機數(shù)重復(fù)的問題
在Golang中,獲取隨機數(shù)的方法一般會介紹有兩種,一種是基于math/rand的偽隨機,一種是基于crypto/rand的真隨機,math/rand由于其偽隨機的原理,經(jīng)常會出現(xiàn)重復(fù)的隨機數(shù),導(dǎo)致在需要進行隨機的業(yè)務(wù)出現(xiàn)較多的重復(fù)問題,所以本文給大家介紹了較好的解放方案2023-12-12
GoFrame框架garray并發(fā)安全數(shù)組使用開箱體驗
這篇文章主要介紹了GoFrame框架garray并發(fā)安全數(shù)組使用開箱體驗,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-06-06
GoLang中panic與recover函數(shù)以及defer語句超詳細講解
這篇文章主要介紹了GoLang的panic、recover函數(shù),以及defer語句,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2023-01-01

