When is the tilde not necessary in Go generics?

Issue

With Golangs new generics we have the tilde operator ~ which will match the underlying type. In what case is it valid to NOT match the underlying type? I’m trying to understand why the current behavior with the tilde is not the default behavior. It seems unnecessary to support both.

For example, why would you write

interface { int }

and not

interface { ~int }

What benefit to you would it be to write a method that is so strict that it could not accept something like

type MyInt int

Why is the tilde behavior not the default, and thus the language would not require another operator?

Solution

Not using the ~ operator means you only accept the listed exact types. Why should this matter?

You may want to use the values of the exact types to set to other variables and else type conversion would be required. And because the saying goes "new type, new method set". New types having the same underlying type have their own method sets.

You may want the "original" behavior of the value, which may change if it has a different method set.

For example, let’s say you want to print the number like this:

type Num interface{ ~int }

func foo[T Num](v T) {
    fmt.Println(v)
}

If MyInt has a String() string method:

type MyInt int

func (m MyInt) String() string { return "bar" }

The output might not be what foo() would want, because the fmt package checks if a printed value has a String() string method, and if so, it is called to acquire its string representation:

foo(1)
foo(MyInt(1))

This will output (try it on the Go Playground):

1
bar

If you only allow int:

type Num interface{ int }

You can still call foo() with a value of type MyInt, using a type conversion:

foo(1)
x := MyInt(1)
foo(int(x))

And output will be what foo() wants, not what MyInt would want (try this one on the Go Playground):

1
1

Yes, this would also be possible if foo() itself would do the conversion, but this clearly documents you want a pure int, with int‘s behavior, and not something that is an int with a different, custom behavior.

Answered By – icza

Answer Checked By – Senaida (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.