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

嵌入式域测试1

注意,在测试中,struct关键字前面 多了 type S1,这表示 类型定义——将其后定义的结构体绑定到标识符S1,之后就可以使用S1来定义常量、变量或其它地方使用了。若只是struct,俺目前不晓得怎么使用,或可能出现在 一次性使用 的场合,未可知也。

前面提到了 三种域 了:命名的域、空域、嵌入式域,下面介绍第四种域,还没看明白,希望写完本文可以搞清楚。

第四种域:一个 结构体 x 的 嵌入式域 的 域 或 方法 f 被称为 升级域(Promoted),如果 x.f 是指向 那个 域 或 方法 f(翻译不准确,请看原文)。

大概能懂,但需要简单的示例就更明白了!

俺的理解:嵌入式域 是一个 类型嘛,这个类型 可能也是 结构体或什么的,也会有自己的 域 和 方法,当它作为 嵌入式域 出现在 另一个结构体中时,它的 域 和 方法就可以 被 另一个结构体直接 调用了。

此时需要注意,嵌入式域 的 域或方法 的 名称 在 外层 结构体中 需保持 唯一性(Unique)。

升级域 表现的 就像  结构体的 普通域一样,除了它们不能在 结构体的 组合字面量(请看官文 composite literals) 中作为域名出现外。

就是说,这些升级域 可以这样 使用,但是,它们不是结构体真正的域,,如果是这样的话,还需要 遵守 非空域名 的唯一性原则吗?

官文更进一步解释了 升级域,下为翻译:

给定一个 结构体类型 S、一个 自定义类型(defined type) T,被升级到 结构体S的方法 包含下面两种情况:

1.S包含 嵌入式域 T,S 和 *S 的 方法集 都会 包含 接收者(receiver)为T的升级方法,另外,*S 的方法集 还包含 接收者 为 *T 的升级方法;

2.S包含 嵌入式域 *T,S 和 *S 的 方法集 都会 包含 接收者 为 T 或 *T 的升级方法;

俺的理解:嵌入式域的所有方法都会被升级,根据 嵌入的方式 不同——类型 或 类型的指针,结构体 或 结构体指针 拥有的 来自 升级方法的 方法集是不同的。

好了,结构体的四种域都介绍完了,如果有更多示例就好了,可本文暂时没有,以后更难说了,下面是最后一部分:域的标签(tag)。

域在声明的时候,可以跟一个字符串字面量,这个叫做 标签(tag),它会成为对应的域的属性。

标签为 空字符串 和 没有标签 一样。

用法有两个:反射接口(reflection interface)、结构体类型识别(type identify)——两个方法请读者查看官文并摸索,其它情况时均忽略。

在俺看来,tag就是域的注释,解释域是干什么的。在上面的两种用法中,可以获取标签的信息,而在其它地方就忽略了,或者获取不到。

官文示例:

struct {
x, y float64 "" // an empty tag string is like an absent tag // 空标签
name string "any string is permitted as a tag"
_ [4]byte "ceci n'est pas un champ de structure" // 法语,Google翻译:这不是结构领域
} // A struct corresponding to a TimeStamp protocol buffer.
// The tag strings define the protocol buffer field numbers;
// they follow the convention outlined by the reflect package.
// 使用 reflect 包输出的 结构体的信息。。要使用反射,那就 从 学习 reflect 包开始吧!
struct {
microsec uint64 `protobuf:"1"` // 注意,是 反引号
serverIP6 uint64 `protobuf:"2"` // 注意,是 反引号
}

好了,结构体类型 就这么多了,本文就比官文多一个示例,其它的都是翻译和自己的理解。

其实,结构体 还需要 和 方法定义或声明 的介绍一起 会更有用,在之前看过的代码中,存在很多 定义结构体后,再定义其方法——单独的方法 或者  接口 中的方法的操作。在俺看来,这就是把 面向对象程序设计 中的 数据和操作 拆开了啊(鸭子类型)!这样更好吗?还需要更多地体会它的好!

Go语言规格说明书 之 结构体类型(Struct types)的更多相关文章

  1. go语言进阶之为结构体类型添加方法

    1.为结构体类型添加方法 示例: package main import "fmt" type Person struct { name string //名字 sex byte ...

  2. 【转】C语言中不同的结构体类型的指针间的强制转换详解

    C语言中不同类型的结构体的指针间可以强制转换,很自由,也很危险.只要理解了其内部机制,你会发现C是非常灵活的. 一. 结构体声明如何内存的分布, 结构体指针声明结构体的首地址, 结构体成员声明该成员在 ...

  3. 结构体类型struct

    教学视频 定义: struct student{CString name; int num; TCHAR sex; int age; };   //注意有个分号 student zansan = {_ ...

  4. C++学习(二十四)(C语言部分)之 结构体1

    1.结构体 存放多个不同类型的数据 但是是相关联的 数组 存放多个相同类型的数据 结构体是存放多个相关联的不同类型的数组 struct 定义一个结构体类型 自定义类型 2.结构体定义方式 定义类型最通 ...

  5. Go语言规格说明书 之 接口类型(Interface types)

    go version go1.11 windows/amd64 本文为阅读Go语言中文官网的规则说明书(https://golang.google.cn/ref/spec)而做的笔记,介绍Go语言的  ...

  6. Go语言规格说明书 之 类型(Types)

    go version go1.11 windows/amd64 本文为阅读Go语言中文官网的规则说明书(https://golang.google.cn/ref/spec)而做的笔记,完整的介绍Go语 ...

  7. C语言中的系统时间结构体类型

    在C语言涉及中经常需要定时触发事件,涉及到获取系统时间,其结构体类型有多种.Unix/Linux系统下有以下几种时间结构: 1.time_t 类型:长整型,一般用来表示从1970-01-01 00:0 ...

  8. Android For JNI(五)——C语言多级指针,结构体,联合体,枚举,自定义类型

    Android For JNI(五)--C语言多级指针,结构体,联合体,枚举,自定义类型 我们的C已经渐渐的步入正轨了,基础过去之后,就是我们的NDK和JNI实战了 一.多级指针 指针的概念我们在前面 ...

  9. typedef和自定义结构体类型

    在自定义结构体类型时会用到typedef关键字.大家都知道typedef是取别名的意思,在C语言中跟它容易混淆的有const,#define等,其区别不在本篇文章讨论之列. /*定义单链表结点类型*/ ...

随机推荐

  1. ACCESS与SQL Server下SQL Like 查询的不同

    在ACCESS中LIKE的用法Access里like的通配符用法是这样: “?”表示任何单一字符: “*”表示零个或多个字符: “#”表示任何一个数字 所以应该是: select * from dat ...

  2. MyEclipse新建工作空间后的配置详细步骤

    1. General --> Workspace --> UTF-8 2. General --> Editors -->File  Associations --> J ...

  3. 洛谷 P1880 [NOI1995] 石子合并(区间DP)

    传送门 https://www.cnblogs.com/violet-acmer/p/9852294.html 题解: 这道题是石子合并问题稍微升级版 这道题和经典石子合并问题的不同在于,经典的石子合 ...

  4. 2018.10.19浪在ACM 集训队第一次测试赛

    2018.10.19浪在ACM 集训队第一次测试赛 待参考资料: [1]:https://blog.csdn.net/XLno_name/article/details/78559973?utm_so ...

  5. php中的session过期思考一二

    看了php开发组成员鸟哥的一篇关于php设置session过期(http://www.laruence.com/2012/01/10/2469.html)的文章 他也说了一般人的回答的几个答案, 回答 ...

  6. Linux命令之ls

    ls命令 用处:列出此目录下的文件和目录 用法:直接在终端中输入ls就好了 示例: 看到了吗,文件夹和文件都显示出来了哦 可是,电脑里面有时会有一些隐藏文件,我还想看到这些隐藏文件怎么办呢?加  -a ...

  7. 为什么要用dubbo,dubbo和zookeeper关系

    为什么要用dubbo? 当网站规模达到了一定的量级的时候,普通的MVC框架已经不能满足我们的需求,于是分布式的服务框架和流动式的架构就凸显出来了.     单一应用架构 当网站流量很小时,只需一个应用 ...

  8. aspectj 表达式 execution切点函数

    execution函数用于匹配方法执行的连接点,语法为: execution(方法修饰符(可选) 返回类型 方法名(参数) 异常模式(可选)) 参数部分允许使用通配符: *  匹配任意字符,但只能匹配 ...

  9. python 小程序,打印数字

    要求如下: 指定一个数字 x ,然后打印 1到x 的所有数字,并问是否继续打印,否退出程序,是就继续.再指定一个数字 y ,如果 y> x 就显示 x+1 到 y 的所有数字,y <= x ...

  10. Java Web 自定义标签

    1.   自定义标签 由于在JSP页面中直接嵌入Java代码会导致页面开起来非常混乱,不方便和美工等配合工作,为此,JSP提供了自定义标签技术,可以代替直接嵌入Java代码的方式提供动态逻辑,但自定义 ...