我希望能够在一个结构的两个字段之间强制执行相似,但在一个映射或切片中也有几个这样的结构。
下面是我的问题的一个简化示例:
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 })
}编译器会抱怨
./. in :13:33:不能使用f(类型为func() T的变量)作为结构文字中的func()类型
有趣的是,如果我不需要在结构中有一个函数指针,这是可以工作的。请参阅https://go.dev/play/p/qXTmaa9PuVe
那么,有什么方法可以让我把T变成N呢?
我知道我可以通过接口{}来实现这一点,并使用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...
}问题已经结束,所以我必须在这里回答我问题的第二部分。
是否可以用更好的答案代替?
上述问题的答案是肯定的。
解决方案:
最初我想:“func()适合func(),any适合T,那么为什么不能让func() T适合func() any呢?”当然,原因是func() any不是any,因此不能容纳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 })
}发布于 2022-04-19 05:38:48
,但在映射或切片中也有一些这样的结构。
您不能这样做(以一种类型安全的方式)。例如,片的所有值都必须具有相同的元素类型。如果您想要存储不同的,您必须求助于interface{},然后键入开关。
如果您使用正确的技术术语参数多态性,而不是“泛型”(它不能解释正在发生的事情),您将看到为什么func(T)和func(any)是不同的、不可转换的类型。
,那么,有什么方法可以让我把T变成any吗?
不,没有前“泛型”的方式,也没有后“泛型”的方式。它有助于将“转变为”作为Go允许的内容:“类型转换”和“赋值”。您可以将T类型的任何变量赋值给任意类型的变量。
您可以通过使用适配器函数(闭包)来克服问题:
w := func(a any){ f(a.(T)) }
b.x = append(b.x, &foo[any]{w})https://stackoverflow.com/questions/71919380
复制相似问题