首页 > 解决方案 > 对类型别名的行为感到困惑

问题描述

考虑以下代码(也在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
}

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

标签: gotypes

解决方案


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

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

你的第一个例子:

type durWithMethods dur

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

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

第二个例子:

type durWithoutMethods time.Duration

创建一个新类型durWithoutMethods,它再次剥离所有方法。既然Duration.String()是 的 方法time.Duration,就不会是 的 方法durWithoutMethods

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

type sameAsDuration = time.Duration

由于它表示相同的类型,它也有String()方法:

var sad sameAsDuration
fmt.Println(sad.String()) // works

推荐阅读