Go 中的类型别名与类型定义

Type alias vs type definition in Go

我在代码中偶然发现了这个类型别名:

type LightSource = struct {
  R, G, B, L float32
  X, Y, Z, A float32
  //...
}

我的问题是:使用这样的类型别名来定义struct而不是这样做的原因是什么?

type LightSource struct {
  R, G, B, L float32
  //...etc
}

在这种情况下,我认为这是错误的 - 第一种选择定义了一个类型 "anonymously" 然后为其分配了一个别名,因此两种情况下的最终结果是相同的,但仍然是第二种备选方案是唯一正确的。

类型别名仅在少数情况下有用,例如如所写 here,它们可用于大规模重构。

我发现类型别名对提高可读性很有用。例如,在测试中,您可以像这样比较 JSON 解码器的输出:

reflect.DeepEqual(r, map[string]interface{}{"a": map[string]interface{}{"b": 42.0}})

但您可以使用类型别名来提高可读性:

type JsonObject = map[string]interface{}
...
reflect.DeepEqual(r, JsonObject{"a": JsonObject{"b": 42.0}})

因为 DeepEqual 使用反射来比较类型(和值)然后使类型别名成为类型定义(通过删除 = 字符)将导致 DeepEqual 失败。您可以在 Go Playground

中尝试

添加到 Rob64 的回答中,他说最终结果是相同的,但不要误解这样一个事实,即您最终会得到两种不同的类型。

type LightSource = struct { // Type struct
  R, G, B, L float32
  X, Y, Z, A float32
  //...
}
type LightSource struct { // Type LightSource
  R, G, B, L float32
  //...etc
}

我觉得你最终会得到一个不同的类型这一事实会引起很多混淆,这意味着如果你在代码中的某处强制执行类型 A,并且你使用了错误的类型别名方式,您最终将对“类型别名”绝对零限制;如果您最终创建了类型别名,end-goal 确实可以区分您的类型,但如果您犯了这个错误,那显然是无效的。

Go play<<