为什么在Golang中需要接口?
在Golang中,我们将结构体与接收器方法结合使用。到这里为止一切都很完美。
我不确定什么是接口。我们在结构中定义方法,如果要在结构上实现方法,则无论如何都要在另一个结构下再次编写该方法。
这意味着接口似乎只是方法定义,仅占用了页面上多余的空间。
有没有解释我为什么需要接口的示例?
回答:
接口太大了,不能在这里给出全面的答案,但是有些事情需要弄清楚它们的用途。
接口是一种 工具
。是否使用它们取决于您自己,但是它们可以使代码更清晰,更短,更易读,并且它们可以在程序包,客户端(用户)和服务器(提供者)之间提供良好的API。
是的,您可以创建自己的struct
类型,并且可以“附加”方法,例如:
type Cat struct{}func (c Cat) Say() string { return "meow" }
type Dog struct{}
func (d Dog) Say() string { return "woof" }
func main() {
c := Cat{}
fmt.Println("Cat says:", c.Say())
d := Dog{}
fmt.Println("Dog says:", d.Say())
}
我们已经在上面的代码中看到了一些重复:在使两者Cat
同时Dog
说话时。我们可以像 对待动物
一样对待两者吗?并不是的。当然,我们可以将两者都作为处理interface{}
,但是如果这样做,则不能调用它们的Say()
方法,因为type的值interface{}
未定义任何方法。
上面的两种类型都有一些 相似之处 :两者都具有Say()
签名相同的方法(参数和结果类型)。我们可以通过一个接口 捕获 它:
type Sayer interface { Say() string
}
接口仅包含方法的 签名 ,而不包含方法的 实现 。
请注意,在Go语言中,如果类型的方法集是该接口的超集,则该类型 隐式
实现该接口。没有意图的声明。这是什么意思?我们以前Cat
和Dog
类型已经实现了这个Sayer
接口,即使在我们前面写了他们这个接口定义根本不存在,而我们没有接触他们,以纪念他们什么。他们只是做。
接口指定行为 。实现接口的类型意味着该类型具有接口“规定”的所有方法。
由于两者都实现了Sayer
,我们可以将两者都当作的值来处理Sayer
,因此它们具有相同的地方。看看我们如何统一处理这两个问题:
animals := []Sayer{c, d}for _, a := range animals {
fmt.Println(reflect.TypeOf(a).Name(), "says:", a.Say())
}
(这反映出部分只是为了获得类型名称,到目前为止还不多。)
最重要的部分是,我们可以同时处理Cat
并Dog
视为同类(接口类型),并与他们合作/使用它们。如果您很快要使用Say()
方法创建其他类型,则可以在Cat
和旁边排队Dog
:
type Horse struct{}func (h Horse) Say() string { return "neigh" }
animals = append(animals, Horse{})
for _, a := range animals {
fmt.Println(reflect.TypeOf(a).Name(), "says:", a.Say())
}
假设您要编写其他适用于这些类型的代码。辅助功能:
func MakeCatTalk(c Cat) { fmt.Println("Cat says:", c.Say())
}
是的,上面的函数可以使用Cat
,也可以不使用。如果您想要类似的东西,则必须为每种类型编写它。不用说这有多糟。
是的,您可以编写它来接受的参数interface{}
,并使用类型断言或类型开关,这将减少辅助函数的数量,但看起来仍然很丑陋。
解决方案?是的,界面。只需声明该函数以采用接口类型的值即可,该接口类型定义了您要对其执行的操作,仅此而已:
func MakeTalk(s Sayer) { fmt.Println(reflect.TypeOf(s).Name(), "says:", s.Say())
}
你可以调用这个函数的值Cat
,Dog
,Horse
或任何其他类型的现在不知道,直到,有一个Say()
方法。凉。
在Go Playground上尝试这些示例。
以上是 为什么在Golang中需要接口? 的全部内容, 来源链接: utcz.com/qa/425948.html