golang接口代码:
Read more...
package main
import "fmt"
type S struct {
i int
}
func (p *S) Get() int {
return p.i
}
func (p *S) Put(v int){
p.i = v
}
type I interface{
Get() int
Put(int)
}
func f(p I){
fmt.Println(p.Get())
p.Put(1)
}
func main(){
var s S
f(&s)
fmt.Println(s.Get())
}
go代码分析:
开始定义了一个具有一个字段和两个方法的结构类型S
14-17行,定义了一个接口类型,他是方法的集合。对于接口I,S是其合法实现,因为结构S定义了I所需的两个方法。
往下,函数f()的参数为接口类型。p能够实现I,则有方法Get()和Put()。函数的功能是 打印字段i的值,和将i至1.
main()函数中,因为S是I的合法实现,定义S类型的s,并将指针传入函数f()。
空接口
每个类型都能匹配空接口:interface{}.我们可以定义一个空接口作为参数的函数:
func g(something interface{}) int {
return something.(I).Get()
}
这个函数中参数为interface{}空接口,能接受任何类型。.(I)是类型断言,用于转换something到I类型的接口。如果有这个类型,则可以调用Get()。
例如:
s=new(S)
fmt.Println(g(s))
这个是成功的。创建S类型满足I,可以调用Get()。再看下面这个:
i := 6
fmt.Println(g(i))
这能编译通过,但运行会出错,因为内建类型int没有Get()方法。他不能实现I。
这种问题解决办法:
package main
import "fmt"
type S struct {
i int
}
func (p *S) Get() int {
return p.i
}
func (p *S) Put(v int){
p.i = v
}
type I interface{
Get() int
Put(int)
}
func f(p I){
fmt.Println(p.Get())
p.Put(1)
}
func g(something interface{}){
if t,ok := something.(I); ok{
fmt.Println("I:",t.Get())
}else if t,ok := something.(int); ok{
fmt.Println("int:",t)
}else{
fmt.Println("not found:",something)
}
}
func h(something interface{}){
switch t:=something.(type){
case I:
fmt.Println("I:",t.Get())
case int:
fmt.Println("int:",t)
case *S:
fmt.Println("S:",t.Get())
default:
fmt.Println("not found:",something)
}
}
func main(){
var s S
f(&s)
fmt.Println(s.Get())
g(&s)
h(&s)
i := 6
g(i)
h(i)
}
与上面相比添加了函数g()h(),与前面不同,这个没有返回值,我修改了一下把fmt.Println写到函数里面了。
g()函数里的switch语句。变量t保存了something的类型,在switch之外使用(type)是非法的。
这里还发现一个问题:
在type switch里不能使用fallthrough,使用时报错:.\9.go:33: cannot fallthrough in type switch
接口类型的方法
接口定义为一个方法的集合。方法包含实际的代码。换句话说,一个接口就是定义,而方法就是实现。
因此,接收者不能定义为接口类型,这样做的话会引起invalid receiver type ... 的编译器错误。
接收者类型必须是T或*T,这里的T是类型名。T叫做接收者基础类型或简称基础类型。基础类型一定不能使指针或接口类型,并且定义在与方法相同的包中。
接收者指 receiver
接口指针
在Go 中创建指向接口的指针是无意义的。实际上创建接口值的指针也是非法的。
var buf bytes.Buffer
io.Copy(buf,os.Stdin)
就会复制标准输入到buf的副本,而不是buf本身。这看起来永远不会是一个期望的结果。