我最近开始阅读Golang Specification Manual并试图了解relevant section中 已命名和未命名的 类型。我来自一种动态的语言,这让我有点头疼。
手册说明:
类型确定特定于该类型值的值集和操作集。类型可以命名为或 无名。命名类型由(可能 qualified ) type name 指定;指定了未命名的类型 使用类型文字,它组成现有类型的新类型。
并继续:
布尔,数字和字符串类型的命名实例是 predeclared 。复合类型数组, struct,pointer,function,interface,slice,map和channel types-可以使用类型文字构建。
这里的问题在于,通过规范,这些链接让我跳过页面,并且忘记了那么多概念向我投射的内容是什么。
我已经四处寻找澄清,除了规格手册之外,资源很少。我能找到的唯一相关材料是:
Learning Go - Types - 博客文章解释Go中类型系统的细微差别。
An issue here关于与我提出的问题非常相似。
很遗憾,我在Stack Overflow上找不到任何关于此的 relevant questions 。 (如果它们存在,我需要修改我的搜索方法!)。我问,因为理解新语言的类型系统是 基本概念 之一,以便有效地学习它。
有人可以提供一个 简明明了的例子来说明命名和未命名类型的概念之间的差异吗? *
*此外,解释合格和预先声明的概念将有助于完整性,但显然不是必需的。
答案 0 :(得分:21)
一种简单的思考方式是命名类型是您使用type
语句定义的类型,未命名类型是由类型文字定义的复合类型。
例如,变量x
的类型未命名:
var x struct{ I int }
变量y
的类型命名为:
type Foo struct{ I int }
var y Foo
这些变量中的每一个都被认为具有不同的类型,即使每个变量的基础类型相同(包含名为I
的单个整数成员的结构)。
未命名类型的一个属性是使用相同的未命名类型声明的所有变量被认为具有相同的类型,而具有相同底层表示的两个命名类型是不同的。例如:
var x2 struct{ I int }
type Bar struct{ I int }
var z Bar
此处x
和x2
具有相同的类型,而y
和z
则没有。
这些区别在语言的一些地方发挥作用:
禁止将一个命名类型的值分配给不同命名类型的变量,即使基础类型相同也是如此。但是允许相关的命名和未命名类型之间的分配。也就是说,以下是可以的:
x = y // named type assigned to unnamed type
y = x // unnamed type assigned to named type
但以下是错误:
y = z // assignment between different named types
您可以为您命名的类型定义方法。因此,可以向Foo
添加方法,但是无法将方法附加到变量x
。
另请注意,可以在类型文字中使用命名类型来定义新的未命名类型。例如,尽管使用[]Foo
,切片类型Foo
仍未命名。如果我们想要将方法附加到此切片类型(例如,与sort
包一起使用),我们必须将其命名为:
type Baz []Foo
答案 1 :(得分:1)
对于初学者来说,语言规范听起来像是一个参考文档。它是一个很好的工具,可供参考,但不是用于学习语言。您最好通过Go Tour了解学习,这是对该语言各个方面的交互式介绍,或通过Effective Go详细说明如何使用该语言。
一个未命名的类型,只是一个使用类型文字声明的没有名称的类型,换句话说,基元类型后跟一个列在{}内的其他类型的列表。或者再次引用规范,类型文字"组成现有类型的新类型"随后是带有结构的example,但是虽然未命名的结构可能很少,但通道和地图(它们本身必须很少地从其他类型组成)很少被命名。
package main
import "fmt"
type Named struct {
x int
y int
}
func main() {
a := Named{1, 2}
fmt.Println(a)
b := struct{ x, y int }{1, 2}
fmt.Println(b)
}