9.1 结构体
结构体是值类型,所以也可以用new来创建。
结构体中,字段名是唯一的。
Go中没有面向对象语言中的类,而结构体struct实现了类似的功能。所以可以把结构体struct想象成一个没有方法的轻量级的类。
声明:
type myst struct {name stringage intsex bool}
初始化:
s := myst{} //初始化s1 := new(myst) //分配内存fmt.Println(s) //返回字段的零值{ 0 false}fmt.Println(s1) //返回内存的指针&{ 0 false}
9.1.1 工厂模式
package mainimport "fmt"//定义一个结构体type myst struct {name stringage intsex 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 mainimport "fmt"//定义一个结构体type myst struct {name stringage intsex 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 mainimport "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 mainimport "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 mainimport "fmt"//顶结构体,内嵌cat和dog结构体type Both struct {c catd 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}
