go接口笔记下

119 阅读3分钟

「这是我参与2022首次更文挑战的第22天,活动详情查看:2022首次更文挑战」。

0 环境

1 指针接收者

如下:指针类型 --> (u users),区别多了一个

func (u *users) show() string{
}

指针接收案例。

type users struct {
   id uint
   usersName string
   addr addr
}

type addr struct {
   city string
}

type Stringser interface {
    show() string
}

func (u *users) show() string {
   fmt.Println("the usersname is -->",u.usersName," |id is -->",u.id)
   return "ok"
}

func printStr(u Stringser) {
   fmt.Println(u.show())
}

func structShow()  {
   u := users{usersName:"小明", id: 1, addr : addr{
      city: "美国",
   }}
   printStr(u)
   printStr(&u)
   
}

func main() {
   structShow()
}

image.png

image.png

可以看出直接值类型传值,会报没有实现这个接口,也就是说这里的指针类型只对应&u。也就是说:接收者是值类型的话,类型本身还是指针类型都可以实现接口。但是接收者是指针类型,只能*类型(* users)才可以实现接口。

2 组合和继承

go语言中没有继承。现在学到的结构体和接口(是没有继承关系的),正常情况下:组合用的多,特点是可复用(灵活)。

组合的思想,在定义结构体的时候,就已经用上了,我定义了一个users的结构体,它的内部又加进去了一个结构体类型,这就是组合了。但是这样子,我们怎么区分它们呢,总不能说组合和被组合的结构体类型吧,组合了其他结构体的(xx {xx 其他结构体}),叫外部类型。被组合了的叫内部类型(外部类型 { 内部结构体 --> 内部类型})。说白了,{}左边的是外部类型,{}里面的是内部类型。

type users struct {
   id uint
   usersName string
   addr addr
}

type addr struct {
   city string
}

接口也是类似。

type a interface {
    showa()
}
type b interface {
    showb()
}

type c interface {
    a
    b
}

3 类型断言

查看我想知道哪些个接口已经被调用过了,用接口变量. (接收者类型),注意:类型不能把括号省略哦。要用if else判断,若是只用if ok {}判断,当结果okfalse时,并且没有else判断,它会抛出异常,终止程序运行。

image.png

只是上面代码指针接收者里的代码,做了拓展,具体内容如下:

func (addr addr) show() string {
   fmt.Println("the addr is -->",addr.city)
   return "ok"
}

func printStr(u Stringser) {
   a, ok := u.(addr)
   if ok {
      fmt.Println("addr -->",a)
   } else {
      fmt.Println("不是addr")
   }

   b, ok1 := u.(*users)
   if ok1 {
      fmt.Println("*users -->",b)
   } else {
      fmt.Println("不是*users")
   }

   fmt.Println(u.show())
}

image.png

4 总结

对于接收者类型是值类型时,它对于类型,一视同仁(不挑食的人)。而对于接收者类型是指针类型时,它比较挑剔,只认自己人(挑食的人)。有时候我们想知道挑食的那位或者不挑食的那位,今天是否吃了没(类型断言),注意加()和判断语句里加else。对于组合来说,就有点套娃,在外面的那个娃叫外面类型,在里面的那个娃叫内部类型。