Go接口有哪些例子?

时间:2009-11-14 16:07:21

标签: go

我找到了关于Go的an interesting blog post

我试图理解接口的概念,但我发现很难从博客文章中的代码片段这样做,而the language specification几乎不可能。

任何人都可以在工作程序中指出一个简单的Go接口示例吗?

6 个答案:

答案 0 :(得分:4)

这是一项正在进行中的学习练习,当然也是一个很好的风格的例子,但是here you gospec)。

此外,作为一个更具异国情调的例子,我在go-nuts邮件列表上提出a post关于使用接口{}来构建使用匿名数据的函数(在这种情况下,是“三元操作”函数) :

package main
import "fmt";
func Tern(exp bool, a interface{}, b interface{}) (interface{}) {
    if exp { return a }
    return b
}
func main() {
    a := 7; b := 1;
    result := Tern(a > b, a, b);
    fmt.Printf("%d\n", result);
}

答案 1 :(得分:3)

教程“Interfaces in Go - Part 2: Aiding adaptable, evolutionary design ”(2012年1月,来自Sathish VJ)清楚地提到了Go中接口的主要优势:

  

Go的接口不是Java或C#接口的变种,它们更多   它们是大规模编程和适应性,进化设计的关键

请参阅同一篇文章中关于总线的不同视角(界面)的示例:

package main

import "fmt"

//Go Step 1: Define your data structures
type Bus struct {
    l, b, h int
    rows, seatsPerRow int
}

//Go Step 2: Define a real world abstraction that could use the data we structure we have
type Cuboider interface {
    CubicVolume() int
}

//Go Step 3: Implement methods to work on data
func (bus Bus) CubicVolume() int {
    return bus.l *  bus.b * bus.h
}

//Go step - repeat 2 & 3 for any other interfaces
type PublicTransporter interface  {
    PassengerCapacity() int
}

func (bus Bus) PassengerCapacity() int {
    return bus.rows * bus.seatsPerRow
}

func main() {
    b := Bus{
             l:10, b:6, h:3,
             rows:10, seatsPerRow:5}

    fmt.Println("Cubic volume of bus:", b.CubicVolume())
    fmt.Println("Maximum number of passengers:", b.PassengerCapacity())
}
  

它似乎以数据为中心 - 首先定义您的数据并在您进行时构建您的界面抽象   这里的层次结构是一种“沿途”而没有明确说明它 - 根据与该类型相关的方法签名,它被理解为实现特定的接口。

     

现在让我们假设随着时间的推移,我们公交车的一些项目要求发生了变化 - 现在有一条新法律规定每位乘客至少应该有一定的最小立方体积量。
  我们的总线现在必须遵守一个名为PersonalSpaceLaw的新接口,它与已经实现的任何其他接口不同

//new requirement that the Bus must be compatible with
type PersonalSpaceLaw interface {
    IsCompliantWithLaw() bool
}

func (b Bus) IsCompliantWithLaw() bool {
    return (b.l * b.b * b.h) / (b.rows * b.seatsPerRow) >= 3
}
  

该功能已扩展,不会对核心类或核心层次结构进行任何更改。这种实现更加清晰,易于扩展,并且可以根据项目要求的不断变化的需求进行更好的扩展。

以下是 full working program in Go Playground

文章以John Asmuth关于Go中接口生产力的帖子结束:

  

“事实上,我不必花时间设计某种类型的层次结构,然后在我完成之前将其重新排列两到三次。
  它甚至不是很容易做到的事实 -
  这是事实,我不必担心它,可以继续使用实际的算法。

答案 2 :(得分:2)

package main

type Stringer interface {
    String() string
}

type pie int
type pizza string

func (p pie) String() string{
    return "pie"
}

func (p pizza) String() string{
    return "pizza"
}

func main(){
    var a pie
    var b pizza
    fmt.Println(a,b) //fmt.Println() will look for Stringers and call their String() method.
}

答案 3 :(得分:1)

扩展@Jessta很好的例子。给出了在工作程序中使用Go's接口访问Go's标准库的简单示例。

package main

import (
    "encoding/json"
    . "fmt"
)

func main() {
    var i interface{} = c

    e := func() error { return c } // type error interface { Error() string}
    Println(e())                   // Hiss

    s := func() Stringer { return d } // type Stringer interface {String() string}

    // func Println(a ...interface{}) (n int, err error)
    Println(s()) // Woof

    d := `{"Pet":"Dog","Age":2, "Eat": "Bone"}`
    json.Unmarshal([]byte(d), &i) // func Unmarshal(data []byte, v interface{}) error
    m := i.(map[string]interface{})
    Println(m["Age"]) // 2
}

type cat string
type dog string
var c cat
var d dog
func (cat) Error() string { return "Hiss" }
func (dog) String() string { return "Woof" }

接口是Go最具特色和功能的功能。它们对图书馆设计有深远的影响。它们支持真正的组件体系结构。主要示例是io.Reader和io.Writer,它们是Unix管道概念的概括。参见https://talks.golang.org/2015/simplicity-is-complicated.slide

按照惯例,错误具有类型错误,这是一个简单的内置接口。请参阅https://golang.org/doc/effective_go.html#errorshttps://talks.golang.org/2012/splash.article。错误变量表示可以描述为字符串的任何值。 func() error { return c }呼叫type error interface { Error() string}func (cat) Error() string实现type error interface { Error() string}。参见https://blog.golang.org/error-handling-and-go

Stringer可以很好地打印自己。任何实现String的都是Stringer。如果参数是Stringer,则fmt.Println将调用String方法。参见https://talks.golang.org/2013/go4python.slide#33func() Stringer { return d }呼叫type Stringer interface {String() string}func (dog) String() string实现type Stringer interface {String() string}

fmt.Println的签名是func Println(format string, a ...interface{}) (n int, err error),也就是说,其参数(在格式字符串之后)是接口值。参见https://blog.golang.org/constants。编辑引号以匹配示例。

标准库中关键接口的广泛使用使将API链接在一起变得容易。参见https://talks.golang.org/2012/goforc.slide#46。有关更多示例,请参见https://talks.golang.org/2014/go4gophershttps://talks.golang.org/2014/go4gophers.slide#1

答案 4 :(得分:0)

Go中接口的基本概念是,实现定义接口的方法的任何对象都可以是该接口的一部分。

最好的例子是Writer界面。 Rob Pike在Google Tech Talk(http://www.youtube.com/watch?v=rKnDgT73v8s)的介绍演讲中就是一个例子 - 在演讲中滚动到33:25进行解释。

答案 5 :(得分:0)

维基百科解释了鸭子打字并在Go中有一个例子。 http://en.wikipedia.org/wiki/Duck_typing