1

Given these type definitions:

type N interface{ ~int | ~float32 | ~float64 }

type S[T any] struct {
    t T
}

type myInt int

type pSpMyInt[T myInt] *S[*T]
type spMyInt[T *myInt,] S[T]
type spMyInt2[T myInt] S[*T]

I can create a var of type pSpMyInt with

func createPS[T myInt]() pSpMyInt[T] {
    var i T
    s := S[*T]{t: &i}
    return &s
}

But I can not figure out how to create vars of spMyInt or spMyInt2.

This

func createSP[T myInt]() spMyInt2[T] {
    var i T
    s := S[*T]{t: &i}
    return s
}

fails to compile cannot use s (variable of type S[*T]) as type spMyInt2[T] in return statement.

1 Answer 1

3

First of all, do NOT use exact type parameter constraints. It almost never makes sense. When you declare a function as createPS[T myInt](), the type parameter type set has cardinality 1, so it can effectively be instantiated only and ever by myInt. You could rewrite the function like the following just as fine:

func createPS() pSpMyInt[myInt] {
    var i myInt
    s := S[*myInt]{t: &i}
    return &s
}

With that out of the way:

The type S[*T] is just not the same as spMyInt2[T]. However, since spMyInt2[T]'s underlying type is S[*T], you can simply convert:

func createSP2[T myInt]() spMyInt2[T] {
    var i T
    s := S[*T]{t: &i}
    return spMyInt2[T](s) // conversion
}

As for type spMyInt[T *myInt,] S[T] (where the comma is not a typo but is needed to avoid a parsing ambiguity), the thing isn't that simple.

The problem is that a type parameter is not its type constraint. Therefore type literals can't be used to instantiate different unnamed type literals. To be clear:

// naive attempt that doesn't compile
func createSP1[T myInt]() spMyInt[*T] {
    var i T
    s := S[*T]{t: &i}
    return spMyInt[*T](s)
}

You might think that spMyInt[T *myInt] has a type parameter constrained to *myInt and the function T is constrained by the base type myInt, therefore *T should satisfy T *myInt. This is not correct for the apparently unobvious reason that the type literal *T is not equivalent to *myInt. So actually you can't write a generic constructor for type spMyInt[T *myInt,] S[T].

However you are in luck because the type constraint had cardinality one. So you can just remove the type parameter:

func createSP1() spMyInt[*myInt] {
    var i myInt
    s := S[*myInt]{t: &i}
    return spMyInt[*myInt](s)
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.