我希望能够在结构的两个字段之间强制执行相似性,但在映射或切片中也有几个这样的结构。
这是我的问题的一个简化示例:
package main
type foo[T any] struct {
f func() T
v T
}
type bar struct {
x []*foo[any]
}
func baz[T any](b *bar, f func() T) {
b.x = append(b.x, &foo[any]{f: f})
}
func main() {
var b bar
baz(&b, func() int { return 0 })
}
编译器抱怨
./prog.go:13:33: 不能在结构文字中使用 f(func() T 类型的变量)作为 func() any 类型
有趣的是,如果我不需要在结构中有一个函数指针,这就可以工作。请参阅https://go.dev/play/p/qXTmaa9PuVe
那么,有没有办法让我把 T 变成 any?
我知道我可以使用 interface{} 来做到这一点并使用 reflect 来执行我想要的,但我确信只有泛型才有可能。
如果有办法解决我的问题,上下文是我正在制作一个标志包。重要的结构如下所示:
type flag[T any] struct {
value T
parse func(in string) (T, error)
// Other fields removed for simplicity...
}
type FlagSet struct {
// could flag[any] be replaced with a better answer?
flags map[string]*flag[any]
// Other fields removed for simplicity...
}
这个问题已经结束,所以我必须在这里回答我问题的第二部分
可以用更好的答案替换 flag[any] 吗?
上面的答案是肯定的。
解决方案:
最初我虽然是这样的:“一个func()适合一个func(),一个any适合一个T,所以为什么我不能有一个func() T适合的func() any?” 当然原因是 afunc() any不是 anany所以它不能容纳 a func() T。
相反,您可以执行以下操作:
package main
type foo[T any] struct {
f func() T
v T
}
func (f *foo[_]) set() {
f.v = f.f()
}
type anyfoo interface {
set()
}
type bar struct {
x []anyfoo
}
func baz[T any](b *bar, f func() T) {
b.x = append(b.x, &foo[T]{f: f})
}
func main() {
var b bar
baz(&b, func() int { return 0 })
}
慕后森