在Go中使用接口

时间:2011-08-12 15:41:53

标签: interface go

我想了解接口类型,并在Go(语言)中使用简单示例。

我阅读了网络文档,但我没理解。

4 个答案:

答案 0 :(得分:39)

go接口背后的想法是duck typing。这简单地转化为:如果你看起来像鸭子和庸医像鸭子那么你就是一只鸭子。这意味着如果你的对象实现了所有duck的功能,那么使用它作为鸭子应该没有问题。这是一个例子:

package main

import (
    "fmt"
)

type Walker interface {
    Walk() string
}

type Human string
type Dog string

func (human Human) Walk() string { //A human is a walker
    return "I'm a man and I walked!"
}

func (dog Dog) Walk() string { //A dog is a walker
    return "I'm a dog and I walked!"
}

//Make a walker walk
func MakeWalk(w Walker) {
    fmt.Println(w.Walk())
}

func main() {
    var human Human
    var dog Dog
    MakeWalk(human)
    MakeWalk(dog)
}

此处HumanWalkerDogWalker。为什么?因为他们俩......嗯...... Walk。它们都实现了Walk () string功能。所以这就是你可以对它们执行MakeWalk的原因。

当您希望不同类型以相同方式运行时,这非常有用。一个实际的例子是文件类型对象(套接字,文件对象) - 你需要一个Write和Read函数。然后你可以使用与其类型无关的相同方式使用Write和Read - 这很酷。

答案 1 :(得分:1)

另一个显示界面和结构之间相互作用的工作示例

package main

import "fmt"

type Info interface {
Noofchar() int
Increment()
}

type Testinfo struct {
noofchar int     
}

func (x *Testinfo) Noofchar() int {
return x.noofchar
}
func (x *Testinfo) Increment() {
x.noofchar++
}

func main(){
var t Info = &Testinfo{noofchar:1}
fmt.Println("No of char ",t.Noofchar())
t.Increment()
fmt.Println("No of char ",t.Noofchar())
}

答案 2 :(得分:0)

要在此处添加@AlexPlugaru和https://stackoverflow.com/a/18854285/12817546上的@ NickCraig-Wood的出色答案。

package main

import . "fmt"

func main() {
    cat("Bird").Eat()      // Bird
    eater.Eat(cat("Milk")) // Milk
    Break(cat("Fish"))     // Fish
    Lunch().Eat()          // Mice
    Tea(true)           // Bird
}

type cat string
type eater interface{ Eat() }

func (c cat) Eat()  { Println(c) }
func Break(e eater) { e.Eat() }
func Lunch() eater  { return cat("Mice") }
func Tea(b bool) {
    if b {
        cat("Bird").Eat()
    }
}

结构或其他任何具体类型上的方法都是静态解析的。请参阅cat("Bird").Eat()eater.Eat(cat("Milk"))。动态分配方法的唯一方法是通过接口。参见Break(cat("Fish"))Lunch().Eat()http://www.golangbr.org/doc/faq#How_do_I_get_dynamic_dispatch_of_methods

Tea(true)动态调用方法,而无需使用接口。参见https://talks.golang.org/2014/taste.slide#19。但是接口(根据设计和约定)鼓励我们编写可组合的代码。参见https://talks.golang.org/2014/go4gophers.slide#21

结果:通过小接口连接的简单零件。参见https://talks.golang.org/2012/chat.slide#5。拥有许多小的简单事物比拥有一件大的复杂事物更好。参见https://talks.golang.org/2014/go4gophers.slide#24

您还可以将任何内容隐藏在私有包中,仅公开特定的类型,接口和工厂功能。参见Break(cat("Fish"))Lunch().Eat()https://code.tutsplus.com/tutorials/lets-go-object-oriented-programming-in-golang--cms-26540

答案 3 :(得分:0)

在此示例中,我使用该界面演示如何在Golang中实现多态。

package main 


import(
    "fmt"
    "math"
)

func main(){
    rect := Rectangle{20,50}
    cir := Circle{2}

    //According to object you passed in getArea method, 
    // it will change the behaviour and that is called Polymorphism.
    fmt.Println("Area of Rectangle =",getArea(rect))
    fmt.Println("Area of Circle =",getArea(cir))

}

//Interface Shape with one area method
type Shape interface{
     area() float64
}

//Creating Rectangle and Circle type using struct 
type Rectangle struct{
    height float64
    width float64
}

type Circle struct{
    radius float64
}

//Receiver function, which implements struct's area methods
func(r Rectangle) area() float64{
    return r.height * r.width
}

func(c Circle) area() float64{
    return math.Pi * math.Pow(c.radius,2)
}

//passing interface as arguments, which can calculate shape of any mentioned type
//All the struct are tied together because of the Interface.
func getArea(shape Shape) float64{
    return shape.area()
}