您好,登錄后才能下訂單哦!
這篇文章主要講解了“Golang三個常見的編程問題是什么”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Golang三個常見的編程問題是什么”吧!
問題1:我需要維護一組"物品"。 但是,哦,不,Golang沒有" Set"數據結構。
解決方案之一:Golang沒有"Set",但有"Map"。 映射的鍵集是一組唯一的項目。
您可以執行以下操作(https://play.golang.com/p/tayo3H5mi56):
package main import "fmt" type Set struct { m map[string]bool } func NewSet() Set { m := make(map[string]bool) return Set{m: m} } func (s *Set) Contains(val string) bool { _, ok := s.m[val] return ok } func (s *Set) Add(val string) { s.m[val] = true } func (s *Set) Remove(val string) { delete(s.m, val) } func main() { s := NewSet() s.Add("foo") fmt.Printf("s has foo: %t. s has bar: %t\n", s.Contains("foo"), s.Contains("bar")) s.Remove("foo") fmt.Printf("s has foo: %t. s has bar: %t\n", s.Contains("foo"), s.Contains("bar")) }
將映射用作集合的基礎數據結構的優點是,您仍然受益于超快速的映射鍵查找,基礎哈希優化,并且最終編寫的代碼更少。
問題2:我需要比較兩個值,但" =="并不總是有效。
解決方案之一:讓我們了解" =="在哪里起作用,在哪里不起作用。
包含地圖或切片的結構
type ABC struct { a int b string c []int } Error: invalid operation: a == b (struct containing []int cannot be compared)
帶指針的結構。
好吧,實際上指針是可以比較的,但是它們并不總是能為您提供理想的結果。
a, b := 1, 1 fmt.Println(&a == &b) // False
輸入reflect.DeepEqual
現在,這將可以按需工作(大多數情況下):
//ABC - A simple type type ABC struct { a int b string c []int } var a = ABC{a: 1, b: "10", c: []int{1, 2}} var b = ABC{a: 1, b: "10", c: []int{1, 2}} reflect.DeepEqual(a, b) Example #2 a, b := 1, 1 fmt.Println(&a == &b) // False fmt.Println(reflect.DeepEqual(&a, &b)) // True
它將為您帶來更好的結果-但是,如果您的結構中有浮點數或時間字段,則需要忽略。 您將需要編寫自定義的equals方法
//ABC - A simple type type ABC struct { a int b string t time.Time // Ignore time while comparing to structs } var a = ABC{a: 1, b: "10", t: time.Now()} var b = ABC{a: 1, b: "10", t: time.Now()} fmt.Println(a == b, equals(a, b)) func equals(val1, val2 ABC) bool { return val1.a == val2.a && val1.b == val2.b }
除非您別無選擇,否則您將不希望編寫自定義的equals函數-但是,與==運算符相比,您應該更喜歡reflect.DeepEqual嗎? 本質上,如果==將為true,則保證reflect.DeepEqual為true,反之則不為true。 因此,默認情況下可以使用reflect.DeepEqual。 除非您有性能限制,否則:
func BenchmarkOperator(t *testing.B) { for i := 0; i < t.N; i++ { if a == b { } } } func BenchmarkReflectDeep(t *testing.B) { for i := 0; i < t.N; i++ { if reflect.DeepEqual(a, b) { } } } BenchmarkOperator-8 44614131 24.8 ns/op 0 B/op 0 allocs/op BenchmarkReflectDeep-8 823174 1558 ns/op 96 B/op 2 allocs/op
" =="比reflect.DeepEqual快。 更快。
問題#3:我需要使用結構作為映射的鍵-但我的結構包含要忽略的切片,指針或字段。
解決方案之一:Golang中的映射鍵評估使用==運算符,而不使用reflect.DeepEqual。
解決此問題的一種方法是使用自定義密鑰創建邏輯。
//Obvious solution that will not work type A struct { i *int } i, j := 1, 1 a, b := A{i: &i}, A{i: &j} m := map[A]bool{} m[a] = true _, ok := m[b] fmt.Println(ok) // False key b doesn't exist in map m //Custom keys- solution func customKey(a A) int { return *a.i } i, j := 1, 1 a, b := A{i: &i}, A{i: &j} m := map[int]bool{} m[customKey(a)] = true _, ok := m[customKey(b)] fmt.Println(ok)// This will return true
獎勵問題:如何比較兩個地圖? [問題2和問題3的推論]
https://play.golang.com/p/0ac2HIyiJ9g
key, val := "key", "val" key1, val1 := "key", "val" abc := map[*string]string{&key: val} abc2 := map[*string]string{&key1: val1} def := map[string]*string{key: &val} def2 := map[string]*string{key1: &val1} fmt.Println(reflect.DeepEqual(abc, abc2)) //false fmt.Println(reflect.DeepEqual(def, def2)) //true
首先要注意的是,您不能通過==運算符比較地圖。 您可以通過reflect.DeepEqual比較兩個地圖。 按照reflect.DeepEqual規則,將映射鍵與==運算符進行比較,并將值與reflect.DeepEqual進行遞歸比較。
感謝各位的閱讀,以上就是“Golang三個常見的編程問題是什么”的內容了,經過本文的學習后,相信大家對Golang三個常見的編程問題是什么這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。