• Golang中用==判断是否相等


    本文介绍Go语言中 == 在一些常见场景下的判断逻辑。

    基础类型与指针

    对于基础类型和指针,== 符号都是直接判断值是否相等。

    因为指针的值实际上是内存地址,所以对于指针是否相等的判断和c语言一样都是看指针是否指向同一个内存地址

    // 基础类型: int, string等, 都是值比较
    var i1 = 2
    var i2 = 2
    var s1 = "hello"
    var s2 = "hello"
    fmt.Println(i1 == i2 && s1 == s2) // true
    fmt.Println(&i1 == &i2 || &s1 == &s2) // false
    
    // 指针类型: 地址比较
    var p1 = &i1
    var p2 = &i2
    var p3 = &i1
    fmt.Println(p1 == p2) // false
    fmt.Println(p1 == p3) // true
    

    struct

    1. 两个不同的类型的值之间不能比较
    2. 相同类型的值进行比较时,根据结构体中每一项是否相等来判断值是否相等(如果结构体中嵌套子结构体,也会用相同的逻辑去比较子结构体)
    type B struct {
    	B1 int
    	B2 int
    }
    
    type A struct {
    	A1 int
    	Bc B
    }
    
    type C A
    
    func main() {
    	a1 := A{A1: 1, Bc: B{B1: 1, B2: 1}}
    	a2 := A{A1: 1, Bc: B{B1: 1, B2: 1}}
    	a3 := A{A1: 1, Bc: B{B1: 1, B2: 2}}
    	fmt.Println(a1 == a2)   // true
    	fmt.Println(a2 == a3)   // false
    	fmt.Println(&a1 == &a2) // false
    
    	c := C{A1: 1, Bc: B{B1: 1, B2: 2}}
    	fmt.Println(c == a3) // cannot compare c == a3 (mismatched types C and A)
    }
    

    interface

    判断interface是否相等时,会分别判断

    1. 值的类型是否相同
    2. 值是否相同
    type A int
    type B = A
    type C int
    type I interface{ m() }
    
    func (a A) m() {}
    func (c C) m() {}
    func main() {
    	// A, B 是相同类型, C和A,B是不同类型
    	var a I = A(1)
    	var a1 I = A(2)
    	var b I = B(1)
    	var c I = C(1)
    	fmt.Println(a == b)  // true
    	fmt.Println(a == a1) // false, 类型相同值不同
    	fmt.Println(b == c)  // false, 类型不同
    }
    

    chan

    两个channel如果要相等,有两种情况

    1. 都为nil
    2. chan结构体中的值完全相等
    var ch1, ch2 chan int
    fmt.Println(ch1 == ch2) // true
    
    ch1 = make(chan int)
    ch2 = make(chan int)
    fmt.Println(ch1 == ch2)   // false
    ch2 = ch1                 // 发生了chan结构体的复制, ch2和ch1结构体虽然位于不同的地址, 但结构体中的值(包括一些指针的值)是完全相等的
    fmt.Println(ch1 == ch2)   // true
    fmt.Println(&ch1 == &ch2) // false, 它们指向不同的地址
    

    array

    要求

    1. 数组长度相同
    2. 数组中每一项的值相同
    type T struct {
    	name string
    	age  int
    	_    float64
    }
    
    func main() {
    	x := [...]float64{1.1, 2, 3.14}
    	fmt.Println(x == [...]float64{1.1, 2, 3.14}) // true
    	y := [1]T{{"foo", 1, 0}}
    	fmt.Println(y == [1]T{{"foo", 1, 1}}) // true
    }
    

    不可用 == 比较的类型 func, slice, map

    它们即使类型相同也不能用==相互比较,它们只能和nil用 == 比较

    func main() {
    	f := func(int) int { return 1 }
    	// g := func(int) int { return 2 }
    	// f == g // cannot compare f == g (operator == not defined for func(int) int)
    
    	m1 := make(map[int]int)
    	// m2 := make(map[int]int)
    	// m1 == m2 // cannot compare m1 == m2 (operator == not defined for map[int]int)
    
    	var slice1 []int
    	// var slice2 []int
    	// slice1 == slice2 // cannot compare slice1 == slice2 (operator == not defined for []int)
    
    	fmt.Println(f == nil)      // false
    	fmt.Println(m1 == nil)     // false
    	fmt.Println(slice1 == nil) // true
    }
    

    reflect.DeepEqual

    对于map和slice,可以用reflect.DeepEqual来比较是否相等

    m1 := make(map[int]int)
    m2 := make(map[int]int)
    fmt.Println(reflect.DeepEqual(m1, m2)) // true
    
    var slice1 []int = []int{1, 2, 3}
    var slice2 []int = []int{1, 2, 3}
    fmt.Println(reflect.DeepEqual(slice1, slice2)) // true
    

    但对于func类型,需要用reflect.TypeOf来判断函数是否相同

    f := func(int) int { return 1 }
    g := func(int) int { return 1 }
    fmt.Println(reflect.DeepEqual(f, g))                // false
    fmt.Println(reflect.TypeOf(f) == reflect.TypeOf(g)) // true
    

    参考: https://medium.com/golangspec/equality-in-golang-ff44da79b7f1

  • 相关阅读:
    WebClien简单示例(一)
    关于WQS二分算法以及其一个细节证明
    Scut游戏服务器免费开源框架快速开发(1)
    Scut游戏服务器免费开源框架快速开发(3)
    Scut游戏服务器免费开源框架快速开发(2)
    Struts中的 saveToken的方法
    CKEditor 3.6
    Oracle 笔记 day01
    Oracle日期格式问题
    Oracle 笔记 day03
  • 原文地址:https://www.cnblogs.com/elimsc/p/15880307.html
Copyright © 2020-2023  润新知