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

//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. python 删除特定字符所在行

    #查询文件中含有特殊字符串的行 #!/usr/bin/python # -*- coding:utf- -*- import re file1 = open('test.txt','r+') istx ...

  2. Oralce问题之ORA-12560:TNS协议适配器错误

    在Windows系统中,通过CMD命令打开命令窗口,通过命令:sqlplus / as sysdba回车后提示 协议适配器错误 可能原因: (1).Oralce数据库监听服务没启动起来 通过开始-&g ...

  3. 归并排序C程序详解

    #include <iostream> #include <cstring> #include <cstdlib> using namespace std; //归 ...

  4. VSCode 快捷键定义

    默认的 Toggle explore side bar 快捷键为 Ctrl + B, 但是这和 Vim 的快捷键冲突,解决方法: File  >  Preferences  >  Keyb ...

  5. Python项目列表

    70个Python项目列表: 1.[Python 图片转字符画]2.[200行Python代码实现2048]3.[Python3 实现火车票查询工具]4.[高德API+Python解决租房问题 ]5. ...

  6. HTML5新特性——1 HTML5音频

    注意:<source>同一个音乐可以添加不同格式的音频,这样就可以满足不同浏览器都能够正常播放,兼容不同浏览器. 代码示例: <!doctype html> <html ...

  7. 基于STM32调试工具STM-STUDIO-STM32的使用

    手上有stlink下载器,正好看到官网有这个工具,可以在运行中实时查看变量的数据.这一点和ucos的ucprobe很类似. 参考https://mp.weixin.qq.com/s?src=11&am ...

  8. mysql自增主键清零方法

    MySQL数据库自增主键归零的几种方法 如果曾经的数据都不需要的话,可以直接清空所有数据,并将自增字段恢复从1开始计数: truncate table table_name; 1 当用户没有trunc ...

  9. Debug .NET Framework Source

    1.Microsoft Reference Source 在线source http://referencesource.microsoft.com/#System.Data.Linq 可以下载离线s ...

  10. aarch-linux-gnu-g++ install

    # apt install g++-aarch64-linux-gnuReading package lists... 0% Reading package lists... Done Buildin ...