GO校验实现接口

https://go.dev/doc/faq#implements_interface
https://www.reddit.com/r/golang/comments/m1hfl7/what_does_this_syntax_mean_tnil/

How can I guarantee my type satisfies an interface?

You can ask the compiler to check that the type T implements the interface I by attempting an assignment using the zero value for T or pointer to T, as appropriate:

1
2
3
4
type T struct{}
var _ I = T{} // Verify that T implements I.
var _ I = (*T)(nil) // Verify that *T implements I.

If T (or *T, accordingly) doesn’t implement I, the mistake will be caught at compile time.

If you wish the users of an interface to explicitly declare that they implement it, you can add a method with a descriptive name to the interface’s method set. For example:

1
2
3
4
5
type Fooer interface {
Foo()
ImplementsFooer()
}

A type must then implement the ImplementsFooer method to be a Fooer, clearly documenting the fact and announcing it in go doc‘s output.

1
2
3
4
type Bar struct{}
func (b Bar) ImplementsFooer() {}
func (b Bar) Foo() {}

Most code doesn’t make use of such constraints, since they limit the utility of the interface idea. Sometimes, though, they’re necessary to resolve ambiguities among similar interfaces.

如何确保我的类型符合接口?

您可以要求编译器使用零值或指针(如适用)来尝试赋值,以检查类型 T 是否实现接口 I:

1
2
3
4
type T struct{}
var _ I = T{} // 验证 T 是否实现了 I。
var _ I = (*T)(nil) // 验证 *T 是否实现了 I。

如果 T(或 *T,相应地)没有实现 I,则该错误将在编译时被捕获。

如果您希望接口的用户明确声明他们实现了它,您可以将一个具有描述性名称的方法添加到接口的方法集中。例如:

1
2
3
4
5
type Fooer interface {
Foo()
ImplementsFooer()
}

那么,类型必须实现 ImplementsFooer 方法才能成为 Fooer,明确记录此事实并在 go doc 的输出中宣布它。

1
2
3
4
type Bar struct{}
func (b Bar) ImplementsFooer() {}
func (b Bar) Foo() {}

大多数代码不使用此类约束,因为它们限制了接口思想的效用。有时,它们是必要的,以解决类似接口之间的不明确性。