从零学习go语言(五)

152 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 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("做炒鸡蛋")
}

image.png

这是接口很典型的一种应用,我学的时候看着视频百思不得其解。于是求教于一个已经学习完 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
}

image.png

通过这种方式可以实现不同类型相加,不必将参数限制在某种类型上,大大提升了效率。

继承和组合

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称为外部类型。此后声明的时候要一起声明。使用的时候可以像自己的字段一样直接使用。外部类型使用内部类型的方法同理。但是如果外部类型和内部类型定义了一样的方法,外部类型方法会覆盖内部类型方法,又称方法复写。