[go]结构体/接口
结构体(打包多种类型的一种复合结构)
//struct类型(内存对齐)
// 结构体字段名类型相同,字段顺序不同, 占用的内存不同
//24bytes
type user struct {
bool
float64
int16
}
//16bytes
type user struct {
float64
int16
bool
}
//结构体元素: 占一块连续的内存地址空间
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]结构体/接口的更多相关文章
- go 基础 结构体 接口 访问权限
package School type SchoolModel struct { Name string Address string StudentCount int Is985 bool } ty ...
- ARM-Linux S5PV210 UART驱动(3)----串口核心层、关键结构体、接口关系
尽管一个特定的UART设备驱动完全可以按照tty驱动的设计方法来设计,即定义tty_driver并实现tty_operations其中的成员函数,但是Linux已经在文件serial_core.c中实 ...
- Go语言学习笔记(四)结构体struct & 接口Interface & 反射
加 Golang学习 QQ群共同学习进步成家立业工作 ^-^ 群号:96933959 结构体struct struct 用来自定义复杂数据结构,可以包含多个字段(属性),可以嵌套: go中的struc ...
- [PHP] PHP服务器接口SAPI中的结构体
SAPI:在各个服务器抽象层之间遵守着相同的约定,这里我们称之为SAPI接口.例如命令行程序的实现,Apache的mod_php模块实现以及fastcgi的实现等等 1.结构体:使用结构体(Struc ...
- GO语言系列(五)- 结构体和接口
结构体(Struct) Go中struct的特点 1. 用来自定义复杂数据结构 2. struct里面可以包含多个字段(属性) 3. struct类型可以定义方法,注意和函数的区分 4. struct ...
- golang 结构体中的匿名接口
golang 结构体中的匿名接口 代码示例 golang 中,可以给结构体增加匿名field,可参考 unknwon 大神的书. 匿名字段和内嵌结构体 但,golang同时也可以给结构体定义一个匿名i ...
- Golang 笔记 2 函数、结构体、接口、指针
一.函数 Go中函数是一等(first-class)类型.我们可以把函数当作值来传递和使用.Go中的函数可以返回多个结果. 函数类型字面量由关键字func.由圆括号包裹声明列表.空格以及可以由圆括号 ...
- golang结构体、接口、反射
struct结构体 struct用来自定义复杂数据结构,可以包含多个字段属性,可以嵌套; go中的struct类型理解为类,可以定义方法,和函数定义有些许区别; struct类型是值类型. struc ...
- Go语言学习笔记(四)结构体struct & 接口Interface & 反射reflect
加 Golang学习 QQ群共同学习进步成家立业工作 ^-^ 群号:96933959 结构体struct struct 用来自定义复杂数据结构,可以包含多个字段(属性),可以嵌套: go中的struc ...
随机推荐
- Image Processing and Analysis_8_Edge Detection: Optimal edge detection in two-dimensional images ——1996
此主要讨论图像处理与分析.虽然计算机视觉部分的有些内容比如特 征提取等也可以归结到图像分析中来,但鉴于它们与计算机视觉的紧密联系,以 及它们的出处,没有把它们纳入到图像处理与分析中来.同样,这里面也有 ...
- php连接docker运行的mysql,显示(HY000/2002): Connection refused的解决办法
php要连接docker中运行的mysql是不能用localhost, 127.0.0.1来连接的,因为每个docker运行容器的localhost 127.0.0.1都是自己容器本身,不是mysql ...
- Mac上使用sunlogin向日葵软件远程控制电脑
1 安装软件 控制端和客户端都安装 https://sunlogin.oray.com/personal/download/ 2 再两台电脑上都安装好客户端和控制端后,打开控制端软件 可以看到自己登录 ...
- Mysql(五):索引原理与慢查询优化
一 介绍 为何要有索引? 一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,在生产环境中,我们遇到最多的,也是最容易出问题的,还是一些复杂的查询操作,因此对查询语句 ...
- asp.net使用FileUpload控件上传图片且重命名
我在根目录下创建了一个Images图片存放文件夹,上传的图片都在这 下面贴代码 if (FileUpload1.HasFile) { string filename = FileUpload1.Fil ...
- JS中call()和apply()以及bind()的区别
一.方法定义: apply:调用一个对象的一个方法,用另一个对象替换当前对象.例如:B.apply(A, arguments);即A对象应用B对象的方法. call:调用一个对象的一个方法,用另一个对 ...
- 构建之法个人作业5——alpha2项目测试
[相关信息] Q A 这个作业属于哪个课程 https://edu.cnblogs.com/campus/xnsy/2019autumnsystemanalysisanddesign/ 这个作业要求在 ...
- Mac&Appium&Python自动化测试-环境搭建之安卓SDK
一.摘要 本博文将详细讲述在Mac环境下的jdk安装.配置以及环境校验:安卓sdk安装.配置以及环境校验 二.安装包工具准备: jdk1.8.0(64 位) android-sdk_r24.4.1-m ...
- idea 设置Terminal为git终端
- linux系统相关文件和操作
查看内核: uname -r [root@server0 ~]# uname -r -.el7.x86_64 [root@server0 ~]# 查看版本: cat /etc/redhat-rele ...