<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
平時開發中對比兩個struct
或者map
、slice
是否相等是經常遇到的,有很多對比的方式,比如==
,reflect.DeepEqual()
,cmp.Equal()
等也是經常容易混淆的,這麼多種對比方式,適用場景和優缺點都有哪些呢?為什麼可以用==
,有的卻不可以呢?問題多多,今天我們來具體總結一下,感興趣的小夥伴們可以參考借鑑,希望對大家能有所幫助。
相信==
判等操作,大家每天都在用。golang
中對==
的處理有一些細節的地方需要特別注意,==
操作最重要的一個前提是:兩個運算元型別必須相同!如果型別不同,那麼編譯時就會報錯。
範例程式碼:
package main import "fmt" func main() { var a int32 var b int64 // 編譯錯誤:invalid operation a == b (mismatched types int32 and int64) fmt.Println(a == b) }
經常見到使用==
的型別一般是:string
,int
等基本型別。struct
有時候可以用有時候不可以。slice
和map
使用 ==
會報錯。
因為slice和map不止是需要比較值,還需要比較len和cap,層級比較深的話還需要遞迴比較,不是簡單的==就可以比較的,所以他們各自之間是不可以直接用==比較的,slice和map只能和nil使用==。
s1 := []int64{1, 3} s2 := []int64{1, 2} if s1 == nil {} //編輯器不會提示報錯 if s1 == s2 {} //編輯器會提示報錯
channel是參照型別,對比的是儲存資料的地址。channel是可以使用==的,只要型別一樣就可以。
ch1 := make(chan int, 1) ch2 := ch1 if cha2 == cha1{fmt.Println("true")} // true
結構體的定義只是一種記憶體佈局的描述,只有當結構體範例化時,才會真正地分配記憶體。
範例化就是根據結構體定義的格式建立一份與格式一致的記憶體區域,結構體範例與範例間的
記憶體是完全獨立的。對結構體進行&取地址操作時,視為對該型別進行一次 new 的範例化操作
因此:go中的結構體: v = Struct {}, v = &Struct{} 這個兩種寫法是等價的。
範例程式碼:
package main import ( "fmt" ) type User struct { Name string Age int64 } type People struct { Name string Hobby []string } func main() { p1 := People{Name: "test", Hobby: []string{"唱", "跳"}} p2 := People{Name: "test", Hobby: []string{"唱", "跳"}} u1 := User{Name: "test", Age:18} u2 := User{Name: "test", Age:18} if p1 == p2 { fmt.Println("p1 == p2") //報錯 } if u1 == u2 { fmt.Println("u1 == u2") } }
reflect包提供的深度對比(遞迴)的方法,適用於go中的slice,map,struct,function的對比。
對比規則
array
的對應元素深度相等時,陣列值是深度相等的。struct
值如果其對應的欄位(包括匯出和未匯出的欄位)都是深度相等的,則該值是深度相等的。func
值如果都是零,則是深度相等;否則就不是深度相等。interface
值如果持有深度相等的具體值,則深度相等。slice
序號相同,如果值,指標都相等,那麼就是深度相等的map
相同的key,如果值,指標都相等,那麼就是深度相等的。通過以上規則可以看到,reflect.DeepEqual
是可以比較struct
的,同時也可以用來比較slice
和map
。
範例程式碼:
package main import ( "fmt" "reflect" ) type People struct { Name string Hobby []string } func main() { p1 := People{Name: "test", Hobby: []string{"唱", "跳"}} p2 := People{Name: "test", Hobby: []string{"唱", "跳"}} if reflect.DeepEqual(p1, p2) { fmt.Println("struct true") } mp1 := map[int]int{1: 1, 2: 2} mp2 := map[int]int{1: 1, 2: 2} if ok := reflect.DeepEqual(mp1, mp2);ok { fmt.Println("mp1 == mp2!") } else { fmt.Println("mp1 != mp2!") } }
go-cmp是 Google 開源的比較庫,它提供了豐富的選項。
對比規則
範例程式碼:
package main import ( "fmt" "github.com/google/go-cmp/cmp" ) type Contact struct { Phone string Email string } type User struct { Name string Age int Contact *Contact } func main() { u1 := User{Name: "test", Age: 18} u2 := User{Name: "test", Age: 18} fmt.Println("u1 == u2?", u1 == u2) //true fmt.Println("u1 equals u2?", cmp.Equal(u1, u2)) //true c1 := &Contact{Phone: "123456789", Email: "dj@example.com"} c2 := &Contact{Phone: "123456789", Email: "dj@example.com"} u1.Contact = c1 u2.Contact = c1 fmt.Println("u1 == u2 with same pointer?", u1 == u2) //true fmt.Println("u1 equals u2 with same pointer?", cmp.Equal(u1, u2)) //true u2.Contact = c2 fmt.Println("u1 == u2 with different pointer?", u1 == u2) //false fmt.Println("u1 equals u2 with different pointer?", cmp.Equal(u1, u2)) //true }
簡單型別的==
對比速度最快
複雜型別,自己知道結構之後寫的自定義對比速度次之
複雜結構且不確定結構的,使用cmp.Equal()或者reflect.DeepEqual()都可以,就是效率低點
assert.Equal()底層使用的就是reflect.DeepEqual()
對於比較兩個struct或者map,slice是否相等,方式很多,效率也有差異。選擇合適自己需求的最重要。相對來說,cmp包是要更安全且可操作性更強一點。
到此這篇關於Golang判斷struct/slice/map是否相等以及對比的方法總結的文章就介紹到這了,更多相關Golang struct slice map內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45