跳到主要内容

约束

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 // 类型元素只能用于约束接口
}