Golang比較兩個(gè)slice是否相等的問(wèn)題
1、為什么在Golang中無(wú)法直接使用==來(lái)比較兩個(gè)slice?
和數(shù)組不同的是,slice無(wú)法做比較,因此不能使用==來(lái)測(cè)試兩個(gè)slice是否擁有相同的元素。這里主要是兩個(gè)原因:
首先和數(shù)組元素不同,slice元素是非直接的,有可能slice可以包含它自身。雖然有辦法處理這種特殊情況,但是始終沒有一種方法是簡(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)文章
以Golang為例詳解AST抽象語(yǔ)法樹的原理與實(shí)現(xiàn)
AST?使用樹狀結(jié)構(gòu)來(lái)表達(dá)編程語(yǔ)言的結(jié)構(gòu),樹中的每一個(gè)節(jié)點(diǎn)都表示源碼中的一個(gè)結(jié)構(gòu),本文將以GO語(yǔ)言為例,為大家介紹一下AST抽象語(yǔ)法樹的原理與實(shí)現(xiàn),希望對(duì)大家有所幫助2024-01-01
Golang使用Decimal庫(kù)避免運(yùn)算中精度損失詳細(xì)步驟
decimal是為了解決Golang中浮點(diǎn)數(shù)計(jì)算時(shí)精度丟失問(wèn)題而生的一個(gè)庫(kù),使用decimal庫(kù)我們可以避免在go中使用浮點(diǎn)數(shù)出現(xiàn)精度丟失的問(wèn)題,下面這篇文章主要給大家介紹了關(guān)于Golang使用Decimal庫(kù)避免運(yùn)算中精度損失的相關(guān)資料,需要的朋友可以參考下2023-06-06
Golang基于JWT與Casbin身份驗(yàn)證授權(quán)實(shí)例詳解
這篇文章主要為大家介紹了Golang基于JWT與Casbin實(shí)現(xiàn)身份驗(yàn)證授權(quán)實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08
go local history本地歷史恢復(fù)代碼神器
這篇文章主要為大家介紹了go local history本地歷史恢復(fù)代碼神器的使用功能詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01
golang字符串拼接實(shí)現(xiàn)方式和區(qū)別對(duì)比
本文介紹了Go語(yǔ)言中字符串拼接的多種方法及其優(yōu)缺點(diǎn),推薦使用strings.Builder進(jìn)行頻繁拼接以優(yōu)化內(nèi)存分配和性能,同時(shí),還討論了通過(guò)sync.Pool優(yōu)化高頻創(chuàng)建的對(duì)象,以減少垃圾回收壓力,感興趣的朋友一起看看吧2025-02-02
Golang實(shí)現(xiàn)http重定向https
這篇文章介紹了Golang實(shí)現(xiàn)http重定向https的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-07-07
小學(xué)生也能看懂的Golang異常處理recover panic
在其他語(yǔ)言里,宕機(jī)往往以異常的形式存在,底層拋出異常,上層邏輯通過(guò) try/catch 機(jī)制捕獲異常,沒有被捕獲的嚴(yán)重異常會(huì)導(dǎo)致宕機(jī),go語(yǔ)言追求簡(jiǎn)潔,優(yōu)雅,Go語(yǔ)言不支持傳統(tǒng)的 try…catch…finally 這種異常2021-09-09
GO語(yǔ)言對(duì)數(shù)組切片去重的實(shí)現(xiàn)
本文主要介紹了GO語(yǔ)言對(duì)數(shù)組切片去重的實(shí)現(xiàn),主要介紹了幾種方法,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-04-04

