首页 >后端开发 >Golang >Go 1.18 泛型可以处理函数签名中的逆变类型吗?

Go 1.18 泛型可以处理函数签名中的逆变类型吗?

Susan Sarandon
Susan Sarandon原创
2024-11-17 10:50:021096浏览

Can Go 1.18 Generics Handle Contravariant Types in Function Signatures?

Go 1.18 中具有逆变类型的泛型:澄清和限制

在 Go 1.18 中使用泛型定义一个函数的努力,该函数接受两个函数兼容但不相同的类型(一种逆向行为)遇到了挑战。让我们深入研究细节以了解原因。

考虑以下函数定义:

func Pipe[A, T1, T2 any](left func(A) T1, right func(T1) T2) func(A) T2 {
    return func(a A) T2 {
        return right(left(a))
    }
}

此函数旨在将左侧函数的输出通过管道传输到右侧函数,从而链接计算。但是,当尝试将其与以下示例一起使用时:

func OpenFile(name string) *os.File {
...
}

func ReadAll(rdr io.Reader) []byte {
...
}

var OpenRead = Pipe(OpenFile, ReadAll)

编译失败。这是因为编译器期望 T1 与 *os.File 相同,即使它与 io.Reader 兼容。虽然期望兼容类型被接受似乎是合理的,但由于 Go 缺乏对协变结果类型的支持,情况并非如此。

有没有办法在 Go 1.18 中修复此签名?

不幸的是,没有。 Go 的泛型目前缺乏使用类型参数表达类型可转换性的能力,因此无法修改 Pipe 函数以允许这种行为。

这是 Go 1.18 中的错误吗?

没有。正如官方常见问题解答中所述,此行为是故意的,不被视为错误。

解决方法

要获得类似的结果,可以手动实现转换步骤:

func Pipe[A, T1, T2, T3 any](left func(A) T1, right func(T2) T3) func(A) T3 {
    return func(a A) T3 {
        return right(any(left(a)).(T2))
    }
}

但是,需要注意的是,这种方法不提供编译时类型安全性。

以上是Go 1.18 泛型可以处理函数签名中的逆变类型吗?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn