结构体

结构体是将零个或多个任意类型的命名变量组合在一起的聚合数据类型。每个变量都叫做结构体的成员。

type Employee struct {
ID int
Name string
age int
}

Employee就是一个结构体。

定义结构体时要注意

1.如果一个成员变量的首字母大写,则它是可导出的。

2.成员变量的顺序对于结构体的同一性很重要,顺序不同表示不同的结构体。

3.结构体中的成员变量类型不能是结构体本身,但可以是该结构体的指针类型

type Node struct {
value int
next *Node
//这样是非法的
//next Node
}

4.结构体的零值由结构体成员的零值构成。

结构体变量的声明

type Point struct {
X int
Y int
} // 方式一
p1 := Point{1, 2} // X=1 Y=2
// 方式二
p2 := Point{X: 3, Y: 4} // X=3 Y=4 // 如果某个成员变量没有指定,那么该成员变量的值为该类型零值
p3 := Point{Y:6} // X=0 Y=6

方式一和方式二不可以混用。并且不能通过方式一绕过不可导出变量无法在其他包中使用的规则

// p.go
package p
type T struct { a, b int } // q.go
package q
import "p"
var _ = p.T{1, 2} // 编译错误
var _ = p.T{a: 1, b: 2} // 编译错误

如果在函数中需要修改结构体变量的内容时,需要传递指针

type Point struct {
X, Y int
} func update(p Point, x int) { // 函数接收到的是实惨的一个副本
p.X = x
} func update2(p *Point, x int) {
p.X = 2
} func main() {
p := Point{}
update(p, 1)
fmt.Println(p) // {0 0}
update2(&p, 2)
fmt.Println(p) // {2 2}
}

结构体的比较

必须所有的成员变量是可比较的,那这个结构体是可变比较

type Point struct {
X, Y int
} type Book struct {
name string
chapters []string
} func main() {
p1 := Point{X: 1, Y: 2}
p2 := Point{X: 1, Y: 2}
p3 := Point{X: 1, Y: 3}
fmt.Println(p1 == p2, p2 == p3) // true false b1 := Book{name: "abc", chapters: []string{"1", "2"}}
b2 := Book{name: "abc", chapters: []string{"1", "2"}}
fmt.Print(b1 == b2) // 编译错误,无法比较,因为chapters是slice类型 不能比较
}

结构体嵌套和匿名成员

结构体嵌套的目的是为了复用

Go允许我们定义不带名称的结构体成员(即匿名成员),这样可以快捷访问到匿名成员里的成员变量

type Point struct {
X, Y int
} type Circle struct {
Point
Radius int
} type Wheel struct {
Circle
Spokes int
} func main() {
var w Wheel
w.X = 8 // 等价于w.Circle.Point.X
w.Y = 8
w.Radius = 5 // 等价于w.Circle.Radius
w.Spokes = 20 fmt.Printf("%#v", w) // main.Wheel{Circle:main.Circle{Point:main.Point{X:8, Y:8}, Radius:5}, Spokes:20}
}

外围的结构体Wheel不仅获得匿名成员Circle的内部成员变量,也会获得Circle的方法

type Point struct {
X, Y int
} func (p Point) Print() {
fmt.Printf("%#v", p)
} type Circle struct {
Point
Radius int
} func (c Circle) Print() {
fmt.Printf("%#v", c)
} type Wheel struct {
Circle
Spokes int
} // func (w Wheel) Print() {
// fmt.Printf("%#v", w)
// } func main() {
var w Wheel
w.X = 8
w.Y = 8
w.Radius = 5
w.Spokes = 20 fmt.Printf("%#v\n", w) // main.Wheel{Circle:main.Circle{Point:main.Point{X:8, Y:8}, Radius:5}, Spokes:20}
w.Print() // main.Circle{Point:main.Point{X:8, Y:8}, Radius:5}
}

如果在Wheel上再加一个匿名命名成员Band, 它也有Print方法

type Band struct {
Name string
} func (b Band) Print() {
fmt.Printf("%#v", b)
} type Wheel struct {
Circle
Band
Spokes int
} func main() {
var w Wheel
w.X = 8
w.Y = 8
w.Radius = 5
w.Spokes = 20 fmt.Printf("%#v\n", w) // main.Wheel{Circle:main.Circle{Point:main.Point{X:8, Y:8}, Radius:5}, Band:main.Band{Name:""}, Spokes:20}
w.Print() // 编译报错
w.Circle.Print() // main.Circle{Point:main.Point{X:8, Y:8}, Radius:5}
w.Band.Print() // main.Band{Name:""}
}

如果外围结构体WheelPrint方法,会直接调用该方法;如果没有,但其内部的多个匿名成员都有该方法,需要显示指定调用哪个匿名结构体的Print方法

Go: 复合数据类型struct的更多相关文章

  1. hive的复合数据类型

    hive中的复合数据类型 Array array中的数据为相同类型,例如,假如array A中元素['a','b','c'],则A[1]的值为'b' 数据结构如下: zhangsan beijing, ...

  2. C/C++知识总结 五 复合数据类型 壹(数组、字符串与string、结构)

    C/C++复合数据类型 壹(数组.结构) 数组 数组的意义.定义与创建 一.二维数组应用 字符数组与字符串处理函数 数组与指针---关系密切 数组的意义与定义创建 意义:反映数据间的特点(通过把同一类 ...

  3. Verilog缺少一个复合数据类型,如C语言中的结构体

    https://mp.weixin.qq.com/s/_9UsgUQv-MfLe8nS938cfQ Verilog中的数据类型(Data Type)是分散的,缺少一个复合数据类型:把多个wire, r ...

  4. ElasticSearch入门 第六篇:复合数据类型——数组,对象和嵌套

    这是ElasticSearch 2.4 版本系列的第六篇: ElasticSearch入门 第一篇:Windows下安装ElasticSearch ElasticSearch入门 第二篇:集群配置 E ...

  5. [日常] Go语言圣经--复合数据类型,数组习题

    go语言圣经-复合数据类型 1.以不同的方式组合基本类型可以构造出来的复合数据类型 2.四种类型——数组.slice.map和结构体 3.数组是由同构的元素组成——每个数组元素都是完全相同的类型——结 ...

  6. 【Oracle】Oracle中复合数据类型

    1,常见的操作数据库的技术有那些 jdbc     使用java 访问数据库的技术    PLSQL  (procedure  过程化sql) 在数据库内部操作数据的技术    proc/c++    ...

  7. Go语言入门篇-复合数据类型

    复合数据类型 主要讨论四种类型——数组.slice.map和结构体 数组和结构体聚合类型   --数组和结构体都是有固定内存大小的数据结构 --数组:由同构的元素组成——每个数组元素都是完全相同的类型 ...

  8. Chisel3 - 复合数据类型

    https://mp.weixin.qq.com/s/rXYqiZKuBpAYL8R94zxgRA   Chisel允许用户根据需要,把基本数据类型组合成为复合数据类型使用.如C语言里面的结构体,这样 ...

  9. Golang入门教程(九)复合数据类型使用案例二

    参考:http://www.runoob.com/go/go-slice.html 目录 切片 字典(map) 函数(func) 接口(interface) 通道(chan) 四.切片(Slice) ...

随机推荐

  1. Python+Requests+Xpath(解析)爬取某站点简历图片(数据分析三)

    1.环境安装 pip install lxml 2.解析原理 使用通用爬虫爬取网页数据 实例化etree对象,且将页面数据加载到该对象中 使用xpath函数结合xpath表达式进行标签定位和指定数据提 ...

  2. python -- 模块与类库

    一.模块 模块(Module)是由一组类.函数和变量组成的,模块文件的扩展名是.py或.pyc 在使用模块之前,需要先使用import语句导入这个模块. 语法格式如下: import 模块名 from ...

  3. Requests方法 -- post

    >>> import requests  导入requests库 >>> help(requests)  #查看requests方法Help on package ...

  4. P6753 [BalticOI 2013 Day1] Ball Machine

    P6753 [BalticOI 2013 Day1] Ball Machine 题意 给你一个树,每次从根节点放一个求,如果其子节点有空这个球会向下滚,若有多个节点为空则找儿子中以子树内编号的最小值为 ...

  5. [考试总结]noip模拟13

    因为最近考试频繁,所以咕掉了好长时间... 淦,刚说完又来一场... 先咕了,等以后有时间再写.... 回来了... 首先看到这个题目们,感觉就不存好意... 然后开始开 \(T1\). 只能蒻蒻地按 ...

  6. javascript学习--(四)面向对象:

    一.生成器generator: javascript里的generator函数是用function*定义的, 案例:yield 也会返回 function* foo(x){ yield x+1; yi ...

  7. python 接口测试之 图片识别

    4.1 pytesser安装 2.安装pytesser,下载地址:http://code.google.com/p/pytesser/ ,下载后直接将其解压到项目代码下,或者解压到python安装目录 ...

  8. MySQL 到底是如何做到多版本并发的?

    之前的文章简单的介绍了 MySQL 的事务隔离级别,它们分别是:读未提交.读已提交.可重复读.串行化.这篇文章我们就来探索一下 MySQL 事务隔离级别的底层原理. 本篇文章针对 InnoDB 存储引 ...

  9. vulnhub-DC:5靶机渗透记录

    准备工作 在vulnhub官网下载DC:5靶机DC: 5 ~ VulnHub 导入到vmware,设置成NAT模式 打开kali准备进行渗透(ip:192.168.200.6) 信息收集 利用nmap ...

  10. Apache ActiveMQ(CVE-2016-3088)

    影响版本 Apache ActiveMQ 5.0.0-5.13.x 路径地址 http://192.168.49.2:8161/admin/test/systemProperties.jsp 该漏洞允 ...