前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Go通关06:struct和interface,结构体和接口的使用

Go通关06:struct和interface,结构体和接口的使用

作者头像
微客鸟窝
发布2021-08-18 15:19:07
2.4K0
发布2021-08-18 15:19:07
举报
文章被收录于专栏:Go语言指北

您诸位好啊,我是无尘,今天跟大家介绍下Go结构体和接口都实现了哪些功能?

结构体

定义

结构体是种聚合类型,里面可以包含任意类型的值,这些值就是结构体的成员,或成为字段,定义结构体,需要使用 「type+struct」 关键字组合

代码语言:javascript
复制
type person struct { //人结构体
  name string //人的名字
  age uint //人的年龄
}
  1. type 与 struct 是关键字,用来定义一个新结构体的类型。
  2. person 为结构体名字。
  3. name/age 为结构体的字段名,后面指对应的字段类型。
  • 字段声明和变量类似,变量名在前,类型在后
  • 字段可以是人一个,一个字段都没有的结构体,成为空结构体。
  • 结构体也是一种类型,比如 person 结构体和 person 类型是一个意思。

声明

  1. 像普通字符串、整型一样声明初始化var p person

❝声明了一个person类型的变量p,但是没有初始化,所以默认使用结构体里字段的零值。 ❞

  1. 字面量方式初始化p := person{"无尘",18}

❝表示结构体变量 p 的name字段初始化为“无尘”,age字段初始化为18。顺序必须和字段定义顺序一致。 ❞

  1. 根据字段名称初始化p := person{age:18,name:"无尘"}

❝像这样指出字段名,就可以打乱初始化字段的顺序。也可以只初始化其中部分字段,剩余字段默认使用零值: p := person{age:30}

字段结构体

结构体字段可以是任意类型,包括自定义的结构体类型:

代码语言:javascript
复制
type person struct { //人结构体
  name string
  age uint
  addr address //使用自定义结构体类型
}
type address struct { //地址结构体
  city string
}

对于这样嵌套结构体,初始化和一般结构体类似,根据字段对应的类型初始化即可:

代码语言:javascript
复制
p := person {
  age:18,
  name:"无尘",
  addr:address{
    city:"北京",
  },
}

结构体的字段和调用一个类型的方法一样,都是使用点操作符“.”:

代码语言:javascript
复制
fmt.Println(p.age)
//访问嵌套结构体里的city字段的值:
fmt.Println(p.addr.city) 

接口

定义

接口是一个抽象的类型,是和调用方的一种约定。接口只需要定义约定,告诉掉用方可以做什么,而不用知道它的内部实现。 接口的定义是 「type + interface」关键字类实现。

代码语言:javascript
复制
//Info 是一个接口,它有方法 Getinfo()string
type Info interface {
  Getinfo() string
}

❝对应 Stringer 接口,它会告诉调用者可以通过 String()放获取一个字符串,这就是接口的约定,而这个字符串是怎么获取到的,接口并不关心,调用者也不用关心,因为这些是接口的实现者来处理的。 ❞

接口的实现

接口的实现者必须是一个具体的类型:

代码语言:javascript
复制
func (p person) Getinfo() string {
  return fmt.Sprintf("my name is %s,age is %d",p.name,p.age)
} 
  • 给结构体类型 person 定义了一个方法,这个方法和接口里的方法名称、参数、返回值都一样,就表示这个结构体 person 实现了 Info 接口。
  • 如果一个接口有多个方法,那么要实现接口中的所有方法才算是实现了这个接口。

使用

我们先定义一个可以打印 Info 接口的函数:

代码语言:javascript
复制
func printInfo(i Info) {
  fmt.Println(i.Getinfo())
}
  • 定义函数 pringInfo,它接收一个 Info 接口类型的参数,然后打印接口 Getinfo 方法返回的字符串。
  • 这个 pringInfo 函数此处是面向接口编程,只有任何一个类型实现了Info接口,都可以使用这个函数打印出对应的字符串,而不用关心具体的类型实现。
代码语言:javascript
复制
printInfo(p) 
//结果为:my name is 无尘,age is 18

❝因为 person 类型实现了Info接口,所以变量p可以作为函数printInfo的参数。 ❞

值接受者、指针接受者

  1. 实现一个接口,必须实现接口中所有的方法。
  2. 定义一个方法,有值类型接收者和指针类型接收者,两者都可以调用方法,因为Go编译器自动做了转换。
  3. 「但是接口的实现,值类型接收者和指针类型接收者不一样」

上面接口体person实现了Info接口,是否结构体指针也实现了该接口呢?

代码语言:javascript
复制
printInfo(&p)

测试发现p的指针作为参数函数也是可以正常运行,表明「以值类型接收者实现接口,类型本身和该类型的指针类型,都实现了该接口」

那么把接收者改成指针类型:

代码语言:javascript
复制
func (p *person) Getinfo() string {
 return fmt.Sprintf("my name is %s,age is %d",p.name,p.age)
}

然后再调用函数 printInfo(p),代码编译不通过,表明「以指针类型接收者实现接口,只有对应的指针类型才被认为实现了接口」

方法接收者

实现接口类型

(p person)

person和*person

(p *person)

*person

  • 当值类型作为接收者,person类型和*person类型都实现了该接口。
  • 当指针类型作为接收者,只有 *person类型实现了该接口。

有什么问题,可以公众号内回复或加我微信交流。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-07-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 微客鸟窝 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 结构体
    • 定义
      • 声明
        • 字段结构体
        • 接口
          • 定义
            • 接口的实现
              • 使用
                • 值接受者、指针接受者
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档