• go interface接口


    interface接口

    定义:Interface类型可以定义一组方法,但是这些不需要实现。并且interface不能 包含任何变量。

    type example interface{
            Method1(参数列表) 返回值列表
            Method2(参数列表) 返回值列表
            …
    }
    

    interface类型默认是一个指针

    样例一:

    package main
    
    import "fmt"
    
    type People struct {
    	name string
    	age  int
    }
    
    type Test interface {
    	Print()
    	Sleep()
    }
    
    type Student struct {
    	name  string
    	age   int
    	score int
    }
    
    func (p Student) Print() {
    	fmt.Println("name:", p.name)
    	fmt.Println("age:", p.age)
    	fmt.Println("score:", p.score)
    }
    
    func (p Student) Sleep() {
    	fmt.Println("student sleep")
    }
    
    func (people People) Print() {
    	fmt.Println("name:", people.name)
    	fmt.Println("age:", people.age)
    }
    
    func (p People) Sleep() {
    	fmt.Println("people sleep")
    }
    
    func main() {
    
    	var t Test
    	fmt.Println(t)
    	//t.Print()
    
    	var stu Student = Student{
    		name:  "stu1",
    		age:   20,
    		score: 200,
    	}
    
    	t = stu
    	t.Print()
    	t.Sleep()
    
    	var people People = People{
    		name: "people",
    		age:  100,
    	}
    
    	t = people
    	t.Print()
    	t.Sleep()
    
    	fmt.Println("t:", t)
    }
    

    样例二:

    package main
    
    import "fmt"
    
    type Carer interface {
    	GetName() string
    	Run()
    	DiDi()
    }
    
    type Test interface {
    	Hello()
    }
    
    type BMW struct {
    	Name string
    }
    
    func (p *BMW) GetName() string {
    	return p.Name
    }
    
    func (p *BMW) Run() {
    	fmt.Printf("%s is running
    ", p.Name)
    }
    
    func (p *BMW) DiDi() {
    	fmt.Printf("%s is didi
    ", p.Name)
    }
    
    func (p *BMW) Hello() {
    	fmt.Printf("hello, i'm %s 
    ", p.Name)
    }
    
    type BYD struct {
    	Name string
    }
    
    func (p *BYD) GetName() string {
    	return p.Name
    }
    
    func (p *BYD) Run() {
    	fmt.Printf("%s is running
    ", p.Name)
    }
    
    func (p *BYD) DiDi() {
    	fmt.Printf("%s is didi
    ", p.Name)
    }
    
    func main() {
    	var car Carer
    	var test Test
    
    	fmt.Println(car)
    
    	bmw := &BMW{
    		Name: "BMW",
    	}
    
    	car = bmw
    	car.Run()
    
    	test = bmw
    	test.Hello()
    
    	byd := &BYD{
    		Name: "BYD",
    	}
    
    	car = byd
    	car.Run()
    }
    

    接口实现

    Golang中的接口,不需要显示的实现。只要一个变量,含有接口类型中 的所有方法,那么这个变量就实现这个接口。因此,golang中没有implement 类似的关键字。

    如果一个变量含有了多个interface类型的方法,那么这个变量就实现了多个 接口。

    如果一个变量只含有了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)
    }
    

    判断一个变量是否实现了指定接口

    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 main() {
    	var f *File
    	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 just(items ...interface{}) {
    	for index, v := range items {
    		switch v.(type) {
    		case bool:
    			fmt.Printf("%d params is bool, value is %v
    ", index, v)
    		case int, int64, int32:
    			fmt.Printf("%d params is int, value is %v
    ", index, v)
    		case float32, float64:
    			fmt.Printf("%d params is float, value is %v
    ", index, v)
    		case string:
    			fmt.Printf("%d params is string, value is %v
    ", index, v)
    		case Student:
    			fmt.Printf("%d params student, value is %v
    ", index, v)
    		case *Student:
    			fmt.Printf("%d params *student, value is %v
    ", index, v)
    		}
    	}
    }
    
    func main() {
    	var b Student = Student{
    		Name: "stu01",
    		Sex:  "female",
    	}
    	Test(b)
    	just(28, 8.2, "this is a test", b, &b)
    }
    

    空接口

    空接口没有任何方法,所以所有类型都实现了空接口,也就是任何变量都可以赋值给空接口。

    var a int
    var b interface{}
    b  = a
    

    备注:变量slice和接口slice之间赋值操作,for range

    通用的链表类

    link.go

    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
    	}
    }
    

    main.go

    package main
    
    import "fmt"
    
    func main() {
    
    	var link Link
    	for i := 0; i < 10; i++ {
    		//intLink.InsertHead(i)
    		link.InsertTail(fmt.Sprintf("str %d", i))
    	}
    
    	link.Trans()
    }
    
  • 相关阅读:
    端口以及服务常用cmd
    异步,同步,阻塞,非阻塞,并行,并发,
    mysql启动不起来
    安装nagios出现的错误
    Linux内核优化
    mysql使用常见问题
    mysql日志
    mysql数据库使用脚本实现分库备份过程
    mysqladmin常用用法
    mysql授权
  • 原文地址:https://www.cnblogs.com/shhnwangjian/p/7453715.html
Copyright © 2020-2023  润新知