代码之家  ›  专栏  ›  技术社区  ›  vtm11

[0]func()作为“不比较”sentinel-type

go
  •  0
  • vtm11  · 技术社区  · 1 年前

    什么类型 'do not compare' sentinel 在结构定义中?

    type SomeStruct struct {
        _ [0]func() // do not compare
        ...
    }
    

    究竟是什么 [0]func() ? 的零长度切片 func() 物体?还有别的吗?

    1 回复  |  直到 1 年前
        1
  •  2
  •   Elias Van Ootegem    1 年前

    好吧,考虑到我的评论,不妨将其视为一个答案:

    _ [0]func()
    

    将作为类型的未命名字段读取 [0]func() 。它不是一个切片,而是一个数组。切片就是 _ []func 在这种情况下,数组类型的长度为0,因此实际上是一个空类型。你不能在里面储存任何东西。此字段仅用于一个目的:

    因为函数类型的任何字段、变量或其他名称根据定义都是不可比较的,并且根据规范,任何包含无法比较的字段的结构/类型都将变得完全不可比较。正在添加 _ [0]func() 因此,对于任何类型,这样做的代码都会产生编译时错误:

    type Base struct {
        Foo uint64
    }
    
    type SomeStruct struct {
        _ [0]func()
        Base // embedded
    }
    
    func main() {
        a, b := Base{Foo: 123}, Base{Foo: 123}
        fmt.Println(a == b) // works
        safeA, safeB := SomeStruct{Base: a}, SomeStruct{Base: b}
        fmt.Println(safeA == safeB) // compiler error
    }
    

    Demo here

    使用的原因 [0]函数() 而不是 func() []func 也就是说,当结构中的第一个字段的大小为零(我们只能在编译时知道数组的大小,而不能知道片的大小)时,它们会占用内存中的0个字节。A. 函数() 类型的大小不会被视为零字节,因此要回答您的最后一个问题:

    _[0]函数() 而不是 _ func() 出于优化原因。