什么是接口? 简单的说,interface是一组method签名的组合,我们通过interface来定义对象的一组行为。interface类型定义了一组方法,如果某个对象实现了某个接口的所有方法,则此对象就实现了此接口 。
Go中的接口为指定对象的行为提供了一种方式:如果事情可以这样做,那么它就可以在这里使用。我们已经看到一些简单的例子:自定义的打印可以通过String() 方法来实现,而Fprintf 可以通过Write 方法输出到任意的地方。只有一个或两个方法的接口在Go代码中很常见,并且它的名字通常来自这个方法,例如实现Write 的io.Writer 。
如果某个对象实现了String()方法,那么它就具有Stringer标准,即能通过fmt包的打印函数按照自定义的格式打印输出。print.go 下的Stringer接口为:
type Stringer interface {
String() string
}
下面给出一个实现的例子:
package main
import (
"fmt"
"strconv"
)
type Student struct {
name string
number int
}
type Teacher struct {
name string
subject string
}
func (self Student)String() string{
return "[name=" + self.name + ",number=" + strconv.Itoa(self.number) + "]"
}
func (self Teacher)String() string {
return "[name=" + self.name + ",subject=" + self.subject + "]"
}
func main() {
student := Student{name:"zhujoe",number:216}
teacher := Teacher{name:"LLL",subject:"Math"}
fmt.Println("studeng:",student)
fmt.Println("teacher:",teacher)
fmt.Println("studeng:",fmt.Sprint(student))
fmt.Println("teacher:",fmt.Sprint(teacher))
}
程序的运行结果为:
studeng: [name=zhujoe,number=216]
teacher: [name=LLL,subject=Math]
studeng: [name=zhujoe,number=216]
teacher: [name=LLL,subject=Math]
上面就是实现String()方法的例子。同样的,对于Reader接口,只要实现了Read()方法,就具有了Reader标准。在go的io包中有这么一个函数ReadFull(),只要某个对象实现了Read()方法,就可以被ReadFull()读取。ReadFull()可以读取任何对象的数据,只要这个对象符合Reader标准(即实现了Read()方法),例如文件、数据库中的数据、网络中的数据、内存、磁盘的扇区等等。
下面给出实现Read()方法的例子:
type Ustr string
func (s Ustr) Read(p []byte)(n int,err error) {
i,ls,lp := 0,len(s),len(p)
for ;i < ls && i < lp;i++{
if s[i]>=‘a‘ && s[i]<=‘z‘{
p[i] = s[i] + ‘A‘ - ‘a‘
}else {
p[i] = s[i]
}
}
switch i {
case lp:
return i,nil
case ls:
return i,io.EOF
default:
return i,errors.New("Read Fail")
}
}
然后就可以这样使用
us := Ustr("Hello World")
buf := make([]byte,1024)
n,err := io.ReadFull(us,buf)
fmt.Println(string(buf))
//fmt.Printf("%s\n",buf)
fmt.Println(n,err)
bytes.NewBuffer 实现了很多基本的接口,可以同步bytes包来学习接口的实现。另外,interface可以被任何对象实现,一个对象可以实现任意多个interface。