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)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值