Golang底层类型

6
在规范的这段代码片段中:
type T1 string
type T2 T1
type T3 []T1
type T4 T3

规范说明:
字符串的基础类型,T1和T2是字符串。[]T1、T3和T4的基础类型是[]T1。
为什么T2的基础类型不是T1,而是字符串?如果T1的基础类型是字符串,那么T4的基础类型不应该是[]string而不是[]T1吗?困惑了。
1个回答

6
规范提到

每种类型 T 都有一个底层类型:如果 T 是预声明的布尔、数字或字符串类型,或者是类型字面量,则相应的底层类型是 T 本身。
否则,T 的底层类型是其类型声明中引用的类型的底层类型

T2 在其类型声明中引用了底层类型为 stringT1

T2 的底层类型为 string 很重要,因为它将有助于可赋值性,其中

一个值 x 可以分配给类型为 T 的变量("x 可以分配给 T")
x 的类型 V 和 T 具有相同的底层类型,并且 V 或 T 中至少有一个不是命名类型

这也在 "Golang: Why can I type alias functions and use them without casting?" 中详细说明。


当涉及到 T4 的底层类型时,我们谈论的是一个底层未命名类型 []T1

同样,可赋值性规则表明你可以将 []T1 赋给 T4(因为 []T1 不是命名类型):其底层类型在第一个非命名类型处停止([]T1)。

请参见此播放器上的示例

var t3 T3 = []T1{"a", "b"}
fmt.Println("t3='%+v'", t3)
// var t4 T4 = []string{}
// cannot use []string literal (type []string) as type T4 in assignment
var t4 T4 = T4(t3)
fmt.Println("t4='%+v'", t4)
t4 = []T1{T1("c"), T1("d")}
fmt.Println("t4='%+v'", t4)

输出:

t3='%+v' [a b]
t4='%+v' [a b]
t4='%+v' [c d]

Danny Rivers在评论中补充道:

为什么T4的底层类型等于[]T1,而不是[]string

T4的底层类型被定义为T3的底层类型,即[]T1的底层类型。由于[]T1类型字面量,因此这是最底层的类型。
规范的语言很容易让人忽略,即类型字面量,而不仅仅是预声明的类型,也算作底层类型。


我很迷茫,我创建了一个带有切片约束的通用类型,但当我传递一个切片时它为什么没有实现它? - Agyakwalf
@Agyakwalf 很好,干得好。这个主题的好读物:使用泛型重新审视数组和切片检查元素是否存在于数组/切片的通用方法字节切片,... 1/2 - VonC
1
@bit 是的。您也可以在此部分中找到它们的介绍。 - VonC
1
@Tarun 不,xyz 的底层类型是整个 struct 类型字面量。结构体内的字段 varstring 类型,但这并不意味着整个结构体 xyz 的底层类型是 string。底层类型是整个结构体,而不仅仅是它的一个字段。 - VonC
显示剩余10条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接