Tipos de datos compuestos
Los tipos de datos compuestos son aquellos que pueden almacenar uno o más valores. En Go existen diferentes tipos de datos compuestos, los que permiten almacenar uno o más valores de un solo tipo o aquellos que permiten almacenar uno o más valores de uno o más tipos diferentes.
Arrays
Los arrays son una secuencia de elementos numerados que nos permite almacenar valores de un mismo tipo con una longitud definida. Es decir, si queremos almacenr una serie de datos del mismo tipo usaríamos un array. Por ejemplo, para definir un array:
var arr [5]int
En el ejemplo anterior estamos definiendo una variable de tipo array con nombre arr
,
con una longitud de 5 elementos y cada de esos elementos tiene que ser de tipo int
.
Luego podemos llenar esa "serie" de datos de la siguiente manera:
arr[0] = 1
arr[1] = 2
arr[2] = 3
arr[3] = 4
arr[4] = 5
arr[5] = 6 // fallará
Como ya mencionamos anteriormente, los arrays son una serie de elementos numerados, por
este motivo podemos acceder al "índice" de cada elemento usando 0, 1, 2, 3, 4, dependiendo
de la longitud de nuestro array. Hay que tener en cuenta que en programación, todos los
índices empiezan a contar desde 0. Por este motivo la operación arr[5]
fallará ya que
nuestro array es de una longitud de 5 elementos y el índice 5 (que sería el elemento 6)
está fuera de nuestro rango.
Slices
Un slice
es un segmento de un array
. Igua que los arrays, los slices son indexados, es
decir, tienen una numeración desde que empieza desde el 0 y se extiende hasta su longitud-1.
También tienen una longitud pero a diferencia de los arrays
esta longitud puede variar.
Por ejemplo:
var slc []int
La única diferencia de esta declaración con la de un array
es que no definimos la
longitud dentro de los brakets []
. En este caso un slice
con longitud de 0 ha sido
creado.
Otra forma de crear un slice
es usando make
:
slc := make([]int, 5, 10)
slc[0] = 10
fmt.Println(slc[0]) // 10
En el ejemplo anterior estamos creando un slice
usando la función make
. El primer
argumento es el tipo de valores que queremos almacenar, el segundo es la longitud y el
tercero representa la capacidad que puede tener. Note que para acceder al valor en el
índice 0 usamos la notación slc[0]
donde 0 es el índice.
Otra forma de crear slice
es usando la notación [low : high]
:
arr := [5]int{1, 2, 3, 4, 5}
slc := arr[0:5]
fmt.Println()
En el ejemplo anterior primero tenemos un array
de 5 elementos. Luego, en la segunda
línea copiamos los elementos en un slice
usando la notación [low : high]
. El primer
element es el array
del que vamos a copiar, el 0 representa el índice desde donde
queremos empezar a copiar y el 5 representa el índice hasta donde queremos copiar. Si
quisieramos copiar todo el array
también podríamos usar arr[:]
de esta forma Go
sabría que queremos empezar desde el índice 0 hasta la longitud - 1.
Cómo ya mencionamos anteriormente, un slice
es similar a un array
pero con la
diferencia de que su longitud puede variar. ¿Por que deberíamos usar slices
en vez de
arrays? Por los métodos a los que tenemos acceso cuando usamos slice
.
Métodos de Slices
Go tiene muchos funciones construidas dentro del lenguaje, las que más usaremos para
manipular slices
son: append
y copy
.
El método append
crea un nuevo slice
y le agrega los elementos que pasemos como
argumento:
slc := []int{1, 2, 3, 4, 5}
newSlc := append(slc, 6, 7)
fmt.Println(newSlc) // 1, 2, 3, 4, 5, 6, 7
El método copy
copia los elementos de un slice
dentro de otro:
slc1 := []int{1, 2, 3, 4, 5}
slc2 := []int{6, 7}
copy(slc1, slc2)
fmt.Println(slc1) // 6, 7, 3, 4, 5
El resultado de ejecutar copy
es un poco raro, el motivo por el que copia 6 y 7 en
el índice 0 y 2 es por que slc1
solo tiene una longitud de 5 elementos, por los que
copy
intenta buscar donde puede copiar los nuevos elementos y los copia en los
primeros índices.
Map
Son una lista desordenada de llaves-valor
. También conocidos como un array
asociativo, un hash table
o diccionario. Se usan para buscar valores usando una
llave. Por ejemplo:
var x = map[string]int{}
En el ejemplo anterior estamos definiendo una variable x
que almacena un map cuya
llave debe ser un string
y su valor debe ser un int
. Al igual que los array
y
slice
, podemos usar la notación de brackets []
para acceder a un elemento de un
map
. Si queremos asignarle alguna llave valor a nuestro nuevo map
podemos usar:
var x = map[string]int {}
x["edad"] = 29
fmt.Println(x["edad"]) // 29
En el ejemplo anterior x["edad"]
se refiere a la llave "edad" y 29 es el valor.
En el print estamos usando x["edad"]
para acceder a el valor almacenado en la llave
"edad" e imprimirlo.
Puede parecer muy similar a un array
pero hay varias diferencias. En primer lugar,
la longitud de un map
va creciendo conforme vamos añadiendo más llaves-valor
.
Segundo, los map
no son secuenciales, es decir, no empiezan en el índice 0 y van
aumentando de 1, se podría decir que los índices en un map
son las llaves.
Si queremos verificar que existe un valor en una llave-valor en nuestro map
podemos
usar una de las siguientes maneras:
if x["edad"] == 0 {
fmt.Println("No existe")
}
Si el tipo del valor es int
la expresión x["edad"] retornará 0
, si es string retornará
""
, si es booleano retornará false
, etc. Esto es muy tedioso, así que podemos usar
una de las formas que nos provee Go para hacerlo más sencillo:
if edad, ok := x["edad"]; !ok {
fmt.Println("No existe")
}
En el ejemplo anterior podemos observar que estamos definiendo dos variables en una sola
línea, edad
y ok
, si x["edad"]
tiene un valor, se le asignará a la variable de edad
y ok
obtendrá el valor true
, si no existe, ok
obtendrá false. Justo después del ;
con el !ok
verificamos si ok
es true
o false
y ejecutamos lo que esté dentro del if
.
Para borrar un elemento de un map
podemos usar la función delete
:
delete(x, "edad")
Para recorrer un map
podemos usar:
for key, value := range x {
fmt.Println(key, value) // edad 29
}
En resumen
Existen diferentes tipos de datos compuestos, los arrays, slices nos permiten almacenar valores de forma ordenada y numerada y los maps nos permiten almacenar valores de una forma a la que podemos acceder facilmente a ellos.