go中struct能不能比较

一、map类型的key和value可以是啥类型

  • key 可以是什么类型

        golang 中的 map,的 key 可以是很多种类型,比如 bool, 数字,string, 指针, channel ,  还可以是只包含前面几个类型的 接口, 结构体, 数组

通常key为int string

注意: slice, map  还有 function  不可以,因为这几个没法用 == 来判断

  • valuetype 可以是什么类型

         valuetype 的类型和 key 基本一样,这里我就不再赘述了通常为: 数字(整数,浮点数),string,map,struct

2、值类型(值传递)、引用类型(引用传递)有哪些

       其实,不管是值传递还是引用传递,传递给函数的都是变量的副本,不同的是,值传递的是值的拷贝,引用传递的是地址的拷贝,一般来说,地址拷贝效率高,因为数据量小,而值拷贝决定拷贝的数据大小,数据越大,效率越低。

  1. 值类型 :   基本数据类型 int 系列, float  系列, bool, string 、数组和结构体 struct
  2. 引用类型:指针、slice 切片、map、管道 chan、interface 等都是引用类型

二、golang中,哪些数据类型是可比较的,哪些是不可比较的:

  • 可比较:IntegerFloating-pointStringBooleanComplex(复数型)PointerChannelInterfaceArray
  • 不可比较:SliceMapFunction

struct能不能比较? 很显然这句话包含了两种情况:

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

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

package main

import "fmt"

type Stu struct {
	Name    string
	Age     int
	Address *int
}

func main() {
	i := 10

	a := Stu{
		Name:    "aa",
		Age:     1,
		Address: &i,
	}
	b := Stu{
		Name:    "aa",
		Age:     1,
		Address: &i,
	}

	fmt.Println(a == b)
}

输出结果:(可比较)

在结构体中加上不可比较类型

直接报错

「总结」

同一个struct的两个实例可比较也不可比较,当结构不包含不可直接比较成员变量时可直接比较,否则不可直接比较

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

如果成员变量中含有不可比较成员变量,即使可以强制转换,也不可以比较

三、如果包含不可比较成员变量时,可以使用reflect.DeepEqual 函数来进行比较

Go 语言中提供了一个函数可以完成此项功能:

func DeepEqual(x, y interface{}) bool

DeepEqual 函数的参数是两个 interface,实际上也就是可以输入任意类型,输出 true 或者 flase 表示输入的两个变量是否是“深度”相等。

先明白一点,如果是不同的类型,即使是底层类型相同,相应的值也相同,那么两者也不是“深度”相等。

type MyInt int
type YourInt int

func main() {
	m := MyInt(1)
	y := YourInt(1)

	fmt.Println(reflect.DeepEqual(m, y)) // false
}

上面的代码中,m, y 底层都是 int,而且值都是 1,但是两者静态类型不同,前者是 MyInt,后者是 YourInt,因此两者不是“深度”相等。

在源码里,有对 DeepEqual 函数的非常清楚地注释,列举了不同类型,DeepEqual 的比较情形,这里做一个总结:

类型深度相等情形
Array相同索引处的元素“深度”相等
Struct相应字段,包含导出和不导出,“深度”相等
Func只有两者都是 nil 时
Interface两者存储的具体值“深度”相等
Map1、都为 nil;2、非空、长度相等,指向同一个 map 实体对象,或者相应的 key 指向的 value “深度”相等
Pointer1、使用 == 比较的结果相等;2、指向的实体“深度”相等
Slice1、都为 nil;2、非空、长度相等,首元素指向同一个底层数组的相同元素,即 &x[0] == &y[0] 或者 相同索引处的元素“深度”相等
numbers, bools, strings, and channels使用 == 比较的结果为真

一般情况下,DeepEqual 的实现只需要递归地调用 == 就可以比较两个变量是否是真的“深度”相等。

但是,有一些异常情况:比如 func 类型是不可比较的类型,只有在两个 func 类型都是 nil 的情况下,才是“深度”相等;float 类型,由于精度的原因,也是不能使用 == 比较的;包含 func 类型或者 float 类型的 struct, interface, array 等。

对于指针而言,当两个值相等的指针就是“深度”相等,因为两者指向的内容是相等的,即使两者指向的是 func 类型或者 float 类型,这种情况下不关心指针所指向的内容。

同样,对于指向相同 slice, map 的两个变量也是“深度”相等的,不关心 slice, map 具体的内容。

  • 34
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值