1) there are no parameters on the container types, every usage involves a cast to or from 'void*', 'interface{}', or the equivalent, and usage is effectively not type-checked.
2) there are parameters on the container types, subsequent usage isn't cluttered up with uninformative type-casts, and the types get checked by the compiler.
These lead to the same code at runtime (or can, in a Java-style implementation of generics); however, the Go maintainers seem to act as if the first is more maintainable and less error-prone. That seems ... odd, to some of us.
(There are other possible implementations of generics, of course. In fact, another post by the same author, [1], lists "everything is boxed" as a bad outcome that he'd like to avoid, in favor of specialized implementations for containers of, say, characters. But scenario 1, the Go status quo, effectively requires that everything be boxed when using a generic container type written the only way the language allows you to write them. Scenario 2 at least potentially gives the compiler other options. But the Go status quo doesn't avoid the "everything is boxed" bad outcome. Instead it mandates it -- with additional compile-time clutter.)
However, if I had a penny for every time I've taken advantage of the generic collections built into the standard library, instead of using the old shitty, type-unsafe ArrayList or HashTable collections, I wouldn't have to work for the rest of my life.
.Net generics are more limited than full C++ style templates, or maybe I've been lucky enough to never encounter any code where people have gone overboard with them, but that seems to be a pretty sweet spot.
I do not know of any studies that explore this concept at large. I would be interested in them.