Golang中如何实现基本数据类型和结构体的泛型?
Golang中如何实现基本数据类型和结构体的泛型?
我正在编写我的数据结构:type MyContainer[constraints.Ordered] {… }
遗憾的是,它可以接受整数、浮点数等任何基本数据类型,但不能接受已实现 Less 和 Equal 方法的自定义结构体。
这迫使我做出选择:要么我的有效载荷(即插入到 MyContainer 中的内容)是基本数据类型,要么是结构体。
有什么办法可以绕过这个限制吗?我希望 MyContainer 能够同时存储两者(即同一泛型代码可以针对基本数据类型或自定义结构体进行实例化)。
在 MyContainer 内部,我希望能够添加整数、浮点数、字符串(任何属于 constraints.Ordered 的内容)。但我也希望相同的代码能够适用于任何实现了 type MyInterface { Less(MyInterface) bool} 的结构体。
另一个问题:我不禁注意到泛型的一个弱点,如果你用 int 类型实例化 MyContainer,然后想向其中插入一个 float,这是行不通的。同样地,如果你用 MyStructA 类型实例化一个 MyContainer,那么你就不能在其中插入类型为 MyStructB 的对象,即使 MyStructB 实现了与 MyStructA 相同的接口。也请就如何绕过此问题提供建议。
更多关于Golang中如何实现基本数据类型和结构体的泛型?的实战教程也可以访问 https://www.itying.com/category-94-b0.html
你可以增加一层间接性:如果你定义一个 Comparable[T] 接口:
type Comparable[T any] interface {
Less(T) bool
Equal(T) bool
}
然后你可以实现一个 ComparablePrimitive[T]:
type ComparablePrimitive[T constraints.Ordered] struct{ Value T }
func ComparablePrimitiveOf[T constraints.Ordered](v T) Comparable[T] {
return ComparablePrimitive[T]{Value: v}
}
func (a ComparablePrimitive[T]) Less(b T) bool { return a.Value < b }
func (a ComparablePrimitive[T]) Equal(b T) bool { return a.Value == b }
那么你的 MyStruct 字段只需要是 Comparable[T] 类型:
type MyStruct[T any] struct {
Comparable Comparable[T]
}
Go Playground - The Go Programming Language
在 MyContainer 内部,我希望能够添加整数、浮点数、字符串(任何在 constraints.Ordered 中的类型)。但我也希望我的相同代码能适用于任何实现了 type MyInterface { Less(MyInterface) bool} 的结构体。
我不太确定你在这里想实现什么。在 Go 语言中,你不能比较不同的类型;它们必须是相同的类型。例如,下面的代码无法编译:
package main
import (
"fmt"
)
func main() {
f := 0.123 // 类型: float64
i := 3 // 类型: int
fmt.Println(f < i)
}
./prog.go:10:18: invalid operation: f < i (mismatched types float64 and int)
所以,即使语言允许你拥有 constraints.Ordered 类型的值,你也不能做类似这样的事情:
f := 0.123 // 类型: float64
i := 3 // 类型: int
values := []constraints.Ordered{f, i}
fmt.Println(values[0] < values[1])
我不得不注意到泛型的一个弱点,如果你用 int 实例化 MyContainer,然后你想向其中插入一个 float,这将无法工作。
这不是一个弱点:这是一个优点。泛型的目的就是禁止混合类型。如果你想要一个混合值的集合,请使用 []interface{}。
你能展示一下你试图用你的 MyStruct 做什么吗?你是想比较 int 和 float,以及它们和 MyStructA 等类型吗?如果是这样,像 MyStructA{Name: "skillian"} <= MyStructB{MeltingPointK: 4012} 这样的混合类型该如何求值?也许泛型/constraints.Ordered 并不是你需要的。
更多关于Golang中如何实现基本数据类型和结构体的泛型?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


