英文:
Go - how to explicitly state that a structure is implementing an interface?
问题
由于Go语言非常注重接口,我想知道如何明确声明一个结构体实现了某个接口,以便于清晰地检查错误,以防某个方法缺失。到目前为止,我看到了两种方法,我想知道哪种方法是正确的,符合Go语言规范。
方法1 - 匿名字段
type Foo interface{
Foo()
}
type Bar struct {
Foo
}
func (b *Bar)Foo() {
}
方法2 - 显式转换
type Foo interface{
Foo()
}
type Bar struct {
}
func (b *Bar)Foo() {
}
var _ Foo = (*Bar)(nil)
这些方法正确吗?还是还有其他方法可以实现类似的功能?
英文:
Since Go puts a heavy emphasis on interfaces, I'm wondering how can I explicitly state that a structure is implementing an interface for clarity and errors checking in case some method is missing? I have seen two approaches so far, and I'm wondering which is correct and in accordance to Go specification.
Method 1 - anonymous field
type Foo interface{
Foo()
}
type Bar struct {
Foo
}
func (b *Bar)Foo() {
}
Method 2 - Explicit conversion
type Foo interface{
Foo()
}
type Bar struct {
}
func (b *Bar)Foo() {
}
var _ Foo = (*Bar)(nil)
Are those methods correct, or is there some other way to do something like this?
答案1
得分: 10
方法2是正确的,方法1只是嵌入了一个类型并覆盖了它的函数。如果你忘记覆盖它,你将得到一个空指针解引用。
英文:
Method 2 is the correct one, method 1 you're just embedding a type and overriding its function. If you forget to override it, you will end up with a nil pointer dereference.
答案2
得分: 7
我很少需要声明这一点,因为在我的包中几乎总会有一个地方我使用结构体作为接口。我倾向于遵循将结构体尽可能保持不公开的模式,并且只通过“构造函数”来提供它们。
type Foo interface {
Foo()
}
type bar struct {}
func (b *bar) Foo() {}
func NewBar() Foo {
return &bar{}
}
如果bar
不满足Foo
,这段代码将无法编译。我不会添加任何构造来声明类型实现了接口,而是确保我的代码在某个地方将其作为接口使用。
英文:
I have rarely needed to declare this, because there is almost always somewhere in my package where I am using the struct as the interface. I tend to follow the pattern of keeping my structs unexposed where possible, and providing them only through "constructor" functions.
type Foo interface{
Foo()
}
type bar struct {}
func (b *bar)Foo() {}
func NewBar() Foo{
return &bar{}
}
If bar
does not satisfy Foo
, this will not compile. Rather than add constructs to declare that the type implements the interface, I just make sure that my code uses it as the interface at some point.
答案3
得分: 2
你不能。在Go语言中,所有接口实现都是隐式的。你可以检查一个类型是否实现了一个接口(这是最明确的方式)。如果我记得没错,在我参与的一个项目中,我们只是在包的顶部对类型进行了一些类型断言,以确定它实现了哪些接口,这是最接近明确的方式了。
英文:
You cannot. In Go all interface implementations are implicit. You can check if a type implements an interface (and that is the most explicit it gets). If I recall correctly in a project I worked on, we just did some type asserts at the top of the package against the interfaces which the type implemented, and that is as close to explicit as it gets.
答案4
得分: 0
var _
技巧不支持泛型约束。你只能声明“这个特定的专门类型实现了接口”,而不能声明“对于满足某个约束的所有类型,这个组合类型实现了接口”。使用函数来实现会更方便:
func _[T1 any, T2 comparable](v Foo[T1, T2]) Bar[T1] { return v }
这段代码的含义是:
对于所有类型
T1
,对于所有可比较的类型T2
,Foo[T1, T2]
实现了Bar[T1]
。
英文:
The var _
trick does not support generic constraints. You can only state "this certain specialized type implements the interface" but not "for all types satisfying a certain constraint, this composed type implements the interface". It is more convenient to do this with a function instead:
func _[T1 any, T2 comparable](v Foo[T1, T2]) Bar[T1] { return v }
This reads as
> For all types T1
, for all comparable types T2
, Foo[T1, T2]
implements Bar[T1]
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论