Go 1.24.0 is here!

February 11, 2025

Go 1.24 is released!

Yay!

That means a short re-visit to the Go spec, as we look at things that have changed.

From the release notes we see that there’s really only one significant change:

Changes to the language¶

Go 1.24 now fully supports generic type aliases: a type alias may be parameterized like a defined type. See the language spec for details. For now, the feature can be disabled by setting GOEXPERIMENT=noaliastypeparams; but the aliastypeparams setting will be removed for Go 1.25.

So let’s take a look at the language spec for those details…

Alias declarations

An alias declaration binds an identifier to the given type [Go 1.9].

AliasDecl = identifier [ TypeParameters ] "=" Type .

The big change here is the addition of [ TypeParameters ]. In earlier versions of Go, aliases of generic types were not allowed.

Then we also have the following new explanation:

If the alias declaration specifies type parameters [Go 1.24], the type name denotes a generic alias. Generic aliases must be instantiated when they are used.

type set[P comparable] = map[P]bool

In an alias declaration the given type cannot be a type parameter.

type A[P any] = P    // illegal: P is a type parameter

I think that’s pretty well explained already. And pretty intuitive (well, as intuitive as aliases and generics ever are).

So I’ll use the rest of today’s email to reiterate the differences between a type alias, and a distinct named type. Because there seems to be no end to confusion on this matter.

Let’s take the example from above, and slightly modify it:

type set1[P comparable] = map[P]bool
type set2[P comparable] map[P]bool

What’s the difference between set1 and set2 here? They seem to have the same underlying type, right?

The former (set1) is an alias. This means you can logically replace set[P] anywhere you see it in code with map[P]bool and vice versa. The two expressions are interchangeable. Neither holds more or less type information than the other.

The latter (set2) is a distinct type. This means that set2[P] and map[P]bool are distinct types (although you can convert between them if you wish). It also means that you can create methods on set2—something you cannot do for aliases.


Share this

Direct to your inbox, daily. I respect your privacy .

Unsure? Browse the archive .

Related Content


Type parameters in method definitions

Yesterday we saw that when a method is defined on a generic type, the receiver must include type parameters. Now for all the relevant details: Method declarations … … Syntactically, this type parameter declaration looks like an instantiation of the receiver base type: the type arguments must be identifiers denoting the type parameters being declared, one for each type parameter of the receiver base type. The type parameter names do not need to match their corresponding parameter names in the receiver base type definition, and all non-blank parameter names must be unique in the receiver parameter section and the method signature.


Methods on generic types

Ready to dive back into generics, this time with regard to methods? Great, ‘cause here we go! Method declarations … If the receiver base type is a generic type, the receiver specification must declare corresponding type parameters for the method to use. Okay. Before we continue, let’s make sure we all know exactly what we’re talking about. What does it mean for a receiver base type to be a generic type?


Generic methods

Type definitions … A generic type may also have methods associated with it. In this case, the method receivers must declare the same number of type parameters as present in the generic type definition. // The method Len returns the number of elements in the linked list l. func (l *List[T]) Len() int { … } This probably needs further explanation. Or an example. It did for me. Let’s look at a simple generic type:

Get daily content like this in your inbox!

Subscribe