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