美文网首页
go 比较性问题总结

go 比较性问题总结

作者: wayyyy | 来源:发表于2022-09-09 00:02 被阅读0次

在 Go 中,数据类型按照比较性可被分为两类:

  • 可比较类型,可比较类型可以使用运算符==和!=
  • 不可比较类型,如果使用==或!=进行运算,那么会产生 panic
Boolean、Integer、Floating-point、Complex、String

Boolean(布尔值)、Integer(整型)、Floating-point(浮点数)、Complex(复数)、String(字符)这些类型可直接比较。

指针

指针可以比较。

数组

在长度和类型相同的数组是可以比较,长度不同或者类型不同的数组不能比较

slice

slice是不可以比较的,但是可以与 nil 进行比较。

map

map是不可以比较的,但是可以与 nil 进行比较。

function

function 是不可以比较的,但是可以与 nil 进行比较。

channel

channel是可以比较的,如果两个通道值是由同一个 make 调用创建的,则它们相等。

struct 的比较
  • 同一 struct 的实例可以比较吗?

    type S struct {
        Name    string
        Age     int
        Address *int
    }
    
    func main() {
        a := S{Name: "aa", Age: 1, Address: new(int)}
        b := S{Name: "aa", Age: 1, Address: new(int)}
        fmt.Println(a == b) // 输出false
    }
    

    如果给结构体S增加一个Slice类型的成员变量后又是什么情况呢?

    type S struct {
        Name    string
        Age     int
        Address *int
        Nums    []int
    }
    
    func main() {
        a := S{Name: "aa", Age: 1, Address: new(int), Nums: []int{1, 2, 3, 4}}
        b := S{Name: "aa", Age: 1, Address: new(int), Nums: []int{1, 2, 3, 4}}
        fmt.Println(a == b) // invalid operation: a == b (struct containing []int cannot be compared)
    }
    

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

  • reflect.DeepEqual
    当需要对含有不可直接比较的数据类型的结构体实例进行比较时,我们可以借助 reflect.DeepEqual 函数 来对两个变量进行比较:

    type S struct {
        Name    string
        Age     int
        Address *int
        Nums    []int
    }
    
    func main() {
        a := S{Name: "aa", Age: 1, Address: new(int), Nums: []int{1, 2, 3, 4}}
        b := S{Name: "aa", Age: 1, Address: new(int), Nums: []int{1, 2, 3, 4}}
        fmt.Println(reflect.DeepEqual(a, b)) // 输出为true
    }
    
interface 比较

interface 在某些场景下可以比较。

  • 不带方法的 interface:
    type Fooer interface {
    }
    
    type Barer interface {
    }
    
    func main() {
        var foo Fooer
        var bar Barer
        fmt.Println(foo == bar) // 输出true
    
        fooInstance := 1
        barInstance := 1
        fmt.Println(fooInstance == barInstance) // 输出为true
    
        fooInstance2 := 1
        barInstance2 := 10
        fmt.Println(fooInstance2 == barInstance2) // 输出为false
    }
    
  • 带有方法的 interface,且方法名相同:
    type Fooer interface {
        value() int
    }
    
    type Barer interface {
        value() int
    }
    
    type Foo int
    
    func (foo Foo) value() int {
        return 1
    }
    
    type Bar int
    
    func (bar Bar) value() int {
        return 1
    }
    
    func main() {
        var foo Fooer
        var bar Barer
        fmt.Println(foo == bar) // 输出true
    
        fooInstance := Foo(10)
        barInstance := Bar(10)
        fmt.Println(fooInstance == barInstance) // invalid operation: fooInstance == barInstance (mismatched types Foo and Bar)
    }
    
  • 带有方法的 interface,且方法名不同:
    type Fooer interface {
        FooerValue() int
    }
    
    type Barer interface {
        BarerValue() int
    }
    
    type Foo int
    
    func (foo Foo) FooerValue() int {
        return 1
    }
    
    type Bar int
    
    func (bar Bar) BarerValue() int {
        return 1
    }
    
    func main() {
        var foo Fooer
        var bar Barer
        fmt.Println(foo == bar) // invalid operation: foo == bar (mismatched types Fooer and Barer)
    
        fooInstance := Foo(10)
        barInstance := Bar(10)
        fmt.Println(fooInstance == barInstance) // invalid operation: fooInstance == barInstance (mismatched types Foo and Bar)
    }
    
  • interface 和 nil 比较
    type Fooer interface {
        FooerValue() int
    }
    
    type Foo int
    
    func (foo Foo) FooerValue() int {
            return 1
    }
    
    func main() {
        var foo Fooer
        fmt.Println(nil == foo) // true
    
        fooInstance := Foo(10)
        fmt.Println(nil == fooInstance) // invalid operation: fooInstance == barInstance (mismatched types Foo and Bar)
    }
    

相关文章

网友评论

      本文标题:go 比较性问题总结

      本文链接:https://www.haomeiwen.com/subject/cpewnrtx.html