golang学习笔记4——结构体
Posted yubo_725
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了golang学习笔记4——结构体相关的知识,希望对你有一定的参考价值。
结构体格式
golang中的结构体格式如下:
type 结构体名称 struct
字段名 字段类型
字段名 字段类型
下面定义一个结构体Point
,有坐标x, y两个整型字段:
type Point struct
x int
y int
同种类型的字段可以写在一行,如下代码:
type Color struct
r, g, b byte
结构体的初始化
结构体的定义只是一种内存布局的描述,只有当结构体实例化时,才会真正地分配内存。因此必须在定义结构体并实例化后才能使用结构体的字段。
如下代码所示:
package main
import "fmt"
type Point struct
x int
y int
func main()
var p Point // 或者 p := Point
p.x = 1
p.y = 0
// 打印:1 0
fmt.Println(p)
可以直接使用.
来访问结构体的成员变量。
除了使用上面的方式声明并初始化结构体外,还可以使用new
关键字,如下代码所示:
package main
import "fmt"
type Point struct
x int
y int
func main()
p := new(Point) // 也可以使用 p := &Point
p.x = 1
p.y = 0
fmt.Println(p)
与var p Point
这种方式不同的是,使用new
关键字创建的是Point
类型的指针变量,golang中同样可以使用.
来访问结构体指针的成员变量。
也可以在声明结构体变量时直接初始化:
func main()
p := Point
x: 1,
y: 0,
fmt.Println(p)
下面的代码中定义了两个结构体:猫和人,人养了一只宠物,代码如下:
package main
import "fmt"
// 结构体 猫
type Cat struct
Name string
Weight float32
Color string
// 结构体 人
type Person struct
Name string
Age int
// 养了一只猫
Pet *Cat
func main()
// 初始化一只猫的指针
pet := &Cat
Name: "kenny",
Weight: 20.3,
Color: "white",
// 初始化一个人
person := Person
Name: "zhangsan",
Age: 25,
Pet: pet,
fmt.Println(person)
匿名结构体
// 结构体作为函数参数
func test(msg *struct
ID string
Name string
Age int
)
fmt.Printf("id: %v, name: %v, age: %v", msg.ID, msg.Name, msg.Age)
func main()
// 调用函数,传入匿名的结构体
test(&struct
ID string
Name string
Age int
"asdfasdf",
"wangwu",
25,
)
// 打印结果:id: asdfasdf, name: wangwu, age: 25
模拟构造函数
golang没有Java中的类的概念,自然也没有类的构造方法,但是可以模拟结构体的构造函数,比如如下代码:
// 结构体: 猫
type Cat struct
Name string
Color string
// 模拟猫的构造函数,传入姓名
func NewCatWithName(name string) *Cat
return &Cat
Name: name,
// 模拟猫的构造函数,传入猫的颜色
func NewCatWithColor(c string) *Cat
return &Cat
Color: c,
func main()
// 调用“构造函数”创建两个猫
c1 := NewCatWithColor("black")
c2 := NewCatWithName("kenny")
fmt.Println(c1, c2)
模拟继承
golang中在一个结构体中嵌入另一个结构体,来完成类似于面向对象编程中的类的继承,如下代码:
// 结构体 表示动物
type Animal struct
Color string
// 结构体 猫
type Cat struct
Animal // 这里嵌入了Animal这个结构体,类似于Cat继承了Animal
Name string
func main()
cat := Cat
// Cat类中没有声明Color,但是由于嵌入了Animal,所以也有了Color字段
cat.Color = "black"
cat.Name = "haha"
fmt.Println(cat)
给结构体添加方法
在面向对象编程中,我们除了给类添加成员变量,还可以为类添加方法,在golang中定义结构体时,只能定义结构体中的成员变量,要为结构体添加方法,只能使用函数来实现,如下代码:
// 定义结构体 猫
type Cat struct
Color string
// 为猫添加一个Eat()方法
func (c *Cat) Eat()
fmt.Printf("The %s cat is eating...\\n", c.Color)
func main()
cat := &Cat
Color: "black",
// The black cat is eating...
cat.Eat()
上面的代码为猫这个结构体添加了一个Eat
方法,在定义Eat
函数时,func
后面紧接着的是(c *Cat)
,这个(c *Cat)
叫做接收器,表示该函数作用的对象,因为是*Cat
,所以表示Eat
方法作用于Cat
指针上,于是在main
函数里,初始化了一个cat
指针,就可以直接使用cat.Eat()
来调用Eat
函数了。
golang里的接收器分为两种:指针类型的接收器和非指针类型的接收器。
上面的代码中展示的是指针类型的接收器,其实也可以定义非指针类型的接收器,如下代码:
// 点,包含两个坐标值
type Point struct
X int
Y int
// 非指针类型的接收器
func (p Point) Add(a, b int) Point
return Point
X: p.X + a,
Y: p.Y + b,
func main()
p := Point
X: 0,
Y: 0,
p1 := p.Add(1, 1)
fmt.Println(p1)
在上面的代码中,Add
是Point
的一个方法,该方法接受两个整型数据,返回一个Point
,Add
函数的接收器是一个Point
结构体,而非结构体的指针类型。
指针类型接收器与非指针类型接收器的区别:
- 小对象比较适合使用非指针类型的接收器,因为其复制时速度较快
- 大对象比较适合使用指针类型的接收器,因为大对象的复制性能较差,使用指针速度更快
给基本数据类型添加方法
// 定义一个MyInt类型(就是int型)
type MyInt int
// 给MyInt型的变量添加一个isZero方法
func (i MyInt) isZero() bool
return i == 0
func main()
var i MyInt = 3
fmt.Println(i.isZero())
方法和函数的统一调用
这里说的方法,指的是与某个结构体关联起来的函数,该函数具有接收器;而普通的使用func
定义的,称为函数。下面的代码展示了方法与函数的统一调用:
type Person struct
// 定义Person的sing方法
func (p *Person) sing(song string)
fmt.Printf("the person is singing %s\\n", song)
// 定义一个单独的sing函数
func sing(song string)
fmt.Printf("call function sing, the song is %s\\n", song)
func main()
// 定义f
var f func(string)
p := &Person
// 将f赋值为Person的成员方法
f = p.sing
f("My heart will go on")
// 将f赋值为独立的函数
f = sing
f("My heart will go on")
上面的代码证明了,如果方法与函数具有相同的签名,则可以使用与它们签名一致的变量保存该方法或函数。
类型内嵌结构体
golang中的结构体在声明时,可以只写字段类型而不写字段名称,这种结构体称为类型内嵌或匿名字段类型内嵌,如下代码所示:
// 定义Data结构体,该结构体字段只有类型没有名称
type Data struct
string
int
float32
func main()
// 初始化结构体
data := &Data
string: "zhangsan",
int: 20,
float32: 80.5,
// 打印: &zhangsan 20 80.5
fmt.Println(data)
结构体的内嵌与初始化
下面以一个例子说明结构体的内嵌,房子由门和窗户组成,如下代码:
// 窗户
type Window struct
Width int
Height int
// 门
type Door struct
Width int
Height int
// 房子
type House struct
Window
Door
func main()
// 初始化House的方式
house := &House
Window: Window
Width: 10,
Height: 10,
,
Door: Door
Width: 20,
Height: 45,
,
fmt.Println(house)
上面的代码如果把Door这个结构体去掉,而直接把Door的结构写在House里,就成了嵌套的匿名结构体,如下代码:
// 窗户
type Window struct
Width int
Height int
// 房子
type House struct
Window
// 门直接以内嵌形式声明,而不单独声明结构体
Door struct
Width int
Height int
func main()
house := &House
Window: Window
Width: 10,
Height: 10,
,
// 初始化House时给Door赋值的方法如下:
Door: struct
Width int
Height int
Width: 20,
Height: 45,
,
fmt.Println(house)
以上是关于golang学习笔记4——结构体的主要内容,如果未能解决你的问题,请参考以下文章