go学习笔记接口

定义

接口定义一个或多个方法签名的集合,任何类型的方法集中只要拥有与之对应的全部方法就表示它’实现’了该接口,无须在该类型上显示添加接口声明
所谓接口对应方法,是指有相同名称,参数列表以及返回值。
接口命名习惯以er结尾,结构体
接口只有方法签名,没有实现
接口没有数据字段
可在接口中嵌入其他接口
类型可实现多个接口
package main

import "fmt"

type Stringer interface {
    String() string         //定义了一个接口
}

type Printer interface {
    Stringer                //嵌套接口
    Print()
}

type User struct {
    id      int
    name    string
}

func (self *User) String() string {
    return fmt.Sprintf("user %d, %s", self.id, self.name)
}

func (self *User) Print() {
    fmt.Println(self.String())
}

func main() {
    var t Printer = &User{1, "Tom"}
    t.Print()       //user 1, Tom
}
空接口interface{}没有任何方法签名,也就意味着任何类型都实现了空接口。
package main

import "fmt"

func Print(v interface{}) {
    fmt.Printf("%T,%v\n", v, v)
}

func main() {
    Print(1)                    //int,1
    Print("Hello, world!")      //string,Hello, world!
}
匿名接口可用作变量类型或结构成员
package main

import "fmt"

type Tester struct {
    s interface {
        String() string
    }
}

type User struct {
    id      int
    name    string
}

func (self *User) String() string {
    return fmt.Sprintf("User %d, %s", self.id, self.name)
}

func main() {
    t := Tester{&User{1, "Tom"}}
    fmt.Println(t.s.String())
}
数据指针持有的是目标对象的只读复制品,赋值完整对象或指针
package main

import "fmt"

type User struct {
    id      int
    name    string
}

func main() {
    u := User{1, "Tom"}
    var i interface{} = u

    u.id = 2
    u.name = "jack"

    fmt.Printf("%v\n", u)           //{2 jack}
    fmt.Printf("%v\n", i.(User))    //{1 Tom}
}
接口转型返回临时对象,只有使用指针才能修改其状态
package main

import "fmt"

type User struct {
    id      int
    name    string
}

func main() {
    u := User{1, "Tom"}
    var vi,pi interface{} = u, &u

    //vi.(User).name = "jim"    //报错,不能这样修改值
    pi.(*User).name = "Jack"


    fmt.Printf("%v\n", vi.(User))     //{1 Tom}
    fmt.Printf("%v\n", pi.(*User))    //&{1 Jack}
}
利用类型推断,可判断接口对象是否某个具体的接口或类型
package main

import "fmt"

type User struct {
    id      int
    name    string
}

func (self *User) String() string {
    return fmt.Sprintf("%d, %s", self.id, self.name)
}

func main() {
    var o interface{} = &User{1, "Tom"}

    if i,ok := o.(fmt.Stringer); ok {
        fmt.Println(i)      //1, Tom
    }


    u := o.(*User)
    //u := o.(User)         //报错
    fmt.Println(u)          //1, Tom
}
类型判断
package main

import "fmt"

type User struct {
    id      int
    name    string
}


func main() {
    var o interface{} = &User{1, "Tom"}

    switch v := o.(type) {
    case nil :                  //nil类型
        fmt.Println("nil")
    case fmt.Stringer:          //interface
        fmt.Println(v)
    case func() string:         //func
        fmt.Println(v())
    case *User:
        fmt.Printf("%d, %s\n", v.id, v.name)
    default:
        fmt.Println("unknow")
    }
}
坚持原创技术分享,您的支持将鼓励我继续创作!