Skip to content

Arreglos en Go

Posted on:December 17, 2020 at 05:10 PM

Table of Contents

Open Table of Contents

Introducción

Los Arreglos son aggregate types; sus valores son agrupaciones de otros valores en memoria. Los Arreglos son homogéneos (sus elementos son del mismo tipo). Los Arreglos son de tamaño fijo.

¿Qué es un Arreglo?

Como mencioné anteriormente un Arreglo es una secuencia de cero o más elementos de un tipo en particular y de tamaño fijo. Debido a que son de tamaño fijo, los arreglos son rara vez utilizados en programas escritos en Go. Los slices (hablaré de slices en otro post), los cuales pueden crecer y reducirse son más versátiles, pero para entender los slices primero tenemos que entender los arreglos.

Trabajando con Arreglos

Para acceder a elementos individuales de un arreglo usamos la notación convencional de subscript, donde los subscripts van desde cero hasta el tamaño del arreglo menos uno. La función preconstruida len regresa el número de elementos en el arreglo.

package main

import "fmt"

func main()  {
  var a [3]int // arreglo de 3 enteros
  fmt.Println(a[0]) // imprime el primer elemento
  fmt.Println(a[len(a)-1]) // imprime el último elemento, a[2]
}

Por defecto, los elementos de un nuevo arreglo son inicializados con su respectivo valor cero.

package main

import "fmt"

func main()  {
  var a [3]int
  var b [3]string
  fmt.Println(a) // [0, 0, 0]
  fmt.Println(b) // ['', '', '']
}

Podemos usar un arreglo literal para inicializar un arreglo con una lista de valores.

package main

import "fmt"

func main()  {
  var ages [3]int = [3]int{10, 20, 30}
  var languages [3]string = [3]string{"go", "php"}
  fmt.Println(ages) // [10, 20, 30]
  fmt.Println(languages[2]) // ''
}

En un arreglo literal, si están presente los ellipsis ”…” en lugar de la longitud, la longitud del arreglo es determinada por el número de elementos que este contenga.

package main

import "fmt"

func main()  {
  ages := [...]int{10, 20, 30} // usando ellipsis "..."
  fmt.Println(ages) // [10, 20, 30]
  fmt.Println(len(ages)) // 3
  fmt.Printf("%T\n", ages) // [3]int
}

El tamaño del arreglo es parte de su tipo, [3]int y [4]int son tipos diferentes.

package main

func main()  {
  ages := [3]int{10, 20, 30}
  ages = [4]int{10, 20, 30, 40} // cannot use [4]int literal (type [4]int) as type [3]int in assignment
}

El tamaño debe de ser una expresión constante, es decir, un valor que pueda ser calculado mientras el programa es compilado.

package main

import "fmt"

func main() {
	var length int
	fmt.Println("Ingresa la longitud del arreglo: ")
	fmt.Scanf("%d", &length)
	var ages [length]int // non-constant array bound length
}

También es posible especificar una lista de pares en forma de index y valor.

package main

import "fmt"

type Language int

const (
	EN Language = iota
	FR
	ES
	DE
)

func main() {
	symbol := [...]string{
		EN: "English",
		FR: "French",
		ES: "Spanish",
		DE: "German",
	}

	fmt.Println(ES, symbol[ES]) // 2 Spanish
}

Los índices pueden aparecer en cualquier orden y algunos pueden ser omitidos; como mencioné antes, los valores no especificados tomarán su valor cero de acuerdo al tipo del elemento.

package main

import "fmt"

func main() {
  ages := [...]int{10: 12}
  fmt.Println(ages) // [0 0 0 0 0 0 0 0 0 0 12]
}

Si el tipo de los elementos de un arreglo son comparables, entonces el tipo del arreglo también es comparable, por lo tanto, podríamos comparar directamente dos arreglos del mismo tipo usando el operador de comparación ==, el cual nos dirá si todos los elementos son iguales.

package main

import "fmt"

func main() {
  a := [2]int{1, 2}
  b := [...]int{1, 2}
  c := [2]int{1, 3}
  fmt.Println(a == b, a == c, b == c) // true false false

  d := [3]int{1, 2}
  fmt.Println(a == d) // invalid operation: a == d (mismatched types [2]int and [3]int)
}

Conclusión

En próximos posts aprenderémos sobre slices los cuales son más utilizados en Go y más versátiles. Hasta la próxima 👋🏽.