使用golang开发应用必然躲不过interface{}类型,虽然golang 提供了类型断言和反射等方式解决类型转换的问题。
如果遇到“==”“!=”比较运算,空接口interface{}可以直接进行比较。接口类型的变量,包含该接口变量存储的值和值的类型两部分组成,分别称为接口的动态类型和动态值。只有动态类型和动态值都相同时,两个接口变量才相同。
测试代码如下:
package main import "fmt" type Foo struct { ID int64 Name string //Bytes []byte //不能比较 //Map map[string]string //不能比较 //Func func() error //不能比较 } func main() { var _testNil, _testNil2 map[string]string struct1 := Foo{ID: 1, Name: "Sam"} _struct1 := Foo{ID: 1, Name: "Sam"} struct2 := Foo{ID: 1, Name: "Peter"} var data = []map[string]interface{}{ {"params": []interface{}{1, 1}, "expected": true}, {"params": []interface{}{2, 2, 2, 2, 2}, "expected": true}, {"params": []interface{}{1, 2}, "expected": false}, {"params": []interface{}{"1", 1}, "expected": false}, {"params": []interface{}{nil, nil}, "expected": true}, {"params": []interface{}{&_testNil, &_testNil2}, "expected": false}, {"params": []interface{}{nil, _testNil}, "expected": false}, //{"params": []interface{}{_testNil, _testNil2}, "expected": false},//slices、maps、functions类型不能参与比较,同样包含这三种类型的结构体也不能参与比较 {"params": []interface{}{struct1, _struct1}, "expected": true}, {"params": []interface{}{struct1, struct2}, "expected": false}, {"params": []interface{}{&struct1, &struct1}, "expected": true}, {"params": []interface{}{&struct1, &_struct1}, "expected": false}, } for _, v := range data { result := compare(v["params"].([]interface{})...) fmt.Printf("expected:%t,result:%t,params:%#v\n", v["expected"].(bool), result, v["params"].([]interface{})) } } func compare(params ...interface{}) bool { if len(params) < 2 { return false } for i, v := range params { if i == 0 { continue } if params[0] != v { return false } } return true }
值得注意的是,进行比较运算的时候,简单的类型和结构体都可以,但是不能是不可比较类型(uncomparable type),map、slice、func,以及包含这三种类型的结构体都不能参与比较。可以使用reflect.DeepEqual进行深度相等比较map、slice等类型。
总结,使用空接口直接进行相等比较,可以大大简化代码量,方便后期维护。