Go-Interface

u013344915 · · 1143 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

要点

  • 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)

有疑问加站长微信联系(非本文作者)

本文来自:CSDN博客

感谢作者:u013344915

查看原文:Go-Interface

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1143 次点击  
加入收藏 微博
下一篇:Go学习指南
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传