对类型别名的行为感到困惑

sco*_*eus 2 types go

考虑以下代码(也在Playground上):

package main

import (
    "fmt"
    "time"
)

type dur struct {
    time.Duration
}

type durWithMethods dur

type durWithoutMethods time.Duration

func main() {
    var d durWithMethods // works ??
    fmt.Println(d.String())
    
    var dWM durWithoutMethods
    fmt.Println(dWM.String()) // doesn't compile
}
Run Code Online (Sandbox Code Playgroud)

我不明白为什么 的直接别名time.Duration不继承任何方法。是因为time.Duration是原始类型的别名吗?

icz*_*cza 7

类型声明有两种形式:别名声明和类型定义。

类型定义创建一个新类型并删除所有方法。类型别名“just”创建(绑定)一个新的标识符到相同的类型。使用“原始”名称或新名称是相同的。

你的第一个例子:

type durWithMethods dur
Run Code Online (Sandbox Code Playgroud)

这将创建一个新类型durWithMethods作为dur其基础类型。由于底层类型是嵌入的结构体time.Duration,因此嵌入类型的方法会得到提升,并将成为嵌入器类型的方法集dur的一部分,因此和durWithMethodsDuration.String()无论创建新类型,都会得到提升,因为该String()方法不是 的方法dur,而是 的方法time.Duration

当你写的时候d.String(),它会是 的简写d.Duration.String()

第二个例子:

type durWithoutMethods time.Duration
Run Code Online (Sandbox Code Playgroud)

创建一个新类型durWithoutMethods,再次删除所有方法。既然Duration.String()是一种方法time.Duration,那么它就不会是一种方法durWithoutMethods

真正的类型别名如下所示:

type sameAsDuration = time.Duration
Run Code Online (Sandbox Code Playgroud)

由于它表示相同的类型,因此它也具有以下String()方法:

var sad sameAsDuration
fmt.Println(sad.String()) // works
Run Code Online (Sandbox Code Playgroud)