首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如果Go的接口没有被强制执行,那么它们是必要的吗?

如果Go的接口没有被强制执行,那么它们是必要的吗?
EN

Stack Overflow用户
提问于 2012-06-16 00:36:01
回答 3查看 989关注 0票数 4

Go语言将接口类型作为特性,类似于C风格的接口。然而,Go的接口类型似乎并不是强制的--它们只是定义协议,而不是实际应用于某个类型。因为它们不是强制的,所以使用接口仍然是一个好主意吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-06-16 00:50:30

是。Go不允许构建类型层次结构,因此接口对于允许某些多态性非常重要。考虑在sort包中定义的sort.Interface

代码语言:javascript
复制
type Interface interface {
    // Len is the number of elements in the collection.
    Len() int
    // Less returns whether the element with index i should sort
    // before the element with index j.
    Less(i, j int) bool
    // Swap swaps the elements with indexes i and j.
    Swap(i, j int)
}

sort包包含一个函数sort(data Interface),该函数需要实现此接口的任何对象。如果没有接口,这种形式的多态性在go中是不可能实现的。事实上,您不必显式地注释您的类型实现了此接口,这一点无关紧要。

关于go最酷的部分是,你甚至可以在原始类型上实现这个接口,只要类型是在同一个包中定义的。因此,下面的代码定义了一个可排序的整数数组:

代码语言:javascript
复制
type Sequence []int

// Methods required by sort.Interface.
func (s Sequence) Len() int {
    return len(s)
}
func (s Sequence) Less(i, j int) bool {
    return s[i] < s[j]
}
func (s Sequence) Swap(i, j int) {
    s[i], s[j] = s[j], s[i]
}
票数 10
EN

Stack Overflow用户

发布于 2020-06-10 15:12:59

是的,使用接口仍然是一个很好的想法。Go强调界面。参见https://talks.golang.org/2014/go4gophers.slide#5。扩展@ElianEbbing杰出的答案,任何类型上的方法和特别的接口构成了一种轻量级的OO编程风格。参见https://talks.golang.org/2012/goforc.slide#48

举个例子可以说明这一点。

代码语言:javascript
复制
package main

import . "fmt"

func main() {
    c.Cry()      // Meow
    Cryer.Eat(c) // Fish
}

var c = cat{"Fish"}
type cat struct{ s string }
type Eater interface{ Eat() }
type Cryer interface {
    Cry()
    Eater
}
func (c cat) Eat() { Println(c.s) }
func (cat) Cry()   { Println("Meow") }

Cryer接口允许您访问Cry()Eat()方法。参见https://talks.golang.org/2012/zen.slide#16。您可以将Cryer添加到基础代码中,而无需更改它。参见https://stackoverflow.com/a/11753508/12817546。如果我们删除它,代码就能正常工作。您仍然可以直接访问一个方法,如c.Cry()所示。这是因为Go可以让你做两件事。

首先,您可以隐式实现一个接口。接口只是一组方法。参见https://talks.golang.org/2013/go4python.slide#33。接口变量可以存储任何非接口值,只要它实现接口的方法即可。参见https://blog.golang.org/laws-of-reflection。可以将实现接口所有方法的任何类型的值赋给该接口的变量。参见https://talks.golang.org/2014/taste.slide#20

ccat的一个变量。cat实现了Eat()Cry()方法。Eater显式实现了Eat()Cryer显式实现了Cry()Eat()。因此,cat隐式地实现了EaterCryer接口。参见https://talks.golang.org/2012/goforc.slide#40。因此,ccat的变量,可以是EaterCryer的变量。参见https://golang.org/doc/effective_go.html#blank_implements

其次,结构和接口类型可以嵌入到其他结构和接口类型中。参见https://golang.org/doc/effective_go.html#embeddingCryer.Eat(c)调用Eat(),因为它嵌入了Eater。因此,Go中的接口是解耦程序组件的主要手段。参见https://www.reddit.com/r/golang/comments/6rwq2g。以及为什么接口可以在包、客户端或服务器之间提供良好的API。参见https://stackoverflow.com/a/39100038/12817546

如果你看不到好处,那就不要添加接口。请参阅https://stackoverflow.com/a/39100038/12817546中的注释。没有明确的层次结构,因此不需要设计层次结构!参见https://talks.golang.org/2012/goforc.slide#46。在需要时添加接口。首先定义你的数据类型,然后构建你的1-3个方法interface。参见https://stackoverflow.com/a/11753508/12817546。编辑引文以匹配示例。

票数 3
EN

Stack Overflow用户

发布于 2012-06-16 00:53:38

我希望知道什么是类型检查,无论是静态的还是运行时的,但我不知道什么是“强制接口”。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11054830

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档