Go-Interface

要点

  • interface关键字用来定义一个接口
  • Go没有implements、extends等关键字
  • 实现一个接口的方法就是直接定义接口中的方法
  • 要实现多态,就要用指针或&object语法

示例

package main
import "fmt"
import "math"

type Shape interface {
    area() float64 
}

type Circle struct {
    r float64 
}

func (c *Circle) area() float64 {
    return math.Pi * c.r * c.r
}

type Rectangle struct {
    length, width float64 
}

func (r *Rectangle) area() float64 {
    return r.length * r.width;
}

func totalArea(shapes ... Shape) (total float64) {
    total = 0 
    for _, shape := range shapes {
        total += shape.area()
    }

    return 
}

func main() {
    circle := Circle{r:5}
    ractangle := Rectangle{3, 4}

    /*.\helloworld.go:40: cannot use circle (type Circle) as type Shape in argument to totalArea:
        Circle does not implement Shape (area method has pointer receiver)
    fmt.Println(totalArea(circle, ractangle)) // L40  */

    fmt.Println(totalArea(&circle, &ractangle))
}

再论传值与传引用

在上面的代码中,注意到totalArea()声明的类型是Shape,但在后面调用的时候传入的是&cirlce这种。因此,冒出来一个疑问:为什么一个是“对象”,一个是地址(指针),却能够运行呢?

曾经考虑过是否Go和Java一样,存在基本类型和对象(用户自定义等)传值、传引用的区别。。。为此,有下面一系列的验证。

基本类型

package main
import "fmt"

func foo(i int) {
    fmt.Println(i)
}

func main() {
    i := 5 
    foo(i)

    /* cannot use &i (type *int) as type int in argument to foo
    foo(&i)*/
}

结构体类型

package main
import "fmt"

type Data struct {
    x int
}

func (data* Data) debug() {
    fmt.Println(data.x)
}

func foo(data Data) {
    data.x++
}

func bar(data *Data) {
    data.x++
}

func main() {
    data := Data{1}
    data.debug()

    // cannot use &data (type *Data) as type Data in argument to foo
    //foo(&data)

    foo(data)
    data.debug()
}

特殊的interface

package main
import "fmt"

type Debugger interface {
    debug()
}

type Data struct {
    x int
}

func (data* Data) debug() {
    fmt.Println(data.x)
}

func foo(debugger Debugger) {
    debugger.debug()
}

func bar(debugger *Debugger) {
    //debugger.debug undefined (type *Debugger is pointer to interface, not interface)
    //debugger.debug()

    (*debugger).debug()

    //syntax error: unexpected >, expecting expression
    //debugger->debug()
}

func main() {
    data := Data{1}
    data.debug()

    /*cannot use data (type Data) as type Debugger in argument to foo:
      Data does not implement Debugger (debug method has pointer receiver)*/
    //foo(data)

    foo(&data)

    /*cannot use &data (type *Data) as type *Debugger in argument to bar:
        *Debugger is pointer to interface, not interface*/
    //bar(&data)

    /*cannot use data (type Data) as type *Debugger in argument to bar:
        *Debugger is pointer to interface, not interface*/
    //bar(data)
}

约定俗成(???)

假定接口为:

type I interface {...}

实现该接口的类为:

type Concreate struct {...}

仅依赖于接口的函数:

func foo(i I) {...}

调用约定:

concreate := Concreate {...}
foo(&concreate)
发布了384 篇原创文章 · 获赞 44 · 访问量 56万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览