Pasar por referencia es algo del lenguaje, nada en Go es "pasar por referencia". Pasar por referencia significa que el operador de asignación puede cambiar el valor original cuando se usa solo. Sin embargo, hay tipos de referencia como mapas y punteros que apuntan a alguna parte. El uso del operador de asignación en ellos no modificará el original a menos que use otros operadores, como el índice del mapa y el operador *
.
Tiene la certeza de que su mapa m
es un tipo de referencia y, por lo tanto, como un puntero. Cualquier cambio en el mapa, excepto la sustitución del mapa, modificará el original.
m["whatever"] = 2 // Modifies the original map
m = anothermap // Does not modify the original map
Si había verdadero "paso por referencia", el segundo ejemplo modificaría el mapa original.
Al pasar un puntero, como lo hace con dog
le permite modificar el original. Si llama a cualquier método de puntero o utiliza el operador *
, el original cambiará. En su ejemplo, un puntero puede no haber sido necesario. Si Dog
es pequeño, puede ser más fácil simplemente pasar una copia. Depende del programador determinar cuándo es un buen momento para usar un puntero.
Set
no se ha pasado por referencia. Las interfaces no son referencias. Si bien es cierto que internamente en el compilador 6g una interfaz utiliza punteros, la interfaz en sí misma no actúa como tal. Pasar una interfaz, sin importar el tamaño del objeto que contiene, es tan barato como pasar un puntero usando el compilador 6g. Sin embargo, no hay forma de modificar el valor original de una interfaz como lo hace con punteros y mapas.
Aunque no puede modificar la interfaz original aprobada, la interfaz puede contener un tipo de puntero. En ese caso, actuaría igual que el puntero del perro, donde la invocación de ciertos métodos puede modificar el original. Para su interfaz particular Set
, supongo que contiene un tipo de puntero basado en los nombres del método. Por lo tanto, cuando llame al set.Add(whatever)
, cambiará los datos internos del original.