定义方式
type identifier struct {
field1 type1
field2 type2
...
}
复制代码
结构体得字段可以是任何类型,甚至是结构体本身,也可以是函数或者接口
初始化方式
type Point struct { x, y int }
复制代码
- 使用new函数给结构体变量分配内存
new函数获取到得是结构体类型得指针
- 获取结构体类型指针
使用new函数跟使用&T{}是等价的,都是产生结构体类型指针
-
获取结构体类型
-
混合字面量语法
point1 := Point{0, 3} (A)
point2 := Point{x:5, y:1} (B)
point3 := Point{y:5} (C)
复制代码
结构体的类型定义在它的包中必须是唯一的,结构体的完全类型名是:packagename.structname
点号选择器
- 点号选择器可以给结构体的字段赋值
point.x = 5
复制代码
- 点号选择器可以获取结构体字段的值
x := point.x
复制代码
- 无论是结构体类型还是结构体类型指针,都可以使用点号来引用结构体字段
type myStruct struct { i int }
var v myStruct // v是结构体类型变量
var p *myStruct // p是指向一个结构体类型变量的指针
复制代码
内存布局
结构体和它所包含的数据在内存中是以连续块的形式存在的
结构体工厂函数
Go不支持面向对象编程语言中的构造方法,但是可以通过函数实现
type File struct {
fd int // 文件描述符
name string // 文件名
}
// 定义工厂方法,函数名大写字母开头才能被跨包调用
func NewFile(fd int, name string) *File {
if fd < 0 {
return nil
}
return &File{fd, name}
}
// 调用工厂方法
f := NewFile(10, "./test.txt")
复制代码
如果想要强制使用工厂函数,那么可以将结构体的类型改为首字母小写
结构体的标签
结构体中的字段,除了名字和类型,还有一个可选的标签,它是附属在字段的字符串(相当于字段的解释)
- 标签的内容需要通过反射获取
type TagType struct { // tags
field1 bool "An important answer"
field2 string "The name of the thing"
field3 int "How much there are"
}
func main() {
tt := TagType{true, "Barak Obama", 1}
for i := 0; i < 3; i++ {
refTag(tt, i)
}
}
func refTag(tt TagType, ix int) {
// 使用reflect包
ttType := reflect.TypeOf(tt)
ixField := ttType.Field(ix)
fmt.Printf("%v\n", ixField.Tag)
}
复制代码
匿名字段和内嵌结构体
- 结构体可以包含一个或多个匿名字段,此时字段的类型就是字段的名称
// 字段名称分别是:bool, string, int
type TagType struct {
bool
string
int
}
复制代码
在结构体中,对于每种数据类型,只能有一个匿名字段
- 匿名字段本身也可以是一个结构体类型
Go语言的继承是通过内嵌或组合来实现的
结构体属性跨包调用
结构体的属性首字母大写
type TagType struct {
Field1 bool
Field2 string
Field3 int
}
复制代码
入门教程推荐: github.com/Unknwon/the…