9.13 Golang不同类型比较 在日常开发过程中难免会遇到各个类型的变量的比较以及运算操作,这里做了一些简单的汇总,希望能给各位同学在开发中带来帮助。
这里先上一波关系运算符==,!=,<,<=,> 和 >=。
float浮点数比较 golang 支持两种浮点float32和float64,众所众知,涉及浮点数比较或运算是会遇到精度问题,具体要根据golang实现IEEE 754的情况定。
默认情况下,float32精度是小数后7位,float64精度是小数点后15位。
如例1:
1 2 3 4 5 6 7 8 9 var a float32 = 1.00000001 var b float32 = 1.000000000001 var c float32 = 1.0000001 var d float32 = 1.000000000001 fmt.Println(a == b) //true fmt.Println(a > b) //false fmt.Println(c == d) //false fmt.Println(c > d) //true
float64
1 2 3 4 5 6 7 8 9 var a float64 = 1.0000000000000001 var b float64 = 1.000000000000000001 var c float64 = 1.000000000000001 var d float64 = 1.0000000000000000001 fmt.Println(a == b) //true fmt.Println(a > b) //false fmt.Println(c == d) //false fmt.Println(c > d) //true
这里写了一个根据精度进行float比较的简单的类,注意最大精度为小数点后15位,超出会丢失精度。
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 package main import ( "fmt" "math" ) type Floater struct { Accuracy float64 //精度,最大为小数点后15位 } //是否相等 func (f Floater) IsEqual(a, b float64) bool { return math.Abs(a-b) < f.Accuracy } //0为相等 1为a大于b -1为a小于b func (f Floater) Bccomp(a, b float64) int8 { if math.Abs(a-b) < f.Accuracy { return 0 } if math.Max(a, b) == a { return 1 } else { return -1 } } func main() { f := Floater{Accuracy: 0.000000000001} var a float64 = 1.0000000002 var b float64 = 1.0000000001 fmt.Println(f.Bccomp(a, b)) //1 fmt.Println(f.Bccomp(b, a)) //-1 fmt.Println(f.Bccomp(a, a)) //0 }
顺便讲一下如何实现保留小数点后2位如何实现
1 2 3 4 5 6 7 8 9 10 11 12 //方法1 a := 2.556 v, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", a), 64) fmt.Println(v) //2.56 //方法2 v = math.Trunc(a*1e2+0.5) * 1e-2 fmt.Println(v) //2.56 //方法3 n10 := math.Pow10(2) v = math.Trunc((a+0.5/n10)*n10) / n10 fmt.Println(v)
指针类型比较 1 2 3 4 a := "hello" b := &a c := &a fmt.Println(b == c)
当变量是相同或者都为nil时,指针值相等。
interface类型比较 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 type I1 interface { f() } type I2 interface { f() } type S1 struct { name string } func (s S1) f() { } type S2 struct { name string } func (s S2) f() { } func main() { var a, b, c, d I1 var e I2 a = S1{"hello"} b = S1{"hello"} c = S1{"world"} d = S2{"hello"} fmt.Println(a == b) //true fmt.Println(a == c) //false fmt.Println(a == d) //false fmt.Println(a == e) //false }
比较 slice/struct/map 这三个都可以用reflect.DeepEqual来判断是否相等
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 package main import ( "fmt" "reflect" ) type S struct { s string } func main() { s1 := S{s: "hello"} s2 := S{s: "hello"} if reflect.DeepEqual(s1, s2) { fmt.Println(s1, "==", s2) } a1 := []int{1, 2} a2 := []int{1, 2} if reflect.DeepEqual(a1, a2) { fmt.Println(a1, "==", a2) } m1 := map[int]string{1: "a", 2: "b"} m2 := map[int]string{1: "a", 2: "b"} if reflect.DeepEqual(m1, m2) { fmt.Println(m1, "==", m2) } }