go cmp 源码

  • 2022-07-15
  • 浏览 (891)

golang cmp 代码

文件路径:/test/cmp.go

// run

// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Test equality and inequality operations.

package main

import (
	"os"
	"unsafe"
)

var global bool

func use(b bool) { global = b }

func stringptr(s string) uintptr { return *(*uintptr)(unsafe.Pointer(&s)) }

func isfalse(b bool) {
	if b {
		// stack will explain where
		panic("wanted false, got true")
	}
}

func istrue(b bool) {
	if !b {
		// stack will explain where
		panic("wanted true, got false")
	}
}

type T *int

type X int

func (X) x() {}

func main() {
	var a []int
	var b map[string]int

	var c string = "hello"
	var d string = "hel" // try to get different pointer
	d = d + "lo"

	// go.tools/ssa/interp can't handle unsafe.Pointer.
	if os.Getenv("GOSSAINTERP") == "" {
		if stringptr(c) == stringptr(d) {
			panic("compiler too smart -- got same string")
		}
	}

	var e = make(chan int)

	var ia interface{} = a
	var ib interface{} = b
	var ic interface{} = c
	var id interface{} = d
	var ie interface{} = e

	// these comparisons are okay because
	// string compare is okay and the others
	// are comparisons where the types differ.
	isfalse(ia == ib)
	isfalse(ia == ic)
	isfalse(ia == id)
	isfalse(ib == ic)
	isfalse(ib == id)
	istrue(ic == id)
	istrue(ie == ie)

	istrue(ia != ib)
	istrue(ia != ic)
	istrue(ia != id)
	istrue(ib != ic)
	istrue(ib != id)
	isfalse(ic != id)
	isfalse(ie != ie)

	// these are not okay, because there is no comparison on slices or maps.
	//isfalse(a == ib)
	//isfalse(a == ic)
	//isfalse(a == id)
	//isfalse(b == ic)
	//isfalse(b == id)

	istrue(c == id)
	istrue(e == ie)

	//isfalse(ia == b)
	isfalse(ia == c)
	isfalse(ia == d)
	isfalse(ib == c)
	isfalse(ib == d)
	istrue(ic == d)
	istrue(ie == e)

	//istrue(a != ib)
	//istrue(a != ic)
	//istrue(a != id)
	//istrue(b != ic)
	//istrue(b != id)
	isfalse(c != id)
	isfalse(e != ie)

	//istrue(ia != b)
	istrue(ia != c)
	istrue(ia != d)
	istrue(ib != c)
	istrue(ib != d)
	isfalse(ic != d)
	isfalse(ie != e)

	// gc used to let this go through as true.
	var g uint64 = 123
	var h int64 = 123
	var ig interface{} = g
	var ih interface{} = h
	isfalse(ig == ih)
	istrue(ig != ih)

	// map of interface should use == on interface values,
	// not memory.
	var m = make(map[interface{}]int)
	m[ic] = 1
	m[id] = 2
	if m[c] != 2 {
		println("m[c] = ", m[c])
		panic("bad m[c]")
	}

	// interface comparisons (issue 7207)
	{
		type I1 interface {
			x()
		}
		type I2 interface {
			x()
		}
		a1 := I1(X(0))
		b1 := I1(X(1))
		a2 := I2(X(0))
		b2 := I2(X(1))
		a3 := I1(a2)
		a4 := I2(a1)
		var e interface{} = X(0)
		a5 := e.(I1)
		a6 := e.(I2)
		isfalse(a1 == b1)
		isfalse(a1 == b2)
		isfalse(a2 == b1)
		isfalse(a2 == b2)
		istrue(a1 == a2)
		istrue(a1 == a3)
		istrue(a1 == a4)
		istrue(a1 == a5)
		istrue(a1 == a6)
		istrue(a2 == a3)
		istrue(a2 == a4)
		istrue(a2 == a5)
		istrue(a2 == a6)
		istrue(a3 == a4)
		istrue(a3 == a5)
		istrue(a3 == a6)
		istrue(a4 == a5)
		istrue(a4 == a6)
		istrue(a5 == a6)
	}

	// non-interface comparisons
	{
		c := make(chan int)
		c1 := (<-chan int)(c)
		c2 := (chan<- int)(c)
		istrue(c == c1)
		istrue(c == c2)
		istrue(c1 == c)
		istrue(c2 == c)

		isfalse(c != c1)
		isfalse(c != c2)
		isfalse(c1 != c)
		isfalse(c2 != c)

		d := make(chan int)
		isfalse(c == d)
		isfalse(d == c)
		isfalse(d == c1)
		isfalse(d == c2)
		isfalse(c1 == d)
		isfalse(c2 == d)

		istrue(c != d)
		istrue(d != c)
		istrue(d != c1)
		istrue(d != c2)
		istrue(c1 != d)
		istrue(c2 != d)
	}

	// named types vs not
	{
		var x = new(int)
		var y T
		var z T = x

		isfalse(x == y)
		istrue(x == z)
		isfalse(y == z)

		isfalse(y == x)
		istrue(z == x)
		isfalse(z == y)

		istrue(x != y)
		isfalse(x != z)
		istrue(y != z)

		istrue(y != x)
		isfalse(z != x)
		istrue(z != y)
	}

	// structs
	{
		var x = struct {
			x int
			y string
		}{1, "hi"}
		var y = struct {
			x int
			y string
		}{2, "bye"}
		var z = struct {
			x int
			y string
		}{1, "hi"}

		isfalse(x == y)
		isfalse(y == x)
		isfalse(y == z)
		isfalse(z == y)
		istrue(x == z)
		istrue(z == x)

		istrue(x != y)
		istrue(y != x)
		istrue(y != z)
		istrue(z != y)
		isfalse(x != z)
		isfalse(z != x)

		var m = make(map[struct {
			x int
			y string
		}]int)
		m[x] = 10
		m[y] = 20
		m[z] = 30
		istrue(m[x] == 30)
		istrue(m[y] == 20)
		istrue(m[z] == 30)
		istrue(m[x] != 10)
		isfalse(m[x] != 30)
		isfalse(m[y] != 20)
		isfalse(m[z] != 30)
		isfalse(m[x] == 10)

		var m1 = make(map[struct {
			x int
			y string
		}]struct {
			x int
			y string
		})
		m1[x] = x
		m1[y] = y
		m1[z] = z
		istrue(m1[x] == z)
		istrue(m1[y] == y)
		istrue(m1[z] == z)
		istrue(m1[x] == x)
		isfalse(m1[x] != z)
		isfalse(m1[y] != y)
		isfalse(m1[z] != z)
		isfalse(m1[x] != x)

		var ix, iy, iz interface{} = x, y, z

		isfalse(ix == iy)
		isfalse(iy == ix)
		isfalse(iy == iz)
		isfalse(iz == iy)
		istrue(ix == iz)
		istrue(iz == ix)

		isfalse(x == iy)
		isfalse(y == ix)
		isfalse(y == iz)
		isfalse(z == iy)
		istrue(x == iz)
		istrue(z == ix)

		isfalse(ix == y)
		isfalse(iy == x)
		isfalse(iy == z)
		isfalse(iz == y)
		istrue(ix == z)
		istrue(iz == x)

		istrue(ix != iy)
		istrue(iy != ix)
		istrue(iy != iz)
		istrue(iz != iy)
		isfalse(ix != iz)
		isfalse(iz != ix)

		istrue(x != iy)
		istrue(y != ix)
		istrue(y != iz)
		istrue(z != iy)
		isfalse(x != iz)
		isfalse(z != ix)

		istrue(ix != y)
		istrue(iy != x)
		istrue(iy != z)
		istrue(iz != y)
		isfalse(ix != z)
		isfalse(iz != x)
	}

	// structs with _ fields
	{
		var x = struct {
			x int
			_ string
			y float64
			_ float64
			z int
		}{
			x: 1, y: 2, z: 3,
		}
		var ix interface{} = x

		istrue(x == x)
		istrue(x == ix)
		istrue(ix == x)
		istrue(ix == ix)
	}

	// arrays
	{
		var x = [2]string{"1", "hi"}
		var y = [2]string{"2", "bye"}
		var z = [2]string{"1", "hi"}

		isfalse(x == y)
		isfalse(y == x)
		isfalse(y == z)
		isfalse(z == y)
		istrue(x == z)
		istrue(z == x)

		istrue(x != y)
		istrue(y != x)
		istrue(y != z)
		istrue(z != y)
		isfalse(x != z)
		isfalse(z != x)

		var m = make(map[[2]string]int)
		m[x] = 10
		m[y] = 20
		m[z] = 30
		istrue(m[x] == 30)
		istrue(m[y] == 20)
		istrue(m[z] == 30)
		isfalse(m[x] != 30)
		isfalse(m[y] != 20)
		isfalse(m[z] != 30)

		var ix, iy, iz interface{} = x, y, z

		isfalse(ix == iy)
		isfalse(iy == ix)
		isfalse(iy == iz)
		isfalse(iz == iy)
		istrue(ix == iz)
		istrue(iz == ix)

		isfalse(x == iy)
		isfalse(y == ix)
		isfalse(y == iz)
		isfalse(z == iy)
		istrue(x == iz)
		istrue(z == ix)

		isfalse(ix == y)
		isfalse(iy == x)
		isfalse(iy == z)
		isfalse(iz == y)
		istrue(ix == z)
		istrue(iz == x)

		istrue(ix != iy)
		istrue(iy != ix)
		istrue(iy != iz)
		istrue(iz != iy)
		isfalse(ix != iz)
		isfalse(iz != ix)

		istrue(x != iy)
		istrue(y != ix)
		istrue(y != iz)
		istrue(z != iy)
		isfalse(x != iz)
		isfalse(z != ix)

		istrue(ix != y)
		istrue(iy != x)
		istrue(iy != z)
		istrue(iz != y)
		isfalse(ix != z)
		isfalse(iz != x)
	}

	// named booleans
	{
		type mybool bool
		var b mybool

		type T struct{ data [20]byte }
		var x, y T
		b = x == y
		istrue(x == y)
		istrue(bool(b))

		m := make(map[string][10]interface{})
		b = m["x"] == m["y"]
		istrue(m["x"] == m["y"])
		istrue(bool(b))
	}

	shouldPanic(p1)
	shouldPanic(p2)
	shouldPanic(p3)
	shouldPanic(p4)
}

func p1() {
	var a []int
	var ia interface{} = a
	use(ia == ia)
}

func p2() {
	var b []int
	var ib interface{} = b
	use(ib == ib)
}

func p3() {
	var a []int
	var ia interface{} = a
	var m = make(map[interface{}]int)
	m[ia] = 1
}

func p4() {
	var b []int
	var ib interface{} = b
	var m = make(map[interface{}]int)
	m[ib] = 1
}

func shouldPanic(f func()) {
	defer func() {
		if recover() == nil {
			panic("function should panic")
		}
	}()
	f()
}

相关信息

go 源码目录

相关文章

go 235 源码

go 64bit 源码

go alg 源码

go alias 源码

go alias1 源码

go alias2 源码

go alias3 源码

go align 源码

go append 源码

go append1 源码

0  赞