Go中接口的使用

发布于 2024-11-29 10:35:07 字数 70 浏览 2 评论 0原文

我想通过一个在 Go(语言)中使用的简单示例来了解接口类型。

我阅读了网络文档,但我不明白。

I would like to understand the interface type with a simple example of it's use in Go (Language).

I read the web documentation, but I don't get it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

[浮城] 2024-12-06 10:35:07

Go 接口背后的想法是鸭子打字。简单来说就是:如果你看起来像鸭子,嘎嘎叫起来也像鸭子,那么你就是鸭子。这意味着如果您的对象实现了鸭子的所有功能,那么将其用作鸭子应该没有问题。这是一个例子:

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

这里一个Human是一个Walker,一个Dog是一个Walker。为什么?因为他们都......好吧......步行。它们都实现了 Walk() string 函数。这就是为什么你可以对它们执行MakeWalk

当您希望不同类型的行为方式相同时,这非常有用。一个实际的例子是文件类型对象(套接字、文件对象) - 您需要对所有这些对象进行写入和读取函数。然后,您可以以相同的方式使用 Write 和 Read,而不管它们的类型如何 - 这很酷。

The idea behind go interfaces is duck typing. Which simply translates into: If you look like a duck and quack like a duck then you are a duck. Meaning that if your object implements all duck's features then there should be no problem using it as a duck. Here is an example:

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

Here a Human is a Walker and a Dog is a Walker. Why? Because they both.. well... Walk. They both implement the Walk () string function. So this is why you can execute MakeWalk on them.

This is very helpful when you want different types to behave in the same manner. A practical example would be file type objects (sockets, file objects) - you need a Write and a Read function on all of them. Then you can use Write and Read in the same fashion independent of their type - which is cool.

上课铃就是安魂曲 2024-12-06 10:35:07

另一个展示接口和结构之间交互的工作示例

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())
}

Another working example showing the interaction between an interface and a structure

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())
}
南风起 2024-12-06 10:35:07

在此示例中,我使用该接口来演示如何在 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()
}

In this example, I'm using the interface to demonstrate how to achieve polymorphism in 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()
}
下雨或天晴 2024-12-06 10:35:07

添加到 @AlexPlugaru 和 @NickCraig-Wood 的优秀答案 https://stackoverflow.com/a/18854285/12817546

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-orient-programming-in-golang--cms-26540

To add to the excellent answer by @AlexPlugaru here and by @NickCraig-Wood at https://stackoverflow.com/a/18854285/12817546.

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()
    }
}

Methods on a struct or any other concrete type are resolved statically. See cat("Bird").Eat() and eater.Eat(cat("Milk")). The only way to have dynamically dispatched methods is through an interface. See Break(cat("Fish")) and Lunch().Eat(), http://www.golangbr.org/doc/faq#How_do_I_get_dynamic_dispatch_of_methods.

Tea(true) calls a method dynamically without using an interface. See https://talks.golang.org/2014/taste.slide#19. But interfaces—by design and convention—encourage us to write composable code. See https://talks.golang.org/2014/go4gophers.slide#21.

The result: simple pieces connected by small interfaces. See https://talks.golang.org/2012/chat.slide#5. Better to have many small simple things than one big complex thing. See https://talks.golang.org/2014/go4gophers.slide#24.

You can also hide anything in a private package and just expose specific types, interfaces, and factory functions. See Break(cat("Fish")) and Lunch().Eat(), https://code.tutsplus.com/tutorials/lets-go-object-oriented-programming-in-golang--cms-26540

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文