En el paquete sync del lenguaje Go, tipos como sync.Mutex, sync.Once y sync.Map incluyen un campo especial de tipo noCopy que marca valores que no deben copiarse tras su primer uso. Pero ese marcador, un struct vacío con dos métodos también vacíos llamados Lock y Unlock, no impide la copia por sí solo: el compilador lo permite sin objección. La advertencia procede de go vet, una herramienta de análisis estático incluida con Go, y más concretamente de su checker copylocks.
El mecanismo es sutil: copylocks no busca un campo llamado noCopy. Recorre recursivamente los campos del tipo copiado y aplica una regla basada en la interfaz sync.Locker. Si el puntero al tipo implementa sync.Locker pero el valor no, lo señala como sospechoso. Como *noCopy implementa Lock y Unlock pero noCopy como valor no, cumple la regla. Por eso los métodos del marcador se llaman exactamente Lock y Unlock.
El marcador noCopy fue añadido a la biblioteca estándar en 2016 por Aliaksandr Valialkin, CTO de VictoriaMetrics, siguiendo un patrón propuesto por Russ Cox. En 2018 se le añadió Unlock cuando copylocks pasó a verificar la interfaz sync.Locker.
Incluir _ noCopy en tipos como sync.Map cumple tres funciones: hace explícita la restricción, produce un mensaje de error más claro (que nombra noCopy en lugar del mutex interno) y corrige un falso negativo con tipos definidos como LocalMutex a partir de sync.Mutex, que pierden los métodos Lock y Unlock y, sin el marcador, pasaban la comprobación.
Al ser noCopy un tipo no exportado, los paquetes externos pueden definir su propia versión. Aun así, copylocks no se ejecuta por defecto con go test, por lo que conviene lanzarlo explícitamente con go vet ./... o go test -vet=copylocks ./... para detectar copias accidentales en código y CI.
