Go 默认值与 == 理解

1,256 阅读4分钟

「这是我参与2022首次更文挑战的第11天,活动详情查看:2022首次更文挑战

go 基本数据类型

  1. 基本类型
  • 整型,包括int,uint,int8,uint8,int16,uint16,int32,uint32,int64,uint64,byte,rune,uintptr等
  • 浮点型,包括float32,float64
  • 复数类型,包括complex64,complex128
  • 字符串类型,string
  • 布尔型,bool
  1. 复合类型
  • 数组
  • struct结构体
  1. 引用类型
  • slice
  • map
  • channel
  • pointer or 引用类型
  1. 接口类型
  • io.Reader, io.Writer,error等

go 默认值

  • 整形如int8、byte、int16、uint、uintprt等,默认值为0
  • 浮点类型如float32、float64,默认值为0
  • 布尔类型bool的默认值为false
  • 复数类型如complex64、complex128,默认值为0+0i
  • 字符串string的默认值为""。
  • 错误类型error的默认值为nil
  • 对于一些复合类型,如指针、切片、字典、通道、接口,默认值为nil。而数组的默认值要根据其数据类型来确定。例如:var a [4]int,其默认值为[0 0 0 0]

== 比较

原文说明:

  • Boolean values are comparable. Two boolean values are equal if they are either both true or both false. Integer values are comparable and ordered, in the usual way.
  • Floating-point values are comparable and ordered, as defined by the IEEE-754 standard. Complex values are comparable. Two complex values u and v are equal if both real(u) == real(v) and imag(u) == imag(v).
  • String values are comparable and ordered, lexically byte-wise.
  • Pointer values are comparable. Two pointer values are equal if they point to the same variable or if both have value nil. Pointers to distinct zero-size variables may or may not be equal.
  • Channel values are comparable. Two channel values are equal if they were created by the same call to make or if both have value nil.
  • Interface values are comparable. Two interface values are equal if they have identical dynamic types and equal dynamic values or if both have value nil.
  • A value x of non-interface type X and a value t of - interface type T are comparable when values of type X are comparable and X implements T. They are equal if t's dynamic type is identical to X and t's dynamic value is equal to x.
  • Struct values are comparable if all their fields are comparable. Two struct values are equal if their corresponding non-blank fields are equal.
  • Array values are comparable if values of the array element type are comparable. Two array values are equal if their corresponding elements are equal.

中文说明:

  • 1.基础类型:各种int,bool,string等,这种类型的比较没什么好说的,直接比较值。
  • 2.复合类型(又叫做聚合类型):数组和结构体,这种类型的比较是逐字段比较的。
  • 3.引用类型:slice,map,channel,还有指针,除了slice,剩下的都是通过地址来比较的。
  • 4.接口类型,interface。接口类型的值(称为接口值)其实由两部分组成,具体类型(即该接口存储的值的类型)和该类型的一个值。接口类型的比较涉及这两部分的比较,只有当动态类型完全相同且动态值相等(动态值使用==比较),两个接口值才是相等的。

关于 == 比较,有下面几句话:

  • 类型完全不一样的,不能比较
  • 类型再定义关系的,不能比较, 强转后可以比较
  • 类型别名关系,可以比较

==操作最重要的一个前提是:两个操作数类型必须相同!

func TestEqaual_1(t *testing.T) {
	var a int8
	var b int16
	// 编译错误:invalid operation a == b (mismatched types int8 and int16)
	fmt.Println(a == b)
}

在这里插入图片描述 再定义关系的不能比较,强转的可以比较

func TestEqual_2(t *testing.T) {
	type A int
	var a int = 1
	var b A = 1
	fmt.Println(a == b)      //invalid operation: a == b (mismatched types int and A)
	fmt.Println(a == int(b)) //true 强转的可以比较
}

== 不能用于 slice

切片类型不可比较, 主要因为如下:

  • 1.切片是间接的类型,可以引用自身,有循环引用的问题(如切片[]interface{}中元素可以是任何类型,当然包括自己),实现深度比较难度较大,得不偿失。
  • 2.但是如果直接比较引用的话,与数组的行为不一致,容易造成混淆。
func TestEqual_5(t *testing.T)  {
	test := make([]int, 0)
	test = append(test, 1,2,3,4,5)

	test1 := make([]int, 0)
	fmt.Println(test1 == test) // panic: runtime error: operator not defined on []int
}

数组可以比较

func TestEqual_7(t *testing.T) {
	arr1 := [3]int{1, 2, 3}
	arr2 := [3]int{1, 2, 3}
	fmt.Println("arr1 == arr2 ", arr1 == arr2)
}

执行结果:

=== RUN   TestEqual_7
arr1 == arr2  true
--- PASS: TestEqual_7 (0.00s)
PASS

参考资料