我在Go 1.21中使用泛型。我想扩展一些通用代码。
如果我将下面的foo()
添加到Under11AgeGroups
接口中,那么只有9岁以下和11岁以下的人必须实现这个函数,我会得到一个编译错误:
不能将接口与union中的方法一起使用。
我错过了一个方法来做到这一点吗?
下面的代码运行。
https://go.dev/play/p/w_N7gbsRCjY
package main
import (
"fmt"
)
type AllAgeGroups interface {
Under13Player | Under11AgeGroups
name() string
}
type Under11AgeGroups interface {
Under9Player | Under11Player
// foo() string <-- this causes cannot use main.Under11AgeGroups in union (main.Under11AgeGroups contains methods)
}
type Players[T AllAgeGroups] struct {
Results []T
}
func (t *Players[T]) PrintTheTeam() {
fmt.Println("----------------")
for _, p := range t.Results {
fmt.Println("Player ", p.name())
}
}
type Under9Player struct { Name string }
func (u Under9Player) name() string {
return u.Name
}
type Under11Player struct { Name string }
func (u Under11Player) name() string {
return u.Name
}
type Under13Player struct { Name string; Age int }
func (u Under13Player) name() string {
return u.Name + " " + string(u.Age)
}
func main() {
bob := Under11Player{Name: "bob"}
alice := Under11Player{Name: "alice"}
yves :=Under11Player{Name: "yves"}
under11team := Players[Under11Player]{Results: []Under11Player{bob, alice, yves}}
under11team.PrintTheTeam()
foo :=Under13Player{Name: "foo", Age: 12}
under13team := Players[Under13Player]{Results: []Under13Player{foo}}
under13team.PrintTheTeam()
}
字符串
1条答案
按热度按时间cnwbcb6i1#
你不能直接向已经出现在union项中的接口添加方法。这是语言规范禁止的(关于接口类型的段落):
实施限制:联合(具有多个术语)不能包含预先声明的标识符comparable或指定方法的接口,或嵌入comparable或指定方法的接口。
不过,有个窍门!由于你使用这些接口作为约束,它们提供了编译时检查。你可以通过尝试示例化一个类型参数来复制编译时检查,该类型参数被约束到具有所需类型的方法:
字符串
请注意,
mustDefineFoo[Under9Player]
是函数值。实际上这些值是什么并不重要,它们的存在只是为了强制编译器检查Under9Player
和Under11Player
是否满足约束:如果它们有foo() string
方法,它们就满足约束。Playground:https://go.dev/play/p/2QXzMsw1Qld
显然,每次向主接口约束
Under11AgeGroups
添加一个新项时,都必须向源代码中添加一个新的虚拟示例化,但这与向现有联合体中添加一个新项没有太大区别。