我试图在Golang中编写泛型函数,该函数将以类似的方式在切片和通道中搜索值。下面是一个例子:
// MinOf returns the smallest number found among the channel / slice contents
func MinOf[T chan int | []int](input T) (result int) {
for _, value := range input {
if result > value {
result = value
}
}
return
}
但是我得到以下编译错误:cannot range over input (variable of type T constrained by chan int|[]int) (T has no core type)
.
我试着创建一个通用的接口,像这样:
type Rangable interface {
chan int | []int
}
// MinOf returns the smallest number found among the channel / slice contents
func MinOf[T Rangable](input T) (result int) {
for _, value := range input {
if result > value {
result = value
}
}
return
}
虽然,错误已更改为cannot range over input (variable of type T constrained by Rangable) (T has no core type)
,但基本保持不变…
是否有任何方法可以使用泛型或通道和片来解决此任务?到相同的核心类型?
谢谢你的任何建议和想法!
你不能这么做。
range
表达式必须具有开头的核心类型。具有不同类型术语的联合没有核心类型,因为没有一个共同的基础类型。
您也可以直观地看到为什么range
需要一个核心类型:在片和通道上的范围的语义是不同的。
-
对通道进行测距是潜在的阻塞操作,对切片进行测距则不是
-
迭代变量不同
for i, item := range someSlice {}
对于切片,i
是类型为int
的索引,item
是类型为切片元素的索引。
for item := range someChan {}
对于通道,item
是chan元素的类型,这是唯一可能的范围变量。
你能拥有的最好的是类型切换:
func MinOf[T any, U chan T | []T](input U) (result int) {
switch t := any(input).(type) {
case chan T:
// range over chan
case []T:
// range over slice
}
return
}
但是,这个函数的行为(阻塞与非阻塞)是类型依赖的,并且不清楚在这里使用泛型有什么好处。