美文网首页
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