Convert type T to type U in an identity function

Issue

With the given type signature below, is there a way to do something similar to below?

func Transform[T, U any](item T) U {
    return item
}

The code above gives the following error:

cannot use item (variable of type T constrained by any) as U value in return 
statement

I am unable to use the type signature above, as I am essentially trying to make an optional transform method that sometimes will need to convert from T to U, but sometimes just return itself. A more detailed example of the use case is shown below.

type SomeStruct[T, U any] struct {
    Transform func(T) U
}

func (s SomeStruct[T, U]) Transform(elem T) (U) {
    if s.Transform != nil {
        return s.Transform(elem)
    }
    return elem
}

Is there a way to create a Transform function that sometimes conditionally just returns itself?

Solution

You can make your code snippet work:

func Transform[T, U any](item T) U {
    return any(item).(U)
}

But the code will fail with a panic if U is not assertion-compatible with the actual type of item:

This will panic:

fmt.Println(Transform[string, int]("foo"))

// Output: panic: interface conversion: interface {} is string, not int

This succeeds without panic, because bytes.Buffer is implements both the io.Reader and io.Writer interface:

b := &bytes.Buffer{}
_ = Transform[io.Writer, io.Reader](b)

So, it’s possible to do what you want. But I’m not sure how useful it is, as fails at runtime of the actual argument isn’t compatible with U.

Answered By – Erwin Bolwidt

Answer Checked By – Dawn Plyler (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.