约束
any 约束是什么? 有哪些操作限制?
- 约束入口:
any允许任意类型实参,空接口与别名含义见interface 值; - 操作限制: 只可使用所有类型都支持的操作;
func Identity[T any](v T) T { // any 允许任意类型作为类型实参
return v
}
comparable 约束是什么? 哪些类型不满足?
comparable: 允许相等比较的类型约束;- 不包含类型: slice, map, function;
func Equal[T comparable](a, b T) bool { // comparable 允许 == 和 !=
return a == b
}
-
接口实参: Go 1.20 起,
any等可比较接口也可满足comparable约束;若实际比较的动态值不可比较,仍会 panic; -
动态值反例: 下例的类型实参 any 可以通过约束检查,但两个接口中装的都是不可比较的切片;
var a any = []int{1}
var b any = []int{1}
// Equal[any](a, b) // 编译允许,执行 == 时 panic
_, _ = a, b
自定义约束如何声明? union 与类型集合如何表达?
- constraint interface: 可在接口中写类型集合;
- union:
|表示允许多个类型; - 类型集合: 约束允许的所有类型;
type Integer interface {
~int | ~int8 | ~int16 | ~int32 | ~int64 // ~T 允许底层类型为 T 的自定义类型
}
func Max[T Integer](a, b T) T {
if a > b { // 只有类型集合中所有类型都支持的操作可用
return a
}
return b
}
类型元素是什么? 基本接口与非基本接口有何区别?
- 基本接口: 只包含方法的接口, 可作为普通值类型;
- 非基本接口: 包含类型元素的接口, 只能作为约束使用;
type Number interface {
~int | ~int64 | ~float64 // 类型元素只能用于约束接口
}