Interface類型能夠定義一組方法,可是這些不須要實現。而且interface不能包含任何變量。node
type example interface{ Method1(參數列表) 返回值列表 Method2(參數列表) 返回值列表 … var a example a.Method1() }
interface類型默認是一個指針golang
a. Golang中的接口,不須要顯示的實現。只要一個變量,含有接口類型中的全部方法,那麼這個變量就實現這個接口。所以,golang中沒有implement相似的關鍵字spa
b. 若是一個變量含有了多個interface類型的方法,那麼這個變量就實現了多個接口。指針
c.若是一個變量只含有了1個interface的方部分方法,那麼這個變量沒有實現這個接口。code
一個接口能夠嵌套在另外的接口,以下所示接口
type ReadWrite interface { Read(b Buffer) bool Write(b Buffer) bool } type Lock interface { Lock() Unlock() } type File interface { ReadWrite Lock Close() }
實例:string
package main import "fmt" type Reader interface { Read() } type Writer interface { Write() } type ReadWriter interface { Reader Writer } type File struct { } func (f *File) Read() { fmt.Println("read data") } func (f *File) Write() { fmt.Println("write data") } func Test(rw ReadWriter) { rw.Read() rw.Write() } func main() { var f *File Test(f) var b interface{} b = f v, ok := b.(ReadWriter) fmt.Println(v, ok) }
因爲接口是通常類型,不知道具體類型,若是要轉成具體類型,能夠採用如下方法進行轉換:it
/* var t int var x interface{} x = t y = x.(int) //轉成int var t int var x interface{} x = t y, ok = x.(int) //轉成int,帶檢查 */ package main import "fmt" type Student struct { Name string Sex string } func Test(a interface{}) { b, ok := a.(Student) if ok == false { fmt.Println("convert failed") return } //b += 3 fmt.Println(b) } func main() { var a interface{} var b int a = b c := a.(int) fmt.Printf("%d %T\n",a,a) fmt.Printf("%d %T\n",b,b) fmt.Printf("%d %T\n",c,c) var st Student = Student{ Name: "stu01", Sex: "female", } Test(st) fmt.Printf("%T\n",st) }
類型斷言,採用type switch方式class
空接口Interface{}import
nterface{},接口中一個方法也沒有,因此任何類型都實現了空接口,也就是任何變量均可以賦值給空接口。
var a int var b interface{} b = a
判斷一個變量是否實現了指定接口
type Stringer interface { String() string } var v MyStruct if sv, ok := v.(Stringer); ok { fmt.Printf(「v implements String(): %s\n」, sv.String()); }
實現一個通用的鏈表類
package main import "fmt" type LinkNode struct { data interface{} next *LinkNode } type Link struct { head *LinkNode tail *LinkNode } func (p *Link) InsertHead(data interface{}) { node := &LinkNode{ data: data, next: nil, } if p.tail == nil && p.head == nil { p.tail = node p.head = node return } node.next = p.head p.head = node } func (p *Link) InsertTail(data interface{}) { node := &LinkNode{ data: data, next: nil, } if p.tail == nil && p.head == nil { p.tail = node p.head = node return } p.tail.next = node p.tail = node } func (p *Link) Trans() { q := p.head for q != nil { fmt.Println(q.data) q = q.next } } func main() { var link Link for i := 0; i < 10; i++ { //intLink.InsertHead(i) link.InsertTail(fmt.Sprintf("str %d", i)) } link.Trans() }