首页 > 代码库 > GO 接口

GO 接口

一 接口

Go语言中的接口是一些方法的集合(method set),它指定了对象的行为:如果它(任何数据类型)可以做这些事情,那么它就可以在这里使用.EG

type I1 interface {
    Hello(name string)
    Get() int
    Set(v int)
}

type I1_Impl struct {
    val int
}

func (i *I1_Impl) Hello(name string) {
    fmt.Println(name)
}

func (i *I1_Impl) Get() int {
    return i.val
}

func (i *I1_Impl) Set(v int) {
    //需要是指针,否则设置值会失效.
    i.val = v
}

func test_interface(i I1) interface{} {
    if i != nil {
        i.Hello("yyyy")
        fmt.Println("get init val :", i.Get())
        i.Set(999)
        fmt.Println("get set val :", i.Get())
    }
    return "hello interface"
}

func main() {

    xxxx := &I1_Impl{val: 100}
    ret := test_interface(xxxx) //接口赋值
    fmt.Println(ret)

二 空接口

在Go语言中,所有其它数据类型都实现了空接口。

var v1 interface{} = 1
var v2 interface{} = "abc"
var v3 interface{} = struct{ X int }{1}

如果函数打算接收任何数据类型,则可以将参考声明为interface{}

    //空接口,万能变量
    var any interface{}
    any = 1
    any = true
    any = "hello"
    fmt.Println(any)

三 类型转换

interface{}可用于向函数传递任意类型的变量,但对于函数内部,该变量仍然为interface{}类型(空接口类型),比如

package main

import "fmt"
/*
**用于输出数组元素
*/
func echoArray(a interface{}){
  for _,v:=range a{
    fmt.Print(v," ")
  }
  fmt.Println()
  return
}
func main(){
  a:=[]int{2,1,3,5,4}
  echoArray(a)
}
//以上代码将会报错,因为对于echoArray()而言,a是interface{}类型,而不是[]int类型

接口类型向普通类型的转换称为类型断言(运行期确定)

 

所以前面代码中,将echoArray()做如下修改即可:

1
2
3
4
5
6
7
8
func echoArray(a interface{}){
    b,_:=a.([]int)//通过断言实现类型转换
  for _,v:=range b{
    fmt.Print(v," ")
  }
  fmt.Println()
  return
} 

-----------------------15/11/8更新---------------------------------

注意:在使用断言时最好用 

1
2
3
4
b,ok:=a.([]int)
if ok{
    ...
}

的形式,这样能根据ok的值判断断言是否成功。

因为断言失败在编译阶段不会报错,所以很可能出现断言失败导致运行错误,而你却迟迟找不到原因(亲身经历)。  

-----------------------15/11/21更新----------------------------- 

注意:不同类型变量的运算必须进行显式的类型转换,否者结果可能出错

GO 接口