一 接口
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更新-----------------------------
注意:不同类型变量的运算必须进行显式的类型转换,否者结果可能出错