前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >golang的struct能否比较

golang的struct能否比较

作者头像
素履coder
发布2022-02-17 14:38:54
4830
发布2022-02-17 14:38:54
举报
文章被收录于专栏:素履coder

1.数据类型

golang中能够用 == 号直接比较的数据类型有如下

  • 整型 integer、浮点型 float、字符串 string、布尔型 boolean、复数型 complex、指针型 pointer、通道型 channel、接口型 interface、数组型 array

不能直接比较的

  • 切片型 slice、键值对型 map、函数型 func

2.struct比较

1.相同结构体+可比较类型

代码语言:javascript
复制
package main

import "fmt"

type S struct {
	s string
	i int
	b bool
}

func main() {
	s1 := S{
		s: "你好",
		i: 1,
		b: false,
	}

	s2 := S{
		s: "你好",
		i: 1,
		b: false,
	}

	fmt.Println(s1 == s2)
}

//结果:
true

结构体内都是可比较的类型,赋值两个一样数据的struct,最终两个struct是相等的,返回true

代码语言:javascript
复制
package main

import "fmt"

type S struct {
	s string
	i int
	b bool
	p *int
}

func main() {
	s1 := S{
		s: "你好",
		i: 1,
		b: false,
        p: new(int),
	}

	s2 := S{
		s: "你好",
		i: 1,
		b: false,
		p: new(int),
	}

	fmt.Println(s1 == s2)
    fmt.Println(s1.p)
	fmt.Println(s2.p)
}

//结果
false
0xc000018080
0xc000018088

加了指针类型后依然可以直接比较,但是为什么会返回false呢?因为在初始化s1和s2的时候给p初始化了,两个指针的地址是不同的,导致返回false

如果不给p赋值,则地址为nil,或者赋同一个值,则会返回true,如下

代码语言:javascript
复制
package main

import "fmt"

type S struct {
	s string
	i int
	b bool
	p *int
}

func main() {
	pp := new(int)
	*pp = 123

	s1 := S{
		s: "你好",
		i: 1,
		b: false,
		p: pp,
	}

	s2 := S{
		s: "你好",
		i: 1,
		b: false,
		p: pp,
	}

	fmt.Println(s1 == s2)
	fmt.Println(s1.p)
	fmt.Println(s2.p)
}

//结果
true
0xc00010c008
0xc00010c008

可见此时s1和s2指针的地址是相同的

2.相同结构体+不可比较类型

代码语言:javascript
复制
package main

import "fmt"

type S struct {
	s     string
	i     int
	b     bool
	slice []int
}

func main() {
	s1 := S{
		s:     "你好",
		i:     1,
		b:     false,
		slice: []int{1, 2},
	}

	s2 := S{
		s:     "你好",
		i:     1,
		b:     false,
		slice: []int{1, 2},
	}

    fmt.Println(s1 == s2)
    //此时编译都无法通过,报错误,因为结构体里包含不可比较类型切片 []int
}

//结果
# command-line-arguments
./01_go_struct_compare.go:27:17: invalid operation: s1 == s2 (struct containing []int cannot be compared)

那么有什么办法可以让两个包含不可比较类型的结构体比较吗?可以通过 reflect.DeepEqual 函数

代码语言:javascript
复制
package main

import (
	"fmt"
	"reflect"
)

type S struct {
	s     string
	i     int
	b     bool
	slice []int
}

func main() {
	s1 := S{
		s:     "你好",
		i:     1,
		b:     false,
		slice: []int{1, 2},
	}

	s2 := S{
		s:     "你好",
		i:     1,
		b:     false,
		slice: []int{1, 2},
	}

	fmt.Println(reflect.DeepEqual(s1, s2))
}

//结果
true

reflect.DeepEqual函数深度比较的规则

  • 不同类型的值永远不会完全相等
  • 当数组值的对应元素深度相等时,数组值深度相等
  • 如果结构体的相应字段深度相等,则结构体深度相等
  • 如果func都为nil,则func深度相等,否则不会深度相等
  • 切片深度相等的条件
    • 它们都是 nil 或都非 nil,且具有相同的长度
    • 非 nil 空切片和 nil 切片(例如,[]byte{} 和 []byte(nil))并不完全相等
    • 指向同一底层数组的初始位置要相同(即 &x[0 ] == &y[0]) 或其对应的元素(直到末尾)深度相等
  • 指针深度相等的条件
    • 指针值使用 Go 的 == 运算符相等
    • 它们指向深度相等的值,则它们是深度相等的
  • 映射值map深度相等的条件
    • 它们都是 nil 或都非 nil,且具有相同的长度
    • 它们是相同的映射对象,或者它们对应的键(使用 Go 相等性匹配)映射到深度相等的值

3.不同结构体+可比较类型

可以通过强制类型转换的方式来进行比较

代码语言:javascript
复制
package main

import "fmt"

type S1 struct {
	s string
	i int
	b bool
	p *int
}

type S2 struct {
	s string
	i int
	b bool
	p *int
}

func main() {
	var s1 S1
	var s2 S2

	//s1 = s2 //报错,无法直接赋值
	s3 := S1(s2)
	fmt.Println(s3 == s1)
}

//结果
true

4.不同结构体+不可比较类型

代码语言:javascript
复制
package main

import "fmt"

type S1 struct {
	s string
	i int
	b bool
	p *int
	slice []int
}

type S2 struct {
	s string
	i int
	b bool
	p *int
	slice []int
}

func main() {
	var s1 S1
	var s2 S2

	s3 := S1(s2)
	fmt.Println(s3 == s1)
}

//结果
# command-line-arguments
./02_go_struct_compare.go:26:17: invalid operation: s3 == s1 (struct containing []int cannot be compared)

可见如果结构体里包含了不可比较类型,则无法通过强制类型转换的方式进行比较

5.struct作为map的key

struct里面的类型必须是可比较的,才能作为map的key,否则会报错,无法通过编译

代码语言:javascript
复制
package main

import "fmt"

type S1 struct {
	s string
	i int
	b bool
	p *int
	slice []int
}

func main() {
	m := make(map[S1]string, 0)	//编译出错
	fmt.Println(m)
}

//结果
# command-line-arguments
./02_go_struct_compare.go:27:12: invalid map key type S1
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-01-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.数据类型
  • 2.struct比较
    • 1.相同结构体+可比较类型
      • 2.相同结构体+不可比较类型
        • 3.不同结构体+可比较类型
          • 4.不同结构体+不可比较类型
            • 5.struct作为map的key
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档