接口
接口定义
Interface类型可以定义一组方法,但是这些不需要实现。并且interface不能包含任何变量。
type example interface{
Method1(参数列表) 返回值列表
Method2(参数列表) 返回值列表
…
var a example
a.Method1()
}
interface类型默认是一个指针
接口实现:
a. Golang中的接口,不需要显示的实现。只要一个变量,含有接口类型中的所有方法,那么这个变量就实现这个接口。因此,golang中没有implement类似的关键字
b. 如果一个变量含有了多个interface类型的方法,那么这个变量就实现了多个接口。
c.如果一个变量只含有了1个interface的方部分方法,那么这个变量没有实现这个接口。
接口嵌套
一个接口可以嵌套在另外的接口,如下所示
type ReadWrite interface {
Read(b Buffer) bool
Write(b Buffer) bool
}
type Lock interface {
Lock()
Unlock()
}
type File interface {
ReadWrite
Lock
Close()
}
实例:
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)
}
类型断言
由于接口是一般类型,不知道具体类型,如果要转成具体类型,可以采用以下方法进行转换:
/*
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方式
空接口Interface{}
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()
}