Some programming languages such as C++ and Rust support generic specialization, does Go generic support it?

Specialization is an extension of the generic function code. For example, for a generic function, its implementation is the same for all types (type sets) that satisfy the generic argument. If we want to do a special implementation of the function for one of these type sets, some languages that support generic specialization can support it, such as C++ template:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
template <typename T>
void fun(T a)
{
	cout << "template fun(): " << a << endl;
}
template <>   // 对int型特例化
void fun(int a)
{
	cout << "specialized template fun for int type: " << a << endl;
}

Here fun is a function template, but there is a special implementation of this function for the int type.

Rust also has a similar function:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#![feature(min_specialization)]
struct Special
{
    x : usize,
    y : usize
}
trait MyTrait
{
    fn myfunc(&self);
}
impl<T> MyTrait for T
{
    default fn myfunc(&self) { println!("hi"); }
}
impl MyTrait for Special
{
    fn myfunc(&self) { println!("I'm special"); }
}
fn main() {
    let spe = Special{
        x: 1,
        y: 2,
    };
    spe.myfunc();
}

Here MyTrait has a default implementation for the generic type T, but has a specific implementation for the specific type Special.

Other programming languages do not currently support specialization, but can implement similar functionality through method overloading, such as typescript, C#, etc. In addition, complex specialization includes partial specialization features.

So the question is, do Go’s generics (type parameters) support specialization? Let’s write an example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
type List[T any] struct {
	next  *List[T]
	value T
}
func (l *List[T]) Len() int {
	return 0
}
func (l *List[string]) Length() int {
	return 0
}

Here we define a generic type List[T any] , including its generic method Len() int, and then we try to define a “specialization” method Length() int.

Compile it, no problem, the program compiles normally, does the Go generic really support specialization?

Let’s try adding another special generalization method:

1
2
3
func (l *List[int]) Size() int {
	return 0
}

Try compiling again at this time, the compilation error:

1
cannot use 0 (untyped int constant) as int value in return statement

In fact, the error message already tells us that int is not a built-in integer type, but the name of a type parameter, equivalent to our common T, K, V. It is confusing to use int as the name of a type parameter here.

So the answer is clear, Go 1.18 does not support generic specialization , so be careful not to fall into the hole.