结构体(打包多种类型的一种复合结构)

//struct类型(内存对齐)
// 结构体字段名类型相同,字段顺序不同, 占用的内存不同 //24bytes
type user struct {
bool
float64
int16
} //16bytes
type user struct {
float64
int16
bool
}

在 Go 中恰到好处的内存对齐

//结构体元素: 占一块连续的内存地址空间
func main() {
type test struct {
a int8
b int8
c int8
}
n := test{
1, 2, 3
}
fmt.Printf("n.a %p\n", &n.a)
fmt.Printf("n.b %p\n", &n.b)
fmt.Printf("n.c %p\n", &n.c)
} //n.a 0xc0000160c0
//n.b 0xc0000160c1
//n.c 0xc0000160c2
//type关键字: 给类型起别名(支持互相赋值)

func main() {
type int2 = int
var a int2
fmt.Printf("%#v,%T", a, a) var b int
b = a
fmt.Printf("%#v,%T", b, b)
} //0,int //其他例子
type byte = uint8
type rune = int32
//type关键字: 定义一种新类型(不支持互相赋值)

func main() {
type int2 int
var a int2
fmt.Printf("%#v,%T", a, a) var b int
b = a
fmt.Printf("%#v,%T", b, b)
} //0,main.int2
//.\main.go:11:4: cannot use a (type int2) as type int in assignment
//结构体: 多个不同类型命名字段, 打包成一个复合类型, 是值类型

//type关键字: 定义结构体
type User struct {
name string
age int
} 1. 字段名必须唯一, 可用"_"
2. 字段名字,排列顺序属于类型的组成部分.
3. 支持使用自身指针类型成员
//实例化结构体: 仅声明, 字段值被零值填充

type User struct {
name string
age int
} func main() {
var u User
fmt.Printf("%T, %#v", u, u)
} //main.User, main.User{name:"", age:0}
//实例化结构体: 无字段值, 字段值被零值填充
type User struct {
name string
age int
} func main() {
u := User{}
fmt.Printf("%T, %#v", u, u)
} //main.User, main.User{name:"", age:0}
type User struct {
name string
age int
} func main() {
u := User{}
u.name = "mm"
u.age = 22
fmt.Printf("%T, %#v", u, u)
} //main.User, main.User{name:"mm", age:22}
// 实例化结构体: 携带Field名
type User struct {
name string
age int
} func main() {
u := User{
name: "m1",
age: 22,
}
fmt.Printf("%T, %#v", u, u)
} //main.User, main.User{name:"m1", age:22}
// 实例化结构体: 不指定字段名(必须将所有字段值充全,缺一不可)
type User struct {
name string
age int
} func main() {
u := User{"maotai", 12}
fmt.Println(u)
} //{maotai 12}
// 实例化结构体: 不指定字段名(必须将所有字段值充全,缺一不可)
type User struct {
name string
age int
} func main() {
u := User{"maotai"}
fmt.Println(u)
} //.\main.go:11:12: too few values in User literal
//实例化结构体: 携带Field名+给指定字段名赋值
type User struct {
name string
age int
} func main() {
u := User{name: "mm"}
u.age = 22
fmt.Printf("%T, %#v", u, u)
} //main.User, main.User{name:"mm", age:22}
//通过new进行实例化(返回该类型的地址)

type user struct {
name string
age int
} func main() {
u := new(user)
fmt.Printf("%T, %#v\n", u, u) //*main.user &main.user{name:"", age:0} u.name = "m1"
u.age = 22
fmt.Printf("%#v\n", u) //&main.user{name:"m1", age:22}
}
//*main.user, &main.user{name:"", age:0}
//&main.user{name:"m1", age:22}
// 取结构体的地址实例化
// u := new(user) 等价于 u := &user{} type user struct {
name string
age int
} func main() {
u := &user{}
fmt.Printf("%T, %#v\n", u, u) //*main.user &main.user{name:"", age:0} u.name = "m1" //go语言实现的语法糖 (*u).name = "m1"
u.age = 22
fmt.Printf("%#v\n", u) //&main.user{name:"m1", age:22}
}
//*main.user, &main.user{name:"", age:0}
//&main.user{name:"m1", age:22}
//结构体构造函数(可使用goland快捷键一键生成这个函数)
type User struct {
name string
age int
} func NewUser(name string, age int) *User {
return &User{name: name, age: age}
}
// 结构体字段标签

func main() {
type user struct {
name string `昵称`
sex byte `性别`
} u := user{"Tom", 1} v := reflect.ValueOf(u)
fmt.Println(v.Field(0)) //Tom
fmt.Println(v.Type().Field(0).Tag) //昵称
fmt.Println(v.Type().NumField()) //2
}

匿名结构体

// 匿名结构体: 空结构体
func main() {
var a struct{}
fmt.Printf("%#v", a)
} //struct {}{}
//匿名结构体声明: 初始化零值

func main() {
var a struct {
name string
age int
}
fmt.Printf("%#v",a)
} //struct { name string; age int }{name:"", age:0}
//匿名结构体: 声明 初始化
func main() {
var a struct {
name string
age int
}
a = struct {
name string
age int
}{}
fmt.Printf("%#v", a)
} //struct { name string; age int }{name:"", age:0}
//匿名结构体: 声明+初始化
func main() {
var a struct {
name string
age int
}
a.name = "m1"
a.age = 22
fmt.Printf("%#v", a)
} //struct { name string; age int }{name:"m1", age:22}
//匿名结构体: 1. 先声明 2.初始化
func main() {
var a struct {
name string
age int
}
a = struct {
name string
age int
}{name: "m1", age: 22}
fmt.Printf("%#v", a)
} //struct { name string; age int }{name:"m1", age:22}
//匿名结构体: 声明并初始化
func main() {
a := struct {
name string
age int
}{name: "m1", age: 22}
fmt.Printf("%#v", a)
} //struct { name string; age int }{name:"m1", age:22}
//匿名结构体: 声明并初始化
func main() {
a := struct {
name string
age int
}{}
a.age = 22
fmt.Printf("%#v", a)
} //struct { name string; age int }{name:"", age:22}
//匿名结构体: 声明并初始化

func main() {
a := struct {
name string
age int
}{"m1", 22}
fmt.Printf("%#v", a)
} //struct { name string; age int }{name:"m1", age:22}
// 匿名结构体作为字段类型

func main() {
type file struct {
name string
attr struct {
owner int
perm int
}
}
f := file{
name: "test.txt",
attr: struct {
owner int
perm int
}{1, 1},
} //f2 := file{
// name: "test.txt",
// attr: { // 错误:missing type in composite literal
// owner int
// perm int
// }{1, 1},
//} f.attr.owner = 1
}

方法

//给任意类型绑定方法

type MyInt int

func (m *MyInt) incr() {
*m++
}
func main() {
var a MyInt
a = 0
a.incr()
a.incr()
fmt.Println(a)
}
//2
//给结构体绑定方法
type User struct {
name string
age int
} func (u User) get() {
fmt.Println(u.name)
} func (u *User) post() {
u.name = "mm"
} // 注: 指针接受者和值接收者
// 调用方法
type user struct {
name string
age int
} func (u *user) test() {
fmt.Println("test func")
} func main() {
u := user{"m1", 22}
u.test() //值类型的调用实现指针类型调用效果, &u.test, go实现的语法糖
(&u).test()
}
// 报错, 不支持多级指针调用
func main() {
u := user{"m1", 22} (&u).test()
(&((&u))).test()
}

继承

// 结构体的: 匿名字段, 不写字段名, 只有类型.  字段名就是类型名
type User struct {
name string
int
} func main() {
u:=User{
name: "m1",
int: 0,
} fmt.Printf("%#v\n", u)
}
//main.User{name:"m1", int:0}
type user struct {
name string
age int
}
type manager struct {
user //字段名可省略
title string
} func main() {
m := manager{
user: user{
name: "m1",
age: 22,
},
title: "CTO",
}
fmt.Printf("%#v", m)
} //main.manager{user:main.user{name:"m1", age:22}, title:"CTO"}
// 如嵌入其他包中的类型,实话时时, 隐式字段名字不包括包名。
type data struct{
os.File
} func main() {
d:=data{
File: os.File{}, //这里字段名不需要是os.File
} fmt.Printf("%#v\n",d)
}
//调用父类方法

type user struct {
name string
age int
} func (u *user) say() {
fmt.Println("user say")
} type manager struct {
user
title string
} func main() {
m := manager{}
m.say()
} //user say
//子类覆盖父类方法
type user struct {
name string
age int
} func (u *user) say() {
fmt.Println("user say")
} type manager struct {
user
title string
}
func (m *manager) say() {
fmt.Println("manager say")
} func main() {
m := manager{}
m.say()
m.user.say()
} //manager say
//user say
type data struct{
sync.Mutex
buf [1024]byte
} func main() {
d:=data{}
d.Lock() // 编译会处理为sync.(*Mutex).Lock() 调用
defer d.Unlock()
}
// 要求子类必须实现父类方法

type people interface {
Init()
Say()
} type user struct {
} func (u user) Init() {
panic("implement me")
} func (u user) Say() {
panic("implement me")
} type manager struct {
user
} func main() {
var m manager
m.Say()
} //panic: implement me

[go]结构体/接口的更多相关文章

  1. go 基础 结构体 接口 访问权限

    package School type SchoolModel struct { Name string Address string StudentCount int Is985 bool } ty ...

  2. ARM-Linux S5PV210 UART驱动(3)----串口核心层、关键结构体、接口关系

    尽管一个特定的UART设备驱动完全可以按照tty驱动的设计方法来设计,即定义tty_driver并实现tty_operations其中的成员函数,但是Linux已经在文件serial_core.c中实 ...

  3. Go语言学习笔记(四)结构体struct & 接口Interface & 反射

    加 Golang学习 QQ群共同学习进步成家立业工作 ^-^ 群号:96933959 结构体struct struct 用来自定义复杂数据结构,可以包含多个字段(属性),可以嵌套: go中的struc ...

  4. [PHP] PHP服务器接口SAPI中的结构体

    SAPI:在各个服务器抽象层之间遵守着相同的约定,这里我们称之为SAPI接口.例如命令行程序的实现,Apache的mod_php模块实现以及fastcgi的实现等等 1.结构体:使用结构体(Struc ...

  5. GO语言系列(五)- 结构体和接口

    结构体(Struct) Go中struct的特点 1. 用来自定义复杂数据结构 2. struct里面可以包含多个字段(属性) 3. struct类型可以定义方法,注意和函数的区分 4. struct ...

  6. golang 结构体中的匿名接口

    golang 结构体中的匿名接口 代码示例 golang 中,可以给结构体增加匿名field,可参考 unknwon 大神的书. 匿名字段和内嵌结构体 但,golang同时也可以给结构体定义一个匿名i ...

  7. Golang 笔记 2 函数、结构体、接口、指针

    一.函数 Go中函数是一等(first-class)类型.我们可以把函数当作值来传递和使用.Go中的函数可以返回多个结果.  函数类型字面量由关键字func.由圆括号包裹声明列表.空格以及可以由圆括号 ...

  8. golang结构体、接口、反射

    struct结构体 struct用来自定义复杂数据结构,可以包含多个字段属性,可以嵌套; go中的struct类型理解为类,可以定义方法,和函数定义有些许区别; struct类型是值类型. struc ...

  9. Go语言学习笔记(四)结构体struct & 接口Interface & 反射reflect

    加 Golang学习 QQ群共同学习进步成家立业工作 ^-^ 群号:96933959 结构体struct struct 用来自定义复杂数据结构,可以包含多个字段(属性),可以嵌套: go中的struc ...

随机推荐

  1. go语言中regexp包中的函数和方法

    // regexp.go ------------------------------------------------------------ // 判断在 b 中能否找到正则表达式 patter ...

  2. RobHess的SIFT环境配置

    平台:win10 x64 +VS 2015专业版 +opencv-2.4.11 + gtk_-bundle_2.24.10_win32 参考博客:https://www.cnblogs.com/cql ...

  3. C和指针--动态内存分配

    1.为什么需要使用动态内存分配 数组的元素存储于内存中连续的位置上,当一个数组被声明时,它所需要的内存在编译时就被分配.当你声明数组时,必须用一个编译时常量指定数组的长度.但是,数组的长度常常在运行时 ...

  4. 13_Redis_持久化

    一:概述: Redis的高性能是山于其将所有数据都存储在了内存中,为了使Redis在重启之后仍能保证数据不丢失,需要将数据从内存中同步到硬盘中,这一过程就是持久化. Redis支持两种方式的持久化,一 ...

  5. Linux磁盘及文件系统管理3

    文件系统管理工具: 创建文件系统的工具 mkfs mkfs.ext2,mkfs.ext3,mkfs.ext4,mkfs.xfs,mkfs.vfat,... 检测及修复文件系统的工具 fsck fsck ...

  6. DATASNAP双缓存下载文件

    原文链接:http://www.cnblogs.com/hnxxcxg/archive/2012/12/29/2839358.html procedure TFrmMain.btnUpdateFile ...

  7. ACM-ICPC 2019南昌网络赛I题 Yukino With Subinterval

    ACM-ICPC 2019南昌网络赛I题 Yukino With Subinterval 题目大意:给一个长度为n,值域为[1, n]的序列{a},要求支持m次操作: 单点修改 1 pos val 询 ...

  8. 遍历二叉树 - 基于队列的BFS

    之前学过利用递归实现BFS二叉树搜索(http://www.cnblogs.com/webor2006/p/7262773.html),这次学习利用队列(Queue)来实现,关于什么时BFS这里不多说 ...

  9. switch结构

    switch结构介绍 switch也属于条件判断的语句 支持多种写法,和if .. else if ...else 结构的功能类似,但是里面的细节需要注意的地方更多 switch基本语法 switch ...

  10. MessageBox和ShellExecute初体验

    #include <stdio.h> //包含头文件,标准输入输出库 #include <windows.h> //包含windows头文件,ShellExecute正来自于此 ...