测试小站: 处理网 回收帮 培训网 富贵论坛 老富贵论坛

Go语言中接口相关知识点汇总

  最近公司有项目需要使用go语言来重构以前用php编写的项目,我其实对go没啥兴趣,但是为了生活,只能啃起来了,这里借`狂神`的名言,与君共勉吧!

  ---------

  只要学不死,就往死里学! ----狂神

  ---------

  接口的定义

  在支持面向对象的语言里,基本上都有接口概念, 接口的定义:它是定义一个对象的行为,具体的实现细节,由对象本身确定

  接口的关键字:interface

  接口的声明与实现

  //声明 一个接口

  type Person interface{

  eat()

  }

  //创建一个结构体,模拟一个类,在go语言中没有class的概念!

  type Man struct{

  name string

  }

  //这里是Man类型实现了接口里的方法eat(),也就可以说它实现了接口(这里需要全部实现了接口里的方法,才是实现了接口)

  func (p Man) eat() {

  fmt.Println(p.name,",有好吃的吗?")

  }

  //实现

  func main() {

  var v Person

  man :=Man{name: "test"}

  //这里注意,由于man是实现了Person的接口,要不是会报错的

  v=man

  v.eat()

  }

  总结

  //1.go里面没有implement关键字

  //2.只要是类型实现了接口里的所有方法,就可以说是它是实现了这个接口

  实际应用

  //举个实际中的例子,在项目里,我们有个一个针对不同等级的会员,积会计算的方式会有些不同,这个场景是非常合适用接口来解决的,

  //定义一个计算积分的接口,不同的等级会员都实现自己的计算方法就可以

  //定义一个计算积分的接口

  type CalcPoint interface{

  calc() float64

  }

  //定义一个普通会员的结构体

  type ComMember struct{

  name string

  score float64

  }

  func (c ComMember) calc() float64 {

  return c.score+10

  }

  //定义一个高级会员的结构体

  type GoldMember struct{

  name string

  score float64

  }

  func (g GoldMember) calc() float64 {

  return g.score+20

  }

  //这里就简化了,这里做个无用功能吧,就是计算下,所有人的积分总和是多少

  //定义一个接收calcPoint类型参数的 函数

  func getTotalScore(members []CalcPoint) {

  total :=0.00

  for _, member :=range members {

  total=total+member.calc()

  }

  fmt.Println("总积分",total)

  }

  func main() {

  //创建一个普通会员

  member1 :=ComMember{

  name: "ton",

  score: 78,

  }

  //创建一个高级会员

  member2 :=GoldMember{

  name: "uzi",

  score: 89,

  }

  members :=[]CalcPoint{member1,member2}

  getTotalScore(members) // 返回值197

  }

  空接口

  空接口:没有包含方法的接口,所以在go语言中,所有的类型都是空接口

  表示方法:interface{}

  类型断言

  //类型断言

  i.(T) //接口i的具体类型T

  //

  func main(){

  var s interface{}="abc"

  a,ok :=s.(string)//a=>值,ok,如果断言成功,返回true,否则返回false

  fmt.Println(a,ok)

  }

  //使用switch case进行类型选择

  func findType(i interface{}){

  switch i.(type){ //注意这里i.(type)

  case int:

  fmt.Println("int")

  case string:

  fmt.Println("string")

  case float64:

  fmt.Println("float64")

  default:

  fmt.Println("没有找到")

  }

  }

  实现接口的方法:指针接收者和值接收者

  结论

  如果接收者类型为指针,则接收者的值只能是指针

  如果接收者类型为值类型,则接收者的值可以是指针或者是值

  代码说明

  package main

  import "fmt"

  type notifier interface{

  notify()

  }

  func sentNotify(n notifier) {

  n.notify()

  }

  type User struct{

  name string

  }

  func (u *User) notify() {//这里的值是指针类型接收者

  fmt.Println("user中的notify")

  }

  //如果这个值是值类型接收者时,在调用这个sentNotify()函数传参数时,可以是指针类型或者是值类型都可以

  func (u User) notify() {//这里的值是指针类型接收者

  fmt.Println("user中的notify")

  }

  func main() {

  u:=User{

  name: "abc",

  }

  //sentNotify(u)//这里是报错的 cannot use u (type User) as type notifier in argument to sentNotify:

  // User does not implement notifier (notify method has pointer receiver)

  //这意思也是说 这个接口方法接收指针类型的值,你给一个值类型的参数是不可以的

  //需要传指针类型的值

  sentNotify(&u)

  }

posted @ 2021-12-21 13:54  linjingyg  阅读(47)  评论(0)    收藏  举报