|
You have to click through to read the assignability rules. A very short summary is that people often create new types based on core types. For example: type Name string
Now you can define methods on Name: func (n Name) Foo() { ... }
...
x := Name("Me")
x.Foo()
But, you can't use Name and string interchangeably: func StringFoo(x string) { ... }
StringFoo(Name("Me")) // does not compile
In the case of generics, maybe you want to write a function that can handle any string: func Bar[T string](x T) { ... }
Bar(Name("Me"))
Bar("Me")
This doesn't compile, because Name isn't assignable to string. The fix is to declare the type parameter as [T ~string]. (The compile error suggests this, in fact. You can also write string(Name("Me")) but if T were being used as the type of the return value, the returned value would be type string, not type Name.)In the case of slices, it can be more complicated. These types all seem similar, but aren't the same: []string
[]Name
type StringSlice []string
type NameSlice []Name
The idea of the article is figuring out how to write a generic type signature that would accept any of these and return the right type.Finally, you can rename types and use them interchangeably if you don't want the "safety" of making a new type: type Name = string
Now you can't write methods on Name, but you can use Name and string interchangably. (This, incidentally, is how "any" works. The package builtin contains "type any = interface{}".)If the complaint about syntax is not using <T type> to denote type parameters like Java and C++, [] simplifies the parser. You can read the original generics proposal for all the details. |