go接口与反射

作者: MrKai平凡之路 | 来源:发表于2015-05-26 10:34 被阅读780次

    go语言的interface是个很松散的概念,类型不必明确声明实现了接口,go语言通过内部维护一个实现此接口方法的table来跟踪。实现一个接口的type也可以实现别的接口,也可以有自己的方法。interface编译优先级比较高。

    惯例

    向其他语言喜欢在接口前加个I 或者后面加个 able,go一般加个(e)r

    定义

    type Namer interface {
        Method1(param_list) return_type
        Method2(param_list) return_type
    }
    

    多态

    go语言可以通过接口实现多态

    package main
    
    import (
        "fmt"
    )
    
    type Shaper interface {
        Area() float64
    //  Length() float32  //必须实现接口中定义的所有方法,才算实现了接口
    }
    
    type Square struct {
        side float64
    }
    type Rectangle struct {
        side   float64
        height float64
    }
    
    func (s *Square) Area() float64 {
        return s.side * s.side
    }
    func (s *Square) Another() float64 {
        return s.side * s.side
    }
    
    func (r *Rectangle) Area() float64 {
        return r.side * r.height / 2
    }
    func main() {
        sql := &Square{5}
        rect := &Rectangle{10, 4}
    
        //接口可以直接引用实现了此接口的类型的方法
    
        //接口声明,方式一
        var areaIntf Shaper
        areaIntf = sql
    
        //接口声明,方式二
        areaIntf1 := Shaper(sql)
    
        //接口声明,方式三
        areaIntf2 := sql
    
        fmt.Println(areaIntf.Area())
        fmt.Println(areaIntf1.Area())
        fmt.Println(areaIntf2.Area())
    
        //多态
        areaIntf3 := Shaper(rect)
        fmt.Println(areaIntf3.Area())
    }
    

    go也可以实现鸭式辩型,类似其他语言的转型

    package main
    
    import (
        "fmt"
    )
    
    type Shaper interface {
        Area() float64
        //  Length() float32  //必须实现接口中定义的所有方法,才算实现了接口
    }
    
    type Square struct {
        side float64
    }
    type Rectangle struct {
        side   float64
        height float64
    }
    
    func (s *Square) Area() float64 {
        return s.side * s.side
    }
    func (s *Square) Another() float64 {
        return s.side * s.side
    }
    
    func (r *Rectangle) Area() float64 {
        return r.side * r.height / 2
    }
    
    type stockPosition struct {
        ticker     string
        sharePrice float32
        count      float32
    }
    
    /* method to determine the value of a stock position */
    func (s stockPosition) getValue() float32 {
        return s.sharePrice * s.count
    }
    
    type car struct {
        make  string
        model string
        price float32
    }
    
    /* method to determine the value of a car */
    func (c car) getValue() float32 {
        return c.price
    }
    
    /* contract that defines different things that have value */
    type valuable interface {
        getValue() float32
    }
    
    /* anything that satisfies the “valuable” interface is accepted */
    func showValue(asset valuable) {
        fmt.Printf("Value of the asset is %f\n", asset.getValue())
    }
    
    func main() {
        sql := &Square{5}
        rect := &Rectangle{10, 4}
    
        //接口可以直接引用实现了此接口的类型的方法
    
        //接口声明,方式一
        var areaIntf Shaper
        areaIntf = sql
    
        //接口声明,方式二
        areaIntf1 := Shaper(sql)
    
        //接口声明,方式三
        areaIntf2 := sql
    
        fmt.Println(areaIntf.Area())
        fmt.Println(areaIntf1.Area())
        fmt.Println(areaIntf2.Area())
    
        //多态
        areaIntf3 := Shaper(rect)
        fmt.Println(areaIntf3.Area())
    
        //鸭式辩型,类似其他语言的转型
    
        var o valuable = stockPosition{"GOOG", 577.20, 4}
        showValue(o)
        o = car{"BMW", "M3", 66500}
        showValue(o)
    }
    
    

    io包实现了以下接口

    type Reader interface {
     Read(p []byte) (n int, err error)
    }
    
    当var r io.Reader 时,可以这样做
    r = os.Stdin
    r = bufio.NewReader(r)
    r = new(bytes.Buffer)
    f, _ := os.Open(“test.txt”)
    r = bufio.NewReader(f)
    
    

    嵌套

    type ReadWrite interface {
     Read(b Buffer) bool
     Write(b Buffer) bool
    }
    type Lock interface {
     Lock()
     Unlock()
    }
    type File interface {
     ReadWrite
     Lock
     Close()
    }
    

    类型断言

    
        //类型断言
    
        if t, ok := areaIntf.(*Square); ok {//必须是*Square 而不是Square
            fmt.Printf("%T",t)//*main.Square
        }
    

    type switch

        //type switch
    
        switch areaIntf.(type) {
        case *Square:
            fmt.Println("square")
        case *Rectangle:
            fmt.Println("Rectangle")
        default:
            fmt.Println("not find")
        }
    

    接口转换规则

    receiver为value时,可以通过值和指针类型调用,receiver位pointer时,只能通过pointer来调用

    type List []int
    
    func (l List) Len() int {
        return len(l)
    }
    
    可以
    lst:=List
    lst.Len()
    lst:=new(List)
    lst.Len()
    
    func (l List) Append(val int) {
        *l = append(*l, val)
    }
    
    只能 
    lst:=new(List)
    lst.Append(2)
    
    

    空接口

    go中的空接口相当于其他语言的Object对象

    反射

    package main
    
    import (
        "fmt"
        "reflect"
    )
    
    func main() {
        var x float64 = 3.14
        fmt.Println("Type:", reflect.TypeOf(x))
        v:=reflect.ValueOf(x)
        fmt.Println("Type:",v.Type())
        fmt.Println("kind:",v.Kind())
        fmt.Println("value:",v.Float())
        fmt.Println(v.Interface())
        fmt.Println(v.Interface().(float64))
        fmt.Println(v.CanSet())
    
        v=reflect.ValueOf(&x)
        fmt.Println(v.CanSet())
        v=v.Elem()
        fmt.Println(v.CanSet())
        v.SetFloat(3.141592)
        fmt.Println(v.Interface())
        fmt.Println(x)
    
    }
    
    

    相关文章

      网友评论

        本文标题:go接口与反射

        本文链接:https://www.haomeiwen.com/subject/lndrqttx.html