一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第17天,点击查看活动详情。
结构体
结构体是一种聚合类型,里面可以包含任意类型的值,这些值就是我们定义的结构体的成员,又称字段。
格式:
type structName struct {
fieldName typeName
}
fieldName是结构体的字段名,typeName是对应的字段类型。字段可以是零个、一个或者多个。
结构体声明使用
type person struct {
name string
age uint
}
var p person //如果不初始化则使用默认的零值
p := person{"yu",19}//声明并字面量方式初始化
fmt.Println(p.name,p.age)
注意:结构体内的字段可以是结构体类型的
type person struct {
name string
age uint
address address
}
type address struct {
province string
city string
}
接口
接口是和调用方的一种约定,是一个高度抽象的类型,不用和具体的实现细节绑定在一起。
func main() {
xihongshi := &XiHongShi{}
doCook(xihongshi)
fmt.Println("\n=====> 做另外一道菜")
// 做炒鸡蛋
chaojidan := &ChaoJiDan{}
doCook(chaojidan)
}
type Cooker interface {
fire()
cooke()
outfire()
}
// CookMenu 类似于一个抽象类
type CookMenu struct {
}
func (CookMenu) fire() {
fmt.Println("开火")
}
// 做菜,交给具体的子类实现
func (CookMenu) cooke() {
}
func (CookMenu) outfire() {
fmt.Println("关火")
}
// 封装具体步骤
func doCook(cook Cooker) {
cook.fire()
cook.cooke()
cook.outfire()
}
type XiHongShi struct {
CookMenu
}
func (*XiHongShi) cooke() {
fmt.Println("做西红柿")
}
type ChaoJiDan struct {
CookMenu
}
func (ChaoJiDan) cooke() {
fmt.Println("做炒鸡蛋")
}
这是接口很典型的一种应用,我学的时候看着视频百思不得其解。于是求教于一个已经学习完 go 语言并即将找工作的同学。经过他的一番讲解才有一点点思路。
Go的接口不同于我学习的任何一门语言,我的理解是通过接口可以实现类似于继承的东西,只不过接口是方法的集合。不过接口与继承还是有很多区别的,希望深入学习能了解透彻。
泛型
大佬还给我讲了讲最近出的Go语言泛型,泛型的概念与其他语言倒是十分相似,只是目前泛型还不支持结构体类型。
func main() {
var a int64
var b int64
fmt.Println(add(1.222, 2.333))
fmt.Println(add("faweawfe", "sdafawes"))
}
type addable interface {
int | int64 | float32 | float64 | string | uint
}
func add[V addable](a, b V) V {
return a + b
}
通过这种方式可以实现不同类型相加,不必将参数限制在某种类型上,大大提升了效率。
继承和组合
Go语言没有继承的概念,所以结构、接口之间也没有父子关系。Go语言提倡用组合达到代码复用的目的。
type Reader interface {
Read(p []byte) (n int, err error)
}
type Writer interface {
Write(p []byte) (n int, err error)
}
type ReadWriter interface {
Reader
Writer
}
ReadWriter是Reader和Writer的组合,通过这种方式ReadWriter可以不用定义自己的方法。达到代码复用的目的。
type person struct {
name string
age uint
address
}
type address struct {
province string
city string
}
fmt.Println(p.province)
在结构体里也可以进行组合,组合后address称为内部类型,person称为外部类型。此后声明的时候要一起声明。使用的时候可以像自己的字段一样直接使用。外部类型使用内部类型的方法同理。但是如果外部类型和内部类型定义了一样的方法,外部类型方法会覆盖内部类型方法,又称方法复写。