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{}类型(空接口类型),比如

packagemain

import"fmt"

/*

**用于输出数组元素

*/

funcechoArray(ainterface{}){

  for_,v:=rangea{

    fmt.Print(v," ")

  }

  fmt.Println()

  return

}

funcmain(){

  a:=[]int{2,1,3,5,4}

  echoArray(a)

}

//以上代码将会报错,因为对于echoArray()而言,a是interface{}类型,而不是[]int类型

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

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

1

2

3

4

5

6

7

8

funcechoArray(ainterface{}){

b,_:=a.([]int)//通过断言实现类型转换

  for_,v:=rangeb{

    fmt.Print(v," ")

  }

  fmt.Println()

  return

} 

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

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

1

2

3

4

b,ok:=a.([]int)

ifok{

...

}

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

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

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

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