Go interface详解

栏目: Go · 发布时间: 7年前

内容简介:如interface(接口)是golang最重要的特性之一,Interface类型可以定义interface是为实现多态功能,多态是指代码可以根据类型的具体实现采取不同行为的能力。如果一个类型实现了某个接口,所有使用这个接口的地方,都可以支持这种类型的值。

  如 Go method 中提及,Golang没有明确支持多态,但是通过其他手段可以实现类似C++中的多态特性,即本文中即将介绍的Go interface功能。

interface定义

  interface(接口)是golang最重要的特性之一,Interface类型可以定义 一组方法 ,但是这些不需要实现。请注意:此处限定是 一组方法 ,既然是方法,就不能是变量;而且是 一组 ,表明可以有多个方法。再多声明一点,interface本质上是一种类型,确切的说,是 指针类型 ,此处暂且不多表,后文中自然能体会到。

  interface是为实现多态功能,多态是指代码可以根据类型的具体实现采取不同行为的能力。如果一个类型实现了某个接口,所有使用这个接口的地方,都可以支持这种类型的值。

type  接口名称 interface {
    method1(参数列表) 返回值列表
    method2(参数列表) 返回值列表
    ...
    methodn(参数列表) 返回值列表
}

  接口通常以er作为名称后缀,方法名是声明组成部分,但参数名可不同或省略。如果接口没有任何方法声明,那么就是一个空接口(interface{}),它的用途类似面向对象里的根类型Object,可被赋值为任何类型的对象。接口变量默认值是nil。如果实现接口的类型支持,可做相等运算。

func main() { 
   var t1,t2 interface{} 
   println(t1==nil,t1==t2) 
  
   t1,t2=100,100
   println(t1==t2) 
  
   t1,t2=map[string]int{},map[string]int{} 
   println(t1==t2) 
}

输出为

true true
true
panic:runtime error:comparing uncomparable type map[string]int

  此外,还可以像匿名字段那样,嵌入其他接口。目标类型方法集中必须拥有包含嵌入接口方法在内的全部方法才算实现了该接口。

type stringer interface{ 
   string()string
} 
  
type tester interface{ 
   stringer               // 嵌入其他接口 
   test() 
} 
  
type data struct{} 
  
func(*data)test() {
} 

func(data)string()string{ 
   return""
} 
  
func main() { 
   var d data
  
   var t tester= &d
   t.test() 
   println(t.string()) 
}

interface应用场景

类型转换

  类型推断可将接口变量还原为原始类型,或用来判断是否实现了某个更具体的接口类型。

type data int
  
func(d data)String()string{ 
   return fmt.Sprintf("data:%d",d) 
} 
  
func main() { 
   var d data=15
   var x interface{} =d
  
   if n,ok:=x.(fmt.Stringer);ok{  // 转换为更具体的接口类型 
       fmt.Println(n) 
    } 
  
   if d2,ok:=x.(data);ok{        // 转换回原始类型 
       fmt.Println(d2) 
    } 
  
   e:=x.(error)           // 错误:main.data is not error
   fmt.Println(e) 
}

输出为:

data:15
data:15
panic:interface conversion:main.data is not error:missing method Error

  但是此处会触发 panic ,使用ok-idiom模式,即便转换失败也不会引发panic。还可用switch语句在多种类型间做出推断匹配,这样空接口就有更多发挥空间。

func main() {
var x interface{} =func(x int)string{ 
       return fmt.Sprintf("d:%d",x) 
    } 
  
   switch v:=x.(type) {            // 局部变量v是类型转换后的结果 
   case nil: 
       println("nil") 
   case*int: 
       println(*v) 
   case func(int)string: 
       println(v(100)) 
   case fmt.Stringer: 
       fmt.Println(v) 
   default: 
       println("unknown") 
    } 
}

输出为:

d:100

实现多态功能

  多态功能是interface实现的重要功能,也是Golang中的一大行为特色,其多态功能一般要结合Go method实现,作为函数参数可以容易的实现多台功能。

package main

import "fmt"

// notifier是一个定义了通知类行为的接口
type notifier interface {
  notify()
}

// 定义user及user.notify方法
type user struct {
  name string
  email string
}

func (u *user) notify() {
  fmt.Printf("Sending user email to %s<%s>\n",
    u.name,
    u.email)
}

// 定义admin及admin.notify方法
type admin struct {
  name string
  email string
}

func (a *admin) notify() {
  fmt.Printf("Sending admin email to %s<%s>\n",
    a.name,
    a.email)
}

func main() {
  // 创建一个user值并传给sendNotification
  bill := user{"Bill", "bill@email.com"}
  sendNotification(&bill)

  // 创建一个admin值并传给sendNotification
  lisa := admin{"Lisa", "lisa@email.com"}
  sendNotification(&lisa)
}

// sendNotification接受一个实现了notifier接口的值
// 并发送通知
func sendNotification(n notifier) {
  n.notify()
}

  上述代码中实现了一个多态的例子,函数 sendNotification 接受一个实现了notifier接口的值作为参数。既然任意一个实体类型都能实现该接口,那么这个函数可以针对任意实体类型的值来执行 notify 方法,调用 notify 时,会根据对象的实际定义来实现不同的行为,从而实现多态行为。


以上所述就是小编给大家介绍的《Go interface详解》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Python编程

Python编程

[美]埃里克·马瑟斯 / 袁国忠 / 人民邮电出版社 / 2016-7-1 / CNY 89.00

本书是一本针对所有层次的Python 读者而作的Python 入门书。全书分两部分:第一部分介绍用Python 编程所必须了解的基本概念,包括matplotlib、NumPy 和Pygal 等强大的Python 库和工具介绍,以及列表、字典、if 语句、类、文件与异常、代码测试等内容;第二部分将理论付诸实践,讲解如何开发三个项目,包括简单的Python 2D 游戏开发如何利用数据生成交互式的信息图......一起来看看 《Python编程》 这本书的介绍吧!

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具