golang中数据类型分为4大类:1.基础类型:各种int,bool,string等,这种类型的比较没什么好说的,直接比较值。2.复合类型(又叫做聚合类型):数组和结构体,这种类型的比较是逐字段比较的。3.引用类型:slice,map,channel,还有指针,除了slice,剩下的都是通过地址来比较的。slice后面说。4.接口类型,interface。接口类型的值(称为接口值)其实由两部分组成,具体类型(即该接口存储的值的类型)和该类型的一个值。按照《go程序设计语言》的称谓,分别称为动态类型和动态值。接口类型的比较涉及这两部分的比较,只有当动态类型完全相同且动态值相等(动态值使用==比较),两个接口值才是相等的。
需要注意的是,由于下面两点原因,golang干脆规定,切片类型不可比较。1.切片是间接的类型,可以引用自身,有循环引用的问题(如切片[]interface{}中元素可以是任何类型,当然包括自己),实现深度比较难度较大,得不偿失。2.但是如果直接比较引用的话,与数组的行为不一致,容易造成混淆。
由于不可比较类型的存在,导致比较操作有一些出乎意料的地方:1.如果复合类型中有不可比较的类型,那么复合类型就不可比较。例如数组中的元素是切片类型,结构体中含有切片类型的字段等。2.如果接口值的动态值不可比较,那么直接比较会panic,如:
varainterface{}=[]int{1,2,3}
varbinterface{}=[]int{4,5,6}
fmt.Println(a==b)
//panic:runtimeerror:comparinguncomparabletype[]int
建议翻阅《go程序设计语言》一书的第四章《复合数据类型》和第七章《接口》,有比较详细的说明
网友评论