type Number interface {
int | int64 | float64
}
type NNumber interface {
}
//interface contains type constraints
//type NumberSlice []Number
type NNumberSlice []NNumber
func main() {
var b interface{}
b = interface{}(1)
fmt.Println(b)
// interface contains type constraints
// cannot use interface Number in conversion (contains specific type constraints or is comparable)
//a := []Number{Number(1), Number(2), Number(3), Number(4)}
//fmt.Println(a)
aa := []interface{}{interface{}(1), interface{}(2), interface{}(3), 4}
fmt.Println(aa)
aaa := []NNumber{NNumber(1), NNumber(2), NNumber(3), 4}
fmt.Println(aaa)
}
why the Number
slice a
couldn't be initialized like that?
NumberSlice
and NNumberSlice
look like similarly, but what mean type constraints, it looks strange grammar
The language specifications explicitly disallow using interfaces with type elements as anything other than type parameter constraints (the quote is under the paragraph Interface types):
Interfaces that are not basic may only be used as type constraints, or as elements of other interfaces used as constraints. They cannot be the types of values or variables, or components of other, non-interface types.
An interface that embeds comparable
or another non-basic interface is also non-basic. Your Number
interface contains a union, hence it is non-basic too.
A few examples:
// basic: only methods
type A1 interface {
GetName() string
}
// basic: only methods and/or embeds basic interface
type B1 interface {
A1
SetValue(v int)
}
// non-basic: embeds comparable
type Message interface {
comparable
Content() string
}
// non-basic: has a type element (union)
type Number interface {
int | int64 | float64
}
// non-basic: embeds a non-basic interface
type SpecialNumber interface {
Number
IsSpecial() bool
}
In the initialization of the variable a
, you are attempting to use Number
in a type conversion Number(1)
, and this is not allowed.
You can only use Number
as a type parameter constraint, i.e. to restrict the types allowed for instantiation of a generic type or function. For example:
type Coordinates[T Number] struct {
x, y T
}
func sum[T Number](a, b T) T {
return a + b
}