Translate

lunes, 23 de octubre de 2023

Asignación con new en Go


Go tiene dos primitivas de asignación de memoria, las funciones integradas new y make. Hacen cosas diferentes y se aplican a diferentes tipos, lo que puede resultar confuso, pero las reglas son simples. Hablemos primero de new. Es una función incorporada que asigna memoria, pero a diferencia de sus homónimos en otros lenguajes, no inicializa la memoria, solo la pone a cero. Es decir, new(T) asigna almacenamiento puesto a cero para un nuevo elemento de tipo T y devuelve su dirección, un valor de tipo *T. En la terminología de Go, devuelve un puntero a un valor cero recién asignado de tipo T.

Dado que la memoria devuelta por new se pone a cero, es útil disponer al diseñar las estructuras de datos que el valor cero de cada tipo se pueda usar sin inicialización adicional. Esto significa que un usuario de la estructura de datos puede crear una nueva y ponerse manos a la obra. Por ejemplo, la documentación de bytes.Buffer indica que "el valor cero de Buffer es un búfer vacío listo para usar". De manera similar, sync.Mutex no tiene un constructor explícito ni un método Init. En cambio, el valor cero para sync.Mutex se define como un mutex desbloqueado.

La propiedad del valor cero es útil funciona de forma transitiva. Considere este tipo de declaración.


type SyncedBuffer struct {

    lock    sync.Mutex

    buffer  bytes.Buffer

}


Los valores de tipo SyncedBuffer también están listos para usar inmediatamente después de la asignación o simplemente de la declaración. En el siguiente fragmento, tanto p como v funcionarán correctamente sin más arreglos.


p := new(SyncedBuffer)  // type *SyncedBuffer

var v SyncedBuffer      // type  SyncedBuffer