Tracks
/
Go
Go
/
Temario
/
Valores cero
Va

Valores cero en Go

1 ejercicio

Acerca de Valores cero

En Go, toda variable tiene un valor. Declarar una variable sin asignarle un valor hace que tome el valor cero de su tipo.

Los tipos básicos, como bool, los tipos numéricos y string, tienen un valor cero fijo:

Tipo Valor cero
bool false
int, int8, int64, etc. 0
float32, float64 0
complex64, complex128 0+0i
string ""

Los tipos que referencian datos subyacentes, como punteros, funciones, interfaces, slices, canales y mapas, tienen nil como valor cero. Sin embargo, los arrays y las estructuras nunca son nil, porque contienen los datos directamente, no una referencia a ellos. Cada elemento de un array y cada campo de una estructura se inicializan con el valor cero de su propio tipo. Por ejemplo, var a [3]int crea el array [0, 0, 0].

Declarar valores cero

var sin un valor inicial da el valor cero para cualquier tipo:

var myBool bool   // false
var mySlice []int // nil
var p Person      // Person{Name: "", Age: 0}

Para las estructuras, un literal compuesto T{} es una alternativa:

myPerson := Person{} // equivalent to var myPerson Person

new(T) devuelve un puntero al valor cero de cualquier tipo. Se usa con más frecuencia con estructuras, aunque también funciona con tipos básicos:

p := new(Person) // *Person, pointing to Person{Name: "", Age: 0}
s := new(string) // *string, pointing to ""
i := new(int)    // *int, pointing to 0

Por qué importan los valores cero

En Go, un valor cero representa un estado inicial natural y útil.

Un bool toma false por defecto, lo que puede funcionar como una bandera:

var done bool // action not done yet
done = true   // action now done

Un entero toma 0 por defecto, lo que puede funcionar como un contador:

var count int
count++ // 1
count++ // 2

En las estructuras, cada campo comienza con el valor cero de su propio tipo. Un Stack con un único campo []string ya es una pila vacía funcional cuando se declara. Como append asigna un nuevo array subyacente cuando se llama sobre un slice nil, no se necesita un constructor:

type Stack struct {
    items []string
}

func (s *Stack) Push(v string) {
    s.items = append(s.items, v)
}

func (s *Stack) IsEmpty() bool {
    return len(s.items) == 0
}

var s Stack
fmt.Println(s.IsEmpty()) // true
s.Push("a") // append allocates a new backing array
fmt.Println(s.IsEmpty()) // false

Trabajar con nil

La mayoría de los tipos con valor cero nil requieren inicialización antes de usarse o entran en pánico. Un slice nil es la excepción: puedes recorrerlo con range, añadirle elementos con append y pasarlo a len y cap de forma segura.

Un mapa debe inicializarse antes de almacenar un valor:

var m map[string]int
m["key"] = 1 // panic

Un mapa se inicializa comúnmente de dos formas distintas:

m1 := make(map[string]int)
m2 := map[string]int{}
m1["key"] = 1 // ok
m2["key"] = 1 // ok

Comprueba si un puntero es nil antes de usarlo:

var p *int

if p == nil {
    fmt.Println("no value assigned")
    return
}

fmt.Println(*p) // p is not nil

Los tipos básicos siempre contienen un valor concreto, así que compararlos con nil es un error de compilación:

var myString string

if myString == nil {
    // compile error: mismatched types
}
Editar en GitHub El enlace se abre en una nueva ventana o pestaña

Aprende Valores cero