go version go1.11 windows/amd64
本文为阅读Go语言中文官网的规则说明书(https://golang.google.cn/ref/spec)而做的笔记,介绍Go语言的 结构体类型(Struct types)。
结构体 在Go语言中很重要,用于组织数据,类似OOP中的类,但是,Go语言的 结构体 中只有数据定义,没有 OOP中的 类方法、实例方法 等概念。
Go语言的结构体 和 C语言的结构体 有些类似,不过俺忘记了C语言结构体的具体用法了,下面介绍Go语言的结构体。
结构体 是 命名元素 的 一个 序列,这些 命名元素 被称为 域(Fields),每一个 域 都有一个 名称 和 类型。
注意,域 的名称可以 显示 或 隐式 指定,显示指定 为 使用 标识符列表(IdentifierList),隐式指定 为 嵌入式域(EmbeddedField)。
注意,在结构体中,非空的域名称 必须是 唯一的(Unique)。
疑问,前面说了 每一个域都有一个名称和类型,这里怎么暗示说有 空域 呢?什么是空域?域名称 为 下划线(_)的域即使空域!可以存在多个?应该是的。有什么用处呢?填充 结构体,使其size达到某种长度,还有呢?
下面是官文示例和自己的批注(蓝色部分不十分确定):
// An empty struct.
struct {} // 空结构体
// A struct with 6 fields. // 6个域 包括 空域
struct {
x, y int // 定义了两个域 x、y,类型都是int,这就是 IdentifierList 了
u float32
_ float32 // padding // 空域,下划线
A *[]int // 定义一个 名称为 A 的 整形数组的指针
F func() // 定义一个 名称为 F 的 函数类型 域——无参数、无返回类型
}
什么是 嵌入式域呢?就是 只给出了 类型但没有提供域名称 的域(这也可以!)。嵌入式域 必须(2种情况) 使用类型名T指定,或者 使用指向非接口类型的指针的类型名 *T 指定——此时T本身不能是指针类型(这里翻译的有些问题)。
嵌入式域 也是有 域名称的,它的域名称就是 其 未限定的类型名称(unqualified type name)。
下面是官文示例和自己的批注(蓝色部分不十分确定):
// A struct with four embedded fields of types T1, *T2, P.T3 and *P.T4 struct { T1 // field name is T1 *T2 // field name is T2 // T2不能是接口类型 P.T3 // field name is T3 // 这个是?不属于上面的两种情况吧?属于情况1? *P.T4 // field name is T4 // 属于情况2? x, y int // field names are x and y }
官文中嵌入式域的错误示例——三个域的域名称都是 T,冲突了:
struct {
T // conflicts with embedded field *T and *P.T
*T // conflicts with embedded field T and *P.T
*P.T // conflicts with embedded field T and *T
}
测试及结果(本想定义一个int、*int的,但这两者冲突了):
代码:
type S1 struct {
int
float32
}
func main() {
var sv1 = S1{12, 21.0}
fmt.Println(sv1)
fmt.Println(sv1.int, sv1.float32)
}
运行结果:
{12 21}
12 21