Go 中的类型别名和类型定义有什么区别?

Vik*_*dav 18 go type-alias type-definition

类型别名:

type A = string
Run Code Online (Sandbox Code Playgroud)

类型定义:

type A string
Run Code Online (Sandbox Code Playgroud)

它们之间有什么区别?我无法从规范中理解

Pau*_*kin 20

type A = string创建别名string. 每当您A在代码中使用时,它的工作方式就像string. 例如,您不能在其上定义方法。

type A string定义了一个新类型,它与 具有相同的表示形式string。您可以以零成本在A和 之间进行转换string(因为它们是相同的),但您可以在新类型上定义方法,并且反射将了解该类型A

例如(在操场上)

package main

import (
    "fmt"
)

type A = string
type B string

func main() {
    var a A = "hello"
    var b B = "hello"
    fmt.Printf("a is %T\nb is %T\n", a, b)
}
Run Code Online (Sandbox Code Playgroud)

输出:

a is string
b is main.B
Run Code Online (Sandbox Code Playgroud)


Gri*_*kin 6

为了明确起见,这两者都是类型声明

type A = string
Run Code Online (Sandbox Code Playgroud)

这称为别名声明。即您创建类型的别名。基本上,类型和别名之间没有区别。您可以在别名上定义方法,它们将可用于初始类型实例。例子

type A struct {}

type B = A

func (B) print() {
    fmt.Println("B")
}

func main() {
    a := A{}
    b := B{}

    a.print()  // OUTPUT: B
    b.print()  // OUTPUT: B
}
Run Code Online (Sandbox Code Playgroud)

虽然,在您的特定示例中type A = string,您无法在其上定义方法,因为字符串是非本地类型(有人提议添加为非本地类型创建方法的功能,但它被拒绝了)。

你的第二种情况type A string是类型定义。基本上,它正在创建具有原始类型的所有字段的新类型,但不具有它的方法。例子

type A struct {}

func (A) print() {
    fmt.Println("A")
}

type B A

func (B) print() {
    fmt.Println("B")
}

func main() {
    a := A{}
    b := B{}

    a.print()  // OUTPUT: A
    b.print()  // OUTPUT: B
}
Run Code Online (Sandbox Code Playgroud)