Golang中数据比较

501 阅读3分钟

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

Go 中的数据类型

  • 基本类型:Go中最基本类型包括整型(int、uint、int8、uint8、int16、uint16、int32、uint32、int64、uint64、byte、rune等)、浮点型(float32、float64)、字符串(string也是个[]rune数组)和比较不常用的复数类型(complex64/complex128)。
  • 复合类型:主要包括结构体和数组。
  • 引用类型:Slice、Map、Channel、指针。
  • 接口类型:Error、io.Reader等。

Go中数据类型哪些可比较的,哪些是不可比较的

关于 Golang 中哪些数据类型是可比较的,哪些是不可以比较的,结果如下:

  • 可比较:Integer,Floating-point,String,Boolean,Complex(复数型),Pointer,Channel,Interface,Array
  • 不可比较:Slice,Map,Function
  • 复合类型中如果带有不可比较的类型,那么该复合类型是不可比较的,不可比较类型有传递性

复合类型比较

不包含不能比较类型,可以比较

下面的情况复合类型 S 就是可以比较的

测试代码:

package compare

import (
	"fmt"
	"testing"
)

type User struct {
	Name    string
	Age     int
	Address string
}


func TestStructCompare(t *testing.T) {
	str1 := "北京"
	str2 := "北京"
	a := User{
		Name:    "aa",
		Age:     1,
		Address: str1,
	}
	b := User{
		Name:    "aa",
		Age:     1,
		Address: str2,
	}

	fmt.Println(a == b)
}

执行结果:

=== RUN   TestStructCompare
true
--- PASS: TestStructCompare (0.00s)
PASS

为啥可以比较,因为 struct 中不包含不可以比较的 slice 、 function 、map

现在将复合类型改一下,改成结果如下:

type Student struct {
	Name    string
	Age     int
	Address string
	Data    []int
}

func TestStructCompare2(t *testing.T) {
	a := Student{
		Name:    "aa",
		Age:     1,
		Address: "北京",
		Data:    []int{1, 2, 3},
	}
	b := Student{
		Name:    "aa",
		Age:     1,
		Address: "北京",
		Data:    []int{1, 2, 3},
	}

	fmt.Println(a == b)
}

编译的时候就会报错。 运行结果报错如下:

invalid operation: a == b (struct containing []int cannot be compared)

指针类型比较

  • == 运算符:如果两个指针都指向同一个变量,则此运算符返回true。或如果两个指针都指向不同的变量,则返回false。
func TestPointerCompare(t *testing.T){
	val1 := 2345
	val2 := 567

	//创建和初始化指针
	var p1 *int
	p1 = &val1
	p2 := &val2
	p3 := &val1

	res1 := &p1 == &p2
	fmt.Println("p1指针是否等于p2指针: ", res1)

	res2 := p1 == p2
	fmt.Println("p1指针是否等于p2指针: ", res2)

	res3 := p1 == p3
	fmt.Println("p1指针是否等于p3指针: ", res3)

	res4 := p2 == p3
	fmt.Println("p2指针是否等于p3指针: ", res4)

	res5 := &p3 == &p1
	fmt.Println("p3指针是否等于p1指针: ", res5)

}

执行结果:

=== RUN   TestPointerCompare
p1指针是否等于p2指针:  false
p1指针是否等于p2指针:  false
p1指针是否等于p3指针:  true
p2指针是否等于p3指针:  false
p3指针是否等于p1指针:  false
--- PASS: TestPointerCompare (0.00s)
PASS

slice/struct/map 比较

如果直接使用 == 比较会有问题,可以采用。反射来进行比较,可以用reflect.DeepEqual来判断是否相等.

type S struct {
	s string
	m map[string]string
}

func TestSCompare(t *testing.T) {
	s1 := S{s: "hello", m: map[string]string{"hello": "world"}}
	s2 := S{s: "hello", m: map[string]string{"hello": "world"}}
	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)
	}
}

运行结果:

=== RUN   TestSCompare
{hello map[hello:world]} == {hello map[hello:world]}
[1 2] == [1 2]
map[1:a 2:b] == map[1:a 2:b]
--- PASS: TestSCompare (0.00s)
PASS