Go emplea una técnica intermedia entre la monomorfización completa de Rust o C++ y la borradura de tipos de Java para implementar los genéricos introducidos en Go 1.18: el GC shape stenciling. En lugar de generar una copia del código genérico por cada tipo concreto, el compilador agrupa los tipos según su GC shape, es decir, su tamaño, alineación y disposición de punteros vista por el recolector de basura. Tipos con la misma forma comparten un único cuerpo compilado.
La regla práctica es que dos tipos comparten forma solo si tienen el mismo tipo subyacente, con una excepción: todos los tipos puntero (User, Order, etc.) comparten una forma común llamada *uint8. Esto reduce el número de cuerpos compilados, pero hace que el código genérico pierda el tipo exacto en tiempo de ejecución.
Para recuperar esa información, el compilador añade a cada llamada un argumento oculto llamado dictionary: una tabla fija con descriptores de tipo y metadatos específicos que el cuerpo compilado puede consultar cuando necesita operar sobre el tipo concreto. Así, una función genérica instanciada con User, Order, float64 e int genera tres cuerpos (uno para int, otro para float64 y otro compartido por los punteros) pero cuatro dictionaries, uno por cada tipo original.
El artículo contrasta este enfoque con la monomorfización de Rust, que produce una versión por cada argumento de tipo, y con la borradura de Java, que mantiene un único cuerpo a costa de casts y boxing. GC shape stenciling busca un equilibrio entre el coste de compilación y el rendimiento en ejecución, trasladando parte de la información de tipo a los dictionaries cuando hace falta.
