在Go中键入别名与类型定义

ᆼᆺᆼ*_*ᆼᆺᆼ 2 go type-alias

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

type LightSource = struct {
  R, G, B, L float32
  X, Y, Z, A float32
  //...
}
Run Code Online (Sandbox Code Playgroud)

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

type LightSource struct {
  R, G, B, L float32
  //...etc
}
Run Code Online (Sandbox Code Playgroud)

rob*_*b74 8

在这种情况下,我假设这是错误的 - 第一个替代定义了一个"匿名"类型,然后为它分配一个别名,所以最终结果在两种情况下是相同的,但仍然第二个替代是唯一正确的.

类型别名仅在少数情况下有用,例如,如此处所述,它们可用于大规模重构.


And*_*ips 6

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

reflect.DeepEqual(r, map[string]interface{}{"a": map[string]interface{}{"b": 42.0}})
Run Code Online (Sandbox Code Playgroud)

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

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

由于 DeepEqual 使用反射来比较类型(和值),因此将类型别名设置为类型定义(通过删除 = 字符)将导致 DeepEqual 失败。您可以在Go Playground中尝试一下


Eri*_*ang 3


不同之处

  • 有了=,就是alias type。它不会创建新类型,只是创建相同类型的符号。
  • 没有的话=,就是type definition。它创造了一种新类型。

使用中

  • 当给原始类型赋值时:
    • alias type可以直接赋值,无需强制转换。
    • new type需要强制转换,因为它是不同的类型。
  • 方法 onalias type可用于original type; 而方法type definition不能。

例子

type_alias_vs_new_test.go

package main

import "testing"

type (
    A = int // alias type
    B int   // new type
)

func TestTypeAliasVsNew(t *testing.T) {
    var a A = 1 // A can actually be omitted,
    println(a)

    var b B = 2
    println(b)

    var ia int
    ia = a // no need cast,
    println(ia)

    var ib int
    ib = int(b) // need a cast,
    println(ib)
}
Run Code Online (Sandbox Code Playgroud)