interface类型定义了一组方法,如果某个对象实现了某个接口的所有方法,则此对象就实现了此接口。
如果我们定义了一个interface的变量,那么这个变量里面可以存实现这个interface的任意类型的对象。
package main
import (
"fmt"
)
//定义一个USB接口
type USB interface {
say()
}
//定义SD类型
type Sd struct {
name string
}
//SD类型内定义say方法,即实现了USB接口
func (s Sd) say() {
fmt.Println("这是", s.name)
}
//定义MP3类型
type Mp3 struct {
name string
}
//同样MP3类型内定义say方法,即实现了USB接口
func (m Mp3) say() {
fmt.Println("这是", m.name)
}
func who(u USB) {
u.say()
}
func main() {
//新建USB类型变量
var i USB
//可存放MP3类型数据
i = Mp3{"mp3"}
//调用MP3类型方法
i.say()
//也可存放SD类型数据
i = Sd{"SD"}
//调用SD类型方法
i.say()
}
空接口interface{},由于interface{}未实现任何方法,代表任意类型都实现了interface{},即interface{}可存放任意类型的数据。
有一点要注意,任意类型可赋值给interface{},interface{}类型数据不能直接赋值给任何其它类型,要做类型转换,类似于C中的void*
package main
import (
"fmt"
"reflect"
)
func main() {
var general interface{}
general = 2
v := reflect.ValueOf(general)
fmt.Println("type:", v.Type())
switch general.(type) {
case int:
fmt.Println(general)
case string:
fmt.Println(general)
}
}
GO标准库中interface接口应用,在标准库io包中定义了Writer接口,所有实现了Write方法的类型,我们都说它实现了io.Writer接口。
type Writer interface {
Write(p []byte) (n int, err error)
}
我们在使用fmt包的时候是使用Println/Printf/Print方法。其实,在fmt包中还有Fprint序列方法,而且,Print序列方法内部调用的是Fprint序列方法。以Fprintln为例看看方法的定义:
func Fprintln(w io.Writer, a ...interface{}) (n int, err error)
方法的第一个参数是io.Writer,也就是说,任何实现了io.Writer接口的类型实例都可以传递进来;我们再看看Println方法内部实现:
func Println(a ...interface{}) (n int, err error) {
return Fprintln(os.Stdout, a...)
}
我们不妨追溯一下os.Stdout,也就是标准输出。
Stdout = NewFile(uintptr(syscall.Stdout), "/dev/stdout")
从这里可以看出,os.File也实现了io.Writer,那么,如果第一个参数传递的是一个普通文件,内容便会被输出到该文件。
如果第一个参数传递的是bytes.Buffer,那么,内容便输出到了buffer中。
在写Web程序时,比如:
func Index(rw http.ResponseWriter, req *http.Request) {
fmt.Fprintln(rw, "Hello, World")
}
这样便把Hello World输出给了客户端。
http://blog.studygolang.com/2013/02/%e4%bb%a5io-writer%e4%b8%ba%e4%be%8b%e7%9c%8bgo%e4%b8%ad%e7%9a%84interface/
https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/02.6.md