2 回答
TA贡献1842条经验 获得超21个赞
如果您因为它的通用标题(不是双关语)而遇到这个问答,这里有一个关于工会的快速入门:
可用于指定接口约束的类型集。泛型类型参数
T
将被限制为联合中的类型只能在接口约束中使用。如果一个接口包含一个联合(带有一个或多个术语),那么它就是一个接口约束。
可以包括近似元素
~
例如:
type intOrString interface {
int | string
}
func Foo[T intOrString](x T) {
// x can be int or string
}
现在谈谈OP的问题,还有更多细节:
您不能将接口约束用作类型
通过包含类型集,intOrString
成为接口约束,并且明确不支持将其用作类型。允许约束作为普通接口类型:
这是我们现在不建议的功能,但可以考虑用于该语言的更高版本。
所以首先要做的是intOrString
用作实际约束,因此在类型参数列表中使用它。下面我替换comparable
为intOrString
:
type testDifferenceInput[T intOrString] [][]T
type testDifferenceOutput[T intOrString] []T
type testDifference[T intOrString] struct {
input testDifferenceInput[T]
output testDifferenceOutput[T]
}
这也意味着您不能使用约束将具体类型实例化为测试切片:
// bad: using intOrString to instantiate a parametrized type[]testDifference[intOrString]
通用容器不能容纳不同类型的项目
您遇到的第二个问题是测试切片包含两个不相关类型的结构。一个是testDifference[int]
,一个是testDifference[string]
。即使类型testDifference
本身使用联合约束进行参数化,它的具体实例也不是相同的类型。另请参阅此以获取更多详细信息。
如果您需要一个包含不同类型的切片,您唯一的选择是[]interface{}
(或[]any
) ...或者,您只需将切片分开:
ttInts := []testDifference[int]{ testDifference[int]{...}, /* etc. */ } ttStrs := []testDifference[string]{ testDifference[string]{...}, /* etc. */ }
允许对联合约束的操作
只有类型集中所有类型都支持的操作。基于类型集的操作:
规则是泛型函数可以以参数约束的类型集的每个成员所允许的任何方式使用其类型为类型参数的值。
如果有类似 的约束,在或int | string
上允许的操作是什么?简而言之:int
string
变量声明 (
var foo T
)转换和断言
T(x)
,并x.(T)
在适当的时候比较 (
==
,!=
)排序 (
<
,<=
,>
和>=
)+
操作员
所以你可以有一个intOrString
约束,但使用它的功能,包括你的 func Difference
,仅限于这些操作。例如:
type intOrString interface {
int | string
}
func beforeIntOrString[T intOrString](a, b T) bool {
return a < b
}
func sumIntOrString[T intOrString](a, b T) T {
return a + b
}
func main() {
fmt.Println(beforeIntOrString("foo", "bar")) // false
fmt.Println(beforeIntOrString(4, 5)) // true
fmt.Println(sumIntOrString("foo", "bar")) // foobar
fmt.Println(sumIntOrString(10, 5)) // 15
}
- 2 回答
- 0 关注
- 80 浏览
添加回答
举报