Go struct 对象能比较吗


同一个struct的两个实例能不能比较

可能可以,也可能不可以。

当struct中包含的属性都是可比较类型,则可以。

package main

import "fmt"

type TestStruct1 struct {
	Name string
	Age *int
}

func main(){
	var age int = 18
	t1 := TestStruct1{
		Name: "name1",
		Age:  &age,
	}
	t2 := TestStruct1{
		Name: "name1",
		Age:  &age,
	}
	t3 := &TestStruct1{
		Name: "name1",
		Age:  &age,
	}

	fmt.Println(t1==t2, t1 == *t3, &t1 == t3)
}

结果:true true false
分析:t1==t2 和 t1 == *t3 都是比较两个struct的内容,所以是true, &t1 == t3 是比较t1,t3两个实例的地址,这是两个不同的实例,所以地址肯定是不一样的

如果struct中包含不可比较类型的属性,则不可比较

package main

import "fmt"

type TestStruct1 struct {
	Name string
	Age *int
	Friends []string
}

func main(){
	var age int = 18
	t1 := TestStruct1{
		Name: "name1",
		Age:  &age,
		Friends:[]string{"a","b"},
	}
	t2 := TestStruct1{
		Name: "name1",
		Age:  &age,
		Friends:[]string{"a","b"},
	}

	fmt.Println(t1==t2)
}

fmt.Println(t1==t2) 编译报错:invalid operation: t1 == t2 (struct containing []string cannot be compared)

改成:fmt.Println(&t1==&t2),则编译成功,结果是 false

package main

import "fmt"

type TestStruct1 struct {
	Name    string
	Age     *int
	Friends []string
}

func main() {
	var age int = 18
	friends := []string{"a", "b"}
	t1 := TestStruct1{
		Name:    "name1",
		Age:     &age,
		Friends: friends,
	}
	t2 := TestStruct1{
		Name:    "name1",
		Age:     &age,
		Friends: friends,
	}
	t3 := t1
	t4 := &t1

	fmt.Println(&t1 == &t2, &t1 == &t3, &t1 == t4)
}

结果:false false true

分析:加引用了则比较的是t1和t2两个实例的地址,这是两个实例,地址肯定是不一样的,所以&t1==&t2的结果是false

这里虽然t3直接用t1赋值,但t3和t1是两个不同的实例,因此&t1==&t3为false

t4用t1的指针赋值,因此t4和t1指向同一块内存地址,t4的内容是t1的指针,因此&t1==t4结果是true

不同struct的两个实例能不能比较

可能可以,也可能不可以。

package main

import "fmt"

type TestStruct1 struct {
	Name    string
	Age     *int
}


type TestStruct2 struct {
	Name    string
	Age     *int
}

func main() {
	var age int = 18
	t1 := TestStruct1{
		Name: "name1",
		Age:  &age,
	}
	t2 := TestStruct2{
		Name: "name1",
		Age:  &age,
	}

	fmt.Println(t1 == t2)
}

结果:fmt.Println(t1 == t2)报编译错误:invalid operation: t1 == t2 (mismatched types TestStruct1 and TestStruct2)

分析:t1和t2两个实例的结构体不一样,肯定不能比较

两个struct不一样的结构体的实例不能直接比较,但是可以通过强制类型转换进行比较

package main

import "fmt"

type TestStruct1 struct {
	Name    string
	Age     *int
}


type TestStruct2 struct {
	Name    string
	Age     *int
}

func main() {
	var age int = 18
	t1 := TestStruct1{
		Name: "name1",
		Age:  &age,
	}
	t2 := TestStruct2{
		Name: "name1",
		Age:  &age,
	}

	fmt.Println(t1 == TestStruct1(t2))
	fmt.Println(TestStruct2(t1) == t2)
}

结果:true true

分析:虽然t1,t2是两个不同的结构体,但是通过强制类型转换成一个结构体,也是可以比较的,并且结果是true

但是如果两个结构体中包含不可比较类型的属性,则不能比较

package main

import "fmt"

type TestStruct1 struct {
	Name    string
	Age     *int
	Friends []string
}


type TestStruct2 struct {
	Name    string
	Age     *int
	Friends []string
}

func main() {
	var age int = 18
	friends := []string{"a","b"}
	t1 := TestStruct1{
		Name: "name1",
		Age:  &age,
		Friends:friends,
	}
	t2 := TestStruct2{
		Name: "name1",
		Age:  &age,
		Friends:friends,
	}

	t3 := TestStruct1(t2)
	fmt.Println(t1 == t3)
}

结果:fmt.Println(t1 == t3)编译错误:invalid operation: t1 == t3 (struct containing []string cannot be compared)

分析:虽然t2可以强制转换成TestStruct1类型,但是还是不能与t1比较。

可以取地址比较:fmt.Println(&t1==&t3),结果是false,因为t1和t3是两个不同的实例

struct的实例能做map的key吗

可能可以,也可能不可以。当key是可比较的时候则可以,否则不可以

package main

import "fmt"

type TestStruct1 struct {
	Name    string
	Age     *int
}


type TestStruct2 struct {
	Name    string
	Age     *int
	Friends []string
}

func main() {
	m1 := make(map[TestStruct1]string)
	m2 := make(map[TestStruct2]string)
	fmt.Println(m1,m2)
}

结果:m2 := make(map[TestStruct2]string)编译错误:invalid map key type TestStruct2

可排序、可比比较、不可比较

  • 可排序:int,float,string
  • 可比较:int,float,string,bool,interface,channel,array
  • 不可比较:slice,map,function

参考

【1】Golang中的struct能不能比较


文章作者: Alex
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Alex !
  目录