How does 'type DoNotCompare [0]func()' prevent comparability in Golang

huangapple go评论83阅读模式
英文:

How does 'type DoNotCompare [0]func()' prevent comparability in Golang

问题

根据您提供的代码,DoNotCompare 是一个空数组类型 [0]func(),它可以嵌入到结构体中以防止比较。但是,根据您的代码示例,NonCompare 结构体似乎是可比较的。

根据我理解,DoNotCompare 的作用是通过将其嵌入到结构体中,阻止该结构体进行比较操作。然而,在您的代码示例中,并没有直接使用 DoNotCompare 进行比较,而是使用了 NonCompare 结构体的方法 Compare 进行比较。

因此,根据您的代码示例,NonCompare 结构体仍然是可比较的,而 DoNotCompare 并没有起到阻止比较的作用。可能是您在代码中有其他的实现或使用方式导致了这种情况。

英文:

Per protobuf pragma

> ```
> type DoNotCompare [0]func()
> DoNotCompare can be embedded in a struct to prevent comparability

I am confused why DoNotCompare could prevent comparability, and try to understand with the following codes. Unfortunately, I am failed. The NonCompare struct seems could be comparability.

type DoNotCompare [0]func()

type NonCompare struct {
	DoNotCompare

	ii int8
}

type Comparer interface {
	Compare(b NonCompare) int
}

func (a NonCompare) Compare(b NonCompare) int {
	if a.ii > b.ii {
		return 1
	}
	return 0
}

func main() {
	var nc1 = NonCompare{ii: 3}
	var nc2 = NonCompare{ii: 5}

	nc1.Compare(nc2)

Is there anything am I missing?

答案1

得分: 3

预防措施适用于内置的==运算符,而不是你的Compare()方法。当然,它可以执行任何你想要的操作。

但是,如果你尝试使用==

fmt.Println(nc1 == nc2)

你会得到一个编译时错误:

./prog.go:30:18: invalid operation: nc1 == nc2 (struct containing DoNotCompare cannot be compared)

原因是func()类型的值(或任何函数类型的值)是不可比较的,所以[0]func()类型的值也是不可比较的。而且,包含非可比较类型字段的结构体也是不可比较的。规则在规范:比较运算符中列出:

> 相等运算符==!=适用于可比较的操作数。排序运算符<<=>>=适用于有序的操作数。这些术语和比较的结果定义如下:
>
> - [...]
> - 如果结构体的所有字段都是可比较的,则结构体值是可比较的。如果对应的非空白标识符字段相等,则两个结构体值相等。
> - 如果数组元素类型的值是可比较的,则数组值是可比较的。如果对应的元素相等,则两个数组值相等。
>
> [...] 切片、映射和函数值是不可比较的。

使用大小为0的数组,这样字段的大小将为0,在使用它的结构体中不会添加任何额外的内容。请注意,这仅在将大小为0的字段放在第一位置时才能保证。详细信息请参见https://stackoverflow.com/questions/34219232/struct-has-different-size-if-the-field-order-is-different/34219916#34219916。

英文:

The prevention works on the builtin == operator, not on what your Compare() method does. Of course it can do whatever you want it to.

But if you try to use ==:

fmt.Println(nc1 == nc2)

You get a compile-time error:

./prog.go:30:18: invalid operation: nc1 == nc2 (struct containing DoNotCompare cannot be compared)

The reason is because values of func() type (or any function type) are not comparable, so [0]func() values are also not comparable. And structs having a field of a non-comparable type are also not comparable. Rules are listed at Spec: Comparison operators:

> The equality operators == and != apply to operands that are comparable. The ordering operators <, <=, >, and >= apply to operands that are ordered. These terms and the result of the comparisons are defined as follows:
>
> - [...]
> - Struct values are comparable if all their fields are comparable. Two struct values are equal if their corresponding non-blank fields are equal.
> - Array values are comparable if values of the array element type are comparable. Two array values are equal if their corresponding elements are equal.
>
> [...] Slice, map, and function values are not comparable.

An array of size 0 is used so the field's size will be 0, not adding anything extra to the struct it is used in. Please note this is only guaranteed if you place 0-size fields to the first place. For details see https://stackoverflow.com/questions/34219232/struct-has-different-size-if-the-field-order-is-different/34219916#34219916.

huangapple
  • 本文由 发表于 2022年2月8日 17:12:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/71031243.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定