欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

详解Golang语言中的interface

程序员文章站 2022-07-02 10:48:02
interface是一组method签名的组合,interface可以被任意对象实现,一个对象也可以实现多个interface。任意类型都实现了空interface(也就是包含0个method的int...

interface是一组method签名的组合,interface可以被任意对象实现,一个对象也可以实现多个interface。任意类型都实现了空interface(也就是包含0个method的interface),空interface可以存储任意类型的值。interface定义了一组方法,如果某个对象实现了某个接口的所有方法,则此对象就实现了此接口。

go version go1.12

package main

import (
  "fmt"
)

// 定义struct
type human struct {
  name string
  age  int
  phone string
}
type student struct {
  human // 匿名字段
  school string
  loan  float32
}
type employee struct {
  human  // 匿名字段
  company string
  money  float32
}

// human对象实现sayhi()方法
func (h human) sayhi() {
  fmt.printf("hi, i am %s, you can call me on %s\n", h.name, h.phone)
}

// human对象实现sing()方法
func (h human) sing(lyrics string) {
  fmt.println("la la la...", lyrics)
}

// human对象实现guzzle()方法
func (h human) guzzle(beerstein string) {
  fmt.println("guzzle guzzle guzzle...", beerstein)
}

// employee对象重写sayhi()方法
func (e employee) sayhi() {
  fmt.printf("hi i am %s, i work at %s. call me on %s\n", e.name, e.company, e.phone)
}

// student对象实现borrowmoney()方法
func (s student) borrowmoney(amount float32) {
  s.loan += amount
}

// employee对象实现spendsalary()方法
func (e employee) spendsalary(amount float32) {
  e.money -= amount
}

// 定义interface,interface是一组method签名的组合
// interface可以被任意对象实现,一个对象也可以实现多个interface
// 任意类型都实现了空interface(也就是包含0个method的interface)
// 空interface可以存储任意类型的值
// interface men的3个method被human,student,employee实现,也就是这3个对象都实现了interface men。即:
// interface定义了一组方法,如果某个对象实现了某个接口的所有方法,则此对象就实现了此接口。
type men interface {
  sayhi()
  sing(lyrice string)
  guzzle(beerstein string)
}

// interface youngchap的borrowmoney() method只被student对象实现,也就是只有student实现了youngchap
type youngchap interface {
  sayhi()
  sing(song string)
  borrowmoney(amount float32)
}

// interface elderlygent的spendsalary() method只被employee对象实现,也就是只有employee实现了elderlygent
type elderlygent interface {
  sayhi()
  sing(song string)
  spendsalary(amount float32)
}

func main() {
  // 定义student类型的变量
  lucy := student{human{"lucy", 19, "10086"}, "tsinghua", 100.00}
  lily := student{human{"lily", 19, "10086"}, "tsinghua", 100.00}
  liming := student{human{"liming", 19, "10086"}, "tsinghua", 100.00}
  // 定义employee类型的变量
  tom := employee{human{"tom", 29, "10000"}, "google", 200.00}
  // 定义men类型的变量i
  var i men
  // i存储student
  i = lucy
  fmt.println("this is lucy, a student:")
  i.sayhi()
  i.sing("happy birthday")
  i.guzzle("ha ha ha...")

  // i存储employee
  i = tom
  fmt.println("this is tom, an employee:")
  i.sayhi()

  // 定义slice men,包含men类型元素的切片,这个slice可以被赋予实现了men接口的任意结构的对象
  fmt.println("let's use a slice of men and see what happens:")
  x := make([]men, 3)
  // 三个不同类型(不同method)的元素,实现了同一个interface(men)
  x[0], x[1], x[2] = lucy, lily, liming
  for _, value := range x {
    value.sayhi()
  }
}

函数参数

interface接口还可以作为函数参数,因为interface的变量可以持有任意实现该interface类型的对象,我们可以通过定义interface参数,让函数接受各种类型的参数。 判断interface变量存储的元素的类型,目前常用的有两种方法:comma-ok断言和switch测试。

go version go1.12

/**
 * interface接口作为函数参数
 * 判断interface变量存储的元素的类型
 */
package main

import (
  "fmt"
  "strconv"
)

// 定义human对象
type human struct {
  name string
  age  int 
  phone string
}

// 定义空接口
type element interface{}

// 定义切片
type list []element

// 定义person对象
type person struct {
  name string
  age int 
}

// 通过定义interface参数,让函数接受各种类型的参数
// 通过这个method(方法),human对象实现了fmt.stringer接口
// stringer接口是fmt.println()的参数,最终使得human对象可以作为fmt.println的参数被调用
func (h human) string() string {
  return "<" + h.name + " - " + strconv.itoa(h.age) + " years - phone: " + h.phone + ">" 
}

// 通过定义interface参数,让函数接受各种类型的参数
// 通过这个method(方法),person对象实现了fmt.stringer接口
// stringer接口是fmt.println()的参数,最终使得person对象可以作为fmt.println的参数被调用
func (p person) string() string {
  return "(name: " + p.name + " - age: " + strconv.itoa(p.age) + " years)"
}

func main() {
  // interface作为函数的参数传递
  lucy := human{"lucy", 29, "10086"}
  fmt.println("this human is:", lucy)

  list := make(list, 3)
  list[0] = 100
  list[1] = "hello golang!"
  list[2] = person{"lily", 19}

  // comma-ok断言
  for index, element := range list {
    // 判断变量的类型 格式:value, ok = element(t)
    // value是interface变量的值,ok是bool类型,element是interface的变量,t是断言的interface变量的类型
    if value, ok := element.(int); ok {
      fmt.printf("list[%d] is an int and it's value is %d\n", index, value)
    } else if value, ok := element.(string); ok {
      fmt.printf("list[%d] is a string and it's value is %s\n", index, value)
    } else if value, ok := element.(person); ok {
      fmt.printf("list[%d] is a person and it's value is %s\n", index, value)
    } else {
      fmt.printf("list[%d] is a different type\n", index)
    }
  }

  // switch
  for index, element := range list {
    // 注意:element.(type)语法不能在switch外的任何逻辑中使用
    switch value := element.(type) {
    case int:
      fmt.printf("list[%d] is an int, it's value is %d\n", index, value)
    case string:
      fmt.printf("list[%d] is a string, it's value is %s\n", index, value)
    case person:
      fmt.printf("list[%d] is a person, it's value is %s\n", index, value)
    default:
      fmt.printf("list[%d] is a differernt type", index)
    }
  }
}

以上就是详解golang语言中的interface的详细内容,更多关于golang语言中的interface的资料请关注其它相关文章!

相关标签: Golang interface