GO语言接口
2017-11-10 15:29
387 查看
在Go语言中,一个类只需要实现了接口要求的所有函数,我们就说这个类实现了该接口,
例如:
这里我们定义了一个File类,并实现有Read()、Write()、Seek()、Close()等方法。设想我们有如下接口:
尽管File类并没有从这些接口继承,甚至可以不知道这些接口的存在,但是File类实现了这些接口,可以进行赋值:
例如:
type File struct { // ... } func (f *File) Read(buf []byte) (n int, err error) func (f *File) Write(buf []byte) (n int, err error) func (f *File) Seek(off int64, whence int) (pos int64, err error) func (f *File) Close() error
这里我们定义了一个File类,并实现有Read()、Write()、Seek()、Close()等方法。设想我们有如下接口:
type IFile interface { Read(buf []byte) (n int, err error) Write(buf []byte) (n int, err error) Seek(off int64, whence int) (pos int64, err error) Close() error } type IReader interface { Read(buf []byte) (n int, err error) } type IWriter interface { Write(buf []byte) (n int, err error) } type ICloser interface { Close() error }
尽管File类并没有从这些接口继承,甚至可以不知道这些接口的存在,但是File类实现了这些接口,可以进行赋值:
var file1 IFile = new(File) var file2 IReader = new(File) var file3 IWriter = new(File) var file4 ICloser = new(File)
示例:
package main import ( "fmt" "math" ) type Abser interface { Abs() float64 } func main() { var a Abser f := MyFloat(-math.Sqrt2) v := Vertex{3, 4} a = f // a MyFloat 实现了 Abser fmt.Println(a.Abs()) //输出1.4142135623730951 a = &v // a *Vertex 实现了 Abser fmt.Println(a.Abs()) //输出5 // 下面一行,v 是一个 Vertex(而不是 *Vertex) // 所以没有实现 Abser。报错Vertex does not implement Abser (Abs method has pointer receiver) //a = v //fmt.Println(a.Abs()) } type MyFloat float64 func (f MyFloat) Abs() float64 { if f < 0 { return float64(-f) } return float64(f) } type Vertex struct { X, Y float64 } func (v *Vertex) Abs() float64 { return math.Sqrt(v.X*v.X + v.Y*v.Y) }接口查询-----主要功能用来查询一个接口的实现是否同时实现了另一个接口
package main import ( "fmt" "os" ) type Reader interface { Read(b []byte) (n int, err error) } type Writer interface { Write(b []byte) (n int, err error) } //接口组合 type ReadWriter interface { Reader Writer } type IWriter interface { IWrite(b []byte) (n int, err error) } func main() { var w Writer // os.Stdout 实现了 Writer w = os.Stdout fmt.Fprintf(w, 4000 "hello, writer\n") var rw ReadWriter rw = os.Stdout fmt.Fprintf(rw, "hello, writer\n") //接口查询 if _,ok := w.(Reader);ok { fmt.Println("实现了Reader接口") //因为w的实例是os.Stdout它不光实现了Write接口,还实现了Reader接口,所以此处有打印输出 } if _,ok := w.(IWriter);ok { fmt.Println("实现了IWriter接口") //因为w的实例是os.Stdout它未实现了IWriter接口,所以此处无打印输出 } }上边的打印结果为
hello, writer hello, writer 实现了Reader接口
package main import ( "fmt" "os" ) type Reader interface { Read(b []byte) (n int, err error) } func main() { //接口查询 var f float64 = 3.14 var r Reader = os.Stdout queryInterface(1, "a", r, f) } //args ...interface{}表示任意类型的参数 func queryInterface(args ...interface{}) { for _, arg := range args { switch arg.(type) { case int: fmt.Println(arg, "现在的类型是int") case string: fmt.Println(arg, "现在的类型是string") case Reader: fmt.Println(arg, "现在的类型是Reader") default: fmt.Println(arg, "现在的类型未知") } } }
重写包里边的接口实现
package main import "fmt" type Person struct { Name string Age int } //重写fmt包中的Stringers接口的String()方法来实现自定义的打印输出 func (p Person) String() string { return fmt.Sprintf("%v (%v years)", p.Name, p.Age) } func main() { a := Person{"Arthur Dent", 42} z := Person{"Zaphod Beeblebrox", 9001} fmt.Println(a, z) //结果为Arthur Dent (42 years) Zaphod Beeblebrox (9001 years) }