interface contains type constraints: cannot use interface in conversion
Asked Answered
C

1

23
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

Cashbook answered 10/2, 2022 at 23:6 Comment(0)
H
28

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
}
Horst answered 11/2, 2022 at 6:50 Comment(2)
tks, I misunderstand between type and type parameter constraintCashbook
@Cashbook the confusion probably is that constraints are interface types, however when they include one or more types themselves the language allows only to use them in that specific wayHorst

© 2022 - 2025 — McMap. All rights reserved.