繁体   English   中英

关于Go中接口和指针接收器的问题

[英]Question about interfaces and pointer receiver in Go

我大家,

我想知道接口和指针接收器之间的显着差异,因为两者都做同样的事情。

你能告诉我这两个代码片段有什么区别吗:

type Person struct {
    Name string
    Age  int
}

func (p *Person) IncreaseAge(age int) *Person {
    p.Age = age
    return p
}

player1 := &Person{Age: 25,}
player1.IncreaseAge(55)

而这个有接口

type Increaser interface { IncreaseAge(age int) Person }

type Person struct {
    Name string
    Age  int
}

func (p *Person) IncreaseAge(age int) *Person {
    p.Age = age
    return p
}
var player2 Increaser
player2 = &Person {Age: 25,}
player2.IncreaseAge(55)

在这种情况下,我不明白接口的好处。 非常感谢你的帮助

仅当有多种不同类型具有某些共同行为(明确定义为一组 function 签名)但该行为的不同实现并且您希望将这些不同类型作为参数传递到可以基于此的单个 function 时,接口才有意义接口定义的通用行为(可能还有一些外部输入)不管传递给它的具体类型是什么(只要该类型实现给定接口)都会做一些事情。

假设您想将类型Dog和方法Introduce()添加到将返回介绍消息的PersonDog Person方法的情况下, Introduce()应该返回带有该特定人的姓名和年龄的介绍,在Dog的情况下,只是bark bark ,因为狗不会说人类的语言。 现在在代码中的某个地方,您希望拥有单个 function SayHi(x) ,无论xPerson还是Dog打印Introduce()的 output (他们都有那个“行为”)。 那将是有效的接口用例:

package main

import "fmt"

type Person struct {
    Name string
    Age  int
}

type Dog struct {
    Name string
    Age  int
}

func (p Person) Introduce() string {
    return fmt.Sprintf("I'm a person named %s and %d years old", p.Name, p.Age)
}

func (d Dog) Introduce() string {
    // Dogs cannot talk to human so they just bark to introduce themselves
    return fmt.Sprintf("bark bark!")
}

type Introducer interface {
    Introduce() string
}

func SayHi(i Introducer) {
    fmt.Println(i.Introduce())
}

func main() {
    p := Person{"Timmy", 7}
    d := Dog{"Lassie", 5}

    // Here you can use SayHi no matter if it is Person or Dog...
    SayHi(p)
    SayHi(d)
}

游乐场: https://play.golang.org/p/wjHgPu7Esvr

接口的一个很好的例子是标准库中的io.Reader 它描述了能够读取字节的行为(具有方法Read(p []byte) (int, error) )。 该接口有许多不同的实现,可以从文件、网络连接、存档、密码等中读取。由于io.Reader的存在,您可以编写一个 function,它不关心字节来自哪里。

如果您不需要这样做,显然您不需要创建界面。 过度使用不需要的接口会导致代码混乱。 理想情况下,如果您发现自己处于 position 中,则最好从没有它们的情况下开始,在那里您发现共同点或需要多种类型的共同行为,重构代码并创建接口。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM