Golang几种对象比较方法

Golang几种对象比较方法

本文讨论下Go中对象比较,分别为==、第三方包github.com/google/go-cmp/cmp中cmp.Equal()方法、reflect.DeepEqual()以及自定义isEqual()方法。

1. 环境准备

为了演示,这里定义简单Person结构体以及NewPerson方法创建对象。

type Person struct {
	Name string
	Age int
}

func NewPerson(name string, age int) *Person {
	return &Person{
		Name: name,
		Age:  age,
	}
}

接着在main函数中创建两个对象,然后分别调用不同的比较方法:

func main() {
	Admin1 := NewPerson("Admin", 18)
	Admin2 := NewPerson("Admin", 18)

	Compare1(Admin1, Admin2)
	Compare2(Admin1, Admin2)
	Compare3(Admin1, Admin2)
	IsEqual(Admin1, Admin2)
}

我们再定义衡量执行函数,用于比较性能:

func execTime(compareType string, start time.Time)  {
	var elapsed = time.Since(start)
	log.Printf("%s took %s \n", compareType, elapsed)
}

1.1 == 比较

直接使用==,我们知道这实际在比较对象地址,不会相等。

func Compare1(p1 , p2 *Person)  {
	defer execTime("'==' took ", time.Now())

	if p1 == p2{
		fmt.Printf("== \n")
	} else {
		fmt.Printf("!= \n")
	}
}

1.2 使用cmp.Equal()

func Compare2(p1 , p2 *Person)  {
	defer execTime("cmp.Equal took ", time.Now())

	if cmp.Equal(p1,p2) {
		fmt.Printf("== \n")
	} else {
		fmt.Printf("!= \n")
	}
}

这里是比较对象内容,结果相等。

1.3 使用reflect.DeepEqual()

func Compare3(p1 , p2 *Person)  {
	defer execTime("DeepEqual took ", time.Now())

	if reflect.DeepEqual(p1, p2){
		fmt.Printf("== \n")
	} else {
		fmt.Printf("!= \n")
	}
}

这种方式也是比较对象属性值,结果相等。

1.4 自定义比较方法

func IsEqual(A, B interface{}) bool {
	defer execTime("IsEqual took", time.Now())
	// Find out the type of A & B is Person or not
	if _, ok := A.(*Person); ok {
		if _, ok := B.(*Person); ok {
			if A.(*Person).Name == B.(*Person).Name {
				fmt.Printf("== \n")
				return A.(*Person).Age == B.(*Person).Age
			} else {
				return false
			}
		}
		return false
	}
	return false
}

方法首先检查参数类型,然后依次比较对象属性值。

2. 运行结果与效率

运行结果与之前预期一致,除了第一种方法不相等,其他都相等。同时我们观察执行时间,平均比较还是自定义效率比较高。

2020/07/09 20:44:20 '==' took  took 8.0004ms
2020/07/09 20:44:21 cmp.Equal took  took 16.0009ms
2020/07/09 20:44:21 DeepEqual took  took 1.0001ms
2020/07/09 20:44:21 IsEqual took took 0s

3. 总结

本文介绍了四种Golang的对象比较方法,其中==只能比较对象地址,不能比较属性值是否相等。其他三种方法能够比较对象属性值,从执行效率来看,自定义比较方式有优势。

你可能感兴趣的:(Golang)