【Go常见错误】3. 比较不正确的值

概念

比较值是非常常见的操作。

常规都会使用 == 操作符,但在有些类型情况下会出现意想不到的错误。

错误案例

type customer struct {
  id string
  operations []float64
}

func main() {
  cust1 := customer{id: "x", operations: []float64{1.5}}
  cust2 := customer{id: "x", operations: []float64{1.5}}
  fmt.Println(cust1 == cust2)
}

我们期望这段代码也能够输出true。然而,它甚至都没有编译通过:

invalid operation: cust1 == cust2 (struct containing []float64 cannot be compared)

如果两种类型具有可比较性,那我们可以使用这两种运算符(==和!=)来比较两种不同的类型。

在Go中可比较的类型包括

  • 布尔值:== 和 != 可以比较两个布尔类型的值是否相等

  • 数字:== 和 != 可以比较两个数字类型的值是否相等。如果两个值具有相同的类型或能够转成成相同的类型,那么这两个操作也是可以正常编译的。

  • 字符串:== 和 != 可以比较两个字符串是否相等。我们可以根据字符串的词序使用>=, < 和 > 操作符对两个字符串进行比较。

  • 指针:== 和 != 可以比较两个指针是否指向了相同的内存地址或者是否都是nil。

  • 通道(channels):== 和 != 可以比较两个通道是否是由同一个make创建的或者两个都是nil

所以,在该列表中没有map和slice

如果struct和array仅有可比较的类型组成,我们也可以将他们添加到此列表中

另外,特别注意interface{}类型中使用 == 和 !=操作符可能存在的问题。它将导致一个运行时panic:

panic: runtime error: comparing uncomparable type main.customer

解决方法

如果我们不得不对slice、map、或者包含不能比较类型的struct进行比较的时候,该怎么办呢?

1. 使用标准库的方法

比如 如果想比较两个字节切片,我们可以使用bytes.Compare函数。

2. 使用反射和reflect.DeepEqual

该方法会比较两个元素是否是深度相等的。该函数接受的元素是基本类型,数组,结构体,切片(slice),map,指针,接口和函数。

注:由于此函数使用反射,因此会有性能方面的损耗。在本地使用不同大小的结构体进行一些基准测试,reflect.DeepEqual的平均执行速度要比 == 操作符慢100倍。

3. 实现自定义的比较的方法

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值