9.1 结构体
结构体是值类型,所以也可以用new来创建。
结构体中,字段名是唯一的。
Go中没有面向对象语言中的类,而结构体struct实现了类似的功能。所以可以把结构体struct想象成一个没有方法的轻量级的类。
声明:
type myst struct {
name string
age int
sex bool
}
初始化:
s := myst{} //初始化
s1 := new(myst) //分配内存
fmt.Println(s) //返回字段的零值{ 0 false}
fmt.Println(s1) //返回内存的指针&{ 0 false}
9.1.1 工厂模式
package main
import "fmt"
//定义一个结构体
type myst struct {
name string
age int
sex bool
}
//定义一个工厂,就是一个函数
func me(name string, age int, sex bool) *myst {
return &myst{ //返回指针
name: name,
age: age,
sex: sex,
}
}
func main() {
myinfo := me("吴彦祖", 18, true) //调用
fmt.Println(*myinfo) //{吴彦祖 18 true
}
如果不适用工厂模式,上述怎么写:
package main
import "fmt"
//定义一个结构体
type myst struct {
name string
age int
sex bool
}
//定义一个工厂
func me(name string, age int, sex bool) *myst {
m := myst{
name: name,
age: age,
sex: sex,
}
return &m
}
func main() {
myinfo := me("吴彦祖", 18, true) //调用
fmt.Println(*myinfo) //{吴彦祖 18 true
}
9.1.2 匿名和内嵌结构体
结构体内的字段可以没有名字,只有类型,类型是必须的。
一个结构体内,同一种类型的匿名字段,只能有一个。
结构体可以内嵌套娃的,以此来实现类似于面向对象的继承。
package main
import "fmt"
type myst struct {
name string "这是字段的标签" //姓名
age int //年龄
sex bool //性别
}
type myst2 struct {
int //匿名字段,身高
m myst //结构体类型
}
func main() {
myinfo := myst2{ //实例化
188, //匿名字段
myst{ //内嵌结构体
name: "吴彦祖",
age: 18,
sex: true,
},
}
fmt.Println(myinfo) //{188 {吴彦祖 18 true}}
}
9.2 方法
结构体就像面向对象中的简化的类,自然也有类方法。
Go中的方法是作用在接收者receiver上的一个函数。接收者可以是任意类型的变量,int,bool,struct等,多用于struct,但是不能是接口类型不能是指针类型,但是可以是其他类型的指针。
也就是说,方法还是面向对象的方法,只不过不是作用在类上,而是作用在类型上,尤其作用在结构体上。简单理解也可以把方法看作是结构体的一个字段。
一个类型(比如一个结构体)是可以有多个方法的。
不同类型的方法是可以同名的。
实现一个改名的例子:
package main
import "fmt"
type cat struct {
name string //姓名
age int //年龄
sex bool //性别
}
func (c *cat) changename(name string) { //changename方法作用在cat这个结构体上,传入指针
c.name = name
}
func main() {
mycat := cat{
name: "喵",
age: 1,
sex: true,
}
mycat.changename("汪") //传值改名
fmt.Println(mycat.name) //汪
}
9.2.1 多重继承
Go怎么利用结构体和方法实现多重继承呢?嵌套。
一个结构的两个字段都是结构体,这两个字段又分别有各自的方法,那么实例化第一个结构体,则同时拥有所有的方法。
package main
import "fmt"
//顶结构体,内嵌cat和dog结构体
type Both struct {
c cat
d dog
}
//猫结构体
type cat struct {
name string //姓名
age int //年龄
sex bool //性别
}
//猫改名的方法
func (c *cat) changename(name string) {
c.name = name
}
//狗结构体
type dog struct {
name string //姓名
age int //年龄
sex bool //性别
}
//狗改年龄的方法
func (d *dog) changenage(age int) {
d.age = age
}
func main() {
a := Both{ //实例化顶结构体
c: cat{
name: "喵",
age: 1,
sex: true,
},
d: dog{
name: "汪",
age: 2,
sex: false,
},
}
a.c.changename("喵2") //改猫名
a.d.changenage(3) //改狗年龄
fmt.Println(a.c.name, a.d.age) //喵2 3
}