🐢Variable - Tipos de Datos
Que son las variables y por consiguiente los tipos de datos, ¿cuales hay en go? ¿que tipos de datos se usan más frecuentes? etc...
Referencia:
Tipos de Datos en Go (Golang) ->
En Go, hay varios tipos de datos disponibles, que se pueden clasificar en cuatro categorías principales:
Tipos de datos básicos:
bool
: representa un valor booleano (true
ofalse
).string
: representa una cadena de texto.int
: representa un número entero.float32
yfloat64
: representan números en coma flotante.
Tipos de datos compuestos:
array
: representa una colección de elementos del mismo tipo.slice
: es similar a un array, pero su tamaño puede ser modificado dinámicamente.map
: representa una colección de pares clave-valor.struct
: representa un conjunto de campos con diferentes tipos de datos.
Tipos de datos de referencia:
pointer
: representa la dirección de memoria de una variable.function
: representa una función.interface
: define un conjunto de métodos que una estructura debe implementar.
Tipos de datos especiales:
chan
: se utiliza para la comunicación entre goroutines.complex64
ycomplex128
: representan números complejos.
Código ejemplificando un poco del curso Udemy →
package main
import (
"fmt"
)
func main() {
var nombreVar int //Esta es una forma de declarar una variable en Go.
var nombreDecimal float64 //Decimal de tipo float64 bits
var nombreTexto string //string de tipo string
var nombreBool bool //variable de tipo booleana false or true
nombreVar = 7
nombreDecimal = 6.9
nombreTexto = "Hola Mundo :)"
nombreBool = true
//Forma de declarar una variable sin definir el tipo de dato -> con ":="
nombreNumero := 10
fmt.Println(nombreVar, nombreDecimal, nombreTexto, nombreBool)
fmt.Println(nombreNumero)
}
No se puede redefinir el valor de una variable luego de haber sido definida →
No se puede redefinir el valor de una variable luego de haber sido definida →
Es importante tener en cuenta que los tipos de datos básicos en Go son valores inmutables. Esto significa que una vez que se define su valor, no se puede cambiar. Si se desea actualizar el valor de una variable, se debe crear una nueva variable con el nuevo valor.
Linea 19 con Linea 24
Lo mismo pasa con querer intentar cambiar el tipo de dato de una variable que ya ha sido definida su tipo de dato, no se puede redefinir.

Tipos de datos compuestos en Go
uint8 unsigned 8-bit integers (0 to 255)
uint16 unsigned 16-bit integers (0 to 65535)
uint32 unsigned 32-bit integers (0 to 4294967295)
uint64 unsigned 64-bit integers (0 to 18446744073709551615)
int8 signed 8-bit integers (-128 to 127)
int16 signed 16-bit integers (-32768 to 32767)
int32 signed 32-bit integers (-2147483648 to 2147483647)
int64 signed 64-bit integers (-9223372036854775808 to 9223372036854775807)
float32 IEEE-754 32-bit floating-point numbers
float64 IEEE-754 64-bit floating-point numbers
complex64 complex numbers with float32 real and imaginary parts
complex128 complex numbers with float64 real and imaginary parts
byte alias for uint8
rune alias for int32
uint8: 100
uint16: 50000
uint32: 1000000000
uint64: 100000000000000
int8: -50
int16: -20000
int32: -100000000
int64: 100000000000000
Desglose de los otros tipos:
float32
: Representa números de punto flotante de 32 bits.float64
: Representa números de punto flotante de 64 bits, que tienen mayor precisión.complex64
: Representa números complejos con partes reales e imaginarias de tipofloat32
.complex128
: Representa números complejos con partes reales e imaginarias de tipofloat64
.byte
: Es un alias parauint8
, que puede contener valores de 0 a 255.rune
: Es un alias paraint32
, que se utiliza para representar un carácter Unicode. En el ejemplo,'A'
es el carácter que corresponde al valor 65 en Unicode.
En Go, los tipos de datos compuestos son tipos de datos que están formados por la combinación de uno o más valores de tipos de datos básicos.
El propósito del alias byte
es dejar claro el momento en que el programa usa bytes a modo de medición informática común en elementos de cadenas de caracteres, en contraposición a enteros pequeños no relacionados con la medición de datos de byte. Aunque byte
y uint8
son idénticos una vez que se compila el programa, byte
se utiliza a menudo para representar datos de caracteres en formato numérico, mientras que uint8
está diseñado para ser un número en su programa.
El alias rune
es un poco diferente. Si bien byte
y uint8
contienen exactamente los mismos datos, un rune
puede ser de un solo byte o de cuatro, un rango determinado por int32
. Un rune
se utiliza para representar un carácter Unicode, mientras que solo los caracteres ASCII se pueden representar únicamente con un tipo de datos int32
.
Los tipos de datos compuestos disponibles en Go son
Array: este tipo de datos representa una colección de elementos del mismo tipo. Los arrays en Go tienen una longitud fija que se define en el momento de la creación del array.
// Declarar un array de tipo entero var numeros [5]int = [5]int{1, 2, 3, 4, 5} numeros2 := [2]int{1, 6} // Imprimir el valor de un elemento del array fmt.Println("Número 3:", numeros[2]) fmt.Println("Número 6:", numeros[1])
Slice: este tipo de datos es similar a un array, pero su tamaño puede ser modificado dinámicamente. Un slice se crea a partir de un array y se puede acceder a sus elementos utilizando la misma sintaxis que un array.
// Declarar un slice de tipo entero var numeros3 []int = []int{1, 2, 3, 4, 5} numeros33 := []int{11, 24, 36} seaCreatures := []string{"shark", "cuttlefish", "squid", "mantis shrimp"} []float64{3.14, 9.23, 111.11, 312.12, 1.05} []string{"shark", "cuttlefish", "squid", "mantis shrimp"} // Agregar un nuevo elemento al slice numeros33 = append(numeros33, 190) // Imprimir el valor de un elemento del slice fmt.Println("Número 4:", numeros3[3]) fmt.Println("Número 190:", numeros33[3])
Map: este tipo de datos representa una colección de pares clave-valor. Cada clave en el mapa debe ser única y el valor asociado puede ser de cualquier tipo de datos. Por ejemplo:
La regla de oro es:
Usar
make
para slices, maps y channels y new para valors numéricos, structs etc.
// Declarar un map con claves de tipo cadena y valores de tipo entero var edades map[string]int = make(map[string]int{"Juan": 28, "Ana": 30}) // Imprimir el valor asociado a una clave en el map fmt.Println("Edad de Ana:", edades["Ana"])
Comprobación de la existencia de una clave:Se puede comprobar si una clave existe en un mapa utilizando la función
len
._, ok := m["clave5"] if ok { // La clave existe } else { // La clave no existe } Lenguaje del código: Go (go)
Recorrer un mapa:Se puede recorrer un mapa utilizando un bucle
for
.for clave, valor := range m { fmt.Println(clave, valor) }
Struct: este tipo de datos representa un conjunto de campos con diferentes tipos de datos. Las estructuras se utilizan para agrupar diferentes tipos de datos en una única variable.
// Declarar una estructura con diferentes campos type Persona struct { nombre string edad int altura float64 } // Declarar una variable de tipo Persona var persona1 Persona = Persona{"Juan", 28, 1.75} // Imprimir el valor de un campo de la estructura fmt.Println("Edad de", persona1.nombre, ":", persona1.edad)
Es importante tener en cuenta que los tipos de datos compuestos en Go se utilizan para representar datos más complejos y estructurados en un programa.
Los arrays, slices, maps y struct se utilizan para agrupar diferentes tipos de datos en una única variable.
Matrices: Una matriz es una secuencia ordenada de elementos. La capacidad de una matriz se define en el momento de su creación. Una vez que se asigna el tamaño a una matriz, este ya no se puede cambiar. Debido a que el tamaño de una matriz es estático, significa que se asigna memoria solo una vez. Esto hace que el trabajo con matrices resulte un tanto rígido, pero aumenta el rendimiento de su programa. Debido a esto, las matrices suelen utilizarse al optimizar programas. Los segmentos, que veremos a continuación, son más flexibles y constituyen lo que se podría considerar como matrices en otros lenguajes.
Las matrices se definen al declarar el tamaño de estas y luego el tipo de datos con los valores definidos entre llaves
{ }
.Una matriz de cadenas tiene el siguiente aspecto:
var matriz [3][3]int = [3][3]int{ {1, 2, 3}, // Fila 1 {4, 5, 6}, // Fila 2 } [3][3]string{ {"blue coral", "staghorn coral", "pillar coral"}, {"Cadena 4", "Cadena 5", "Cadena 6"}, } //Tambien se puede almacenar una matriz en una variable e imprimirla: matriz := [2][3]string{ {"blue coral", "staghorn coral", "pillar coral"}, {"Cadena 4", "Cadena 5", "Cadena 6"}, } fmt.Println(matriz)
Como ya lo mencioné anteriormente, los segmentos son similares a las matrices, pero son mucho más flexibles. Veamos este tipo de datos mutable.
Tipos de datos de referencia en GO
Function
:
Function
:este tipo de datos representa una función. Las funciones en Go son tipos de datos de primera clase, lo que significa que se pueden asignar a variables y pasar como argumentos a otras funciones, y que ademas dentro de la función se puede contener una cantidad de código que hará algo en especifico según la logica que se lleve.
Algo importante por saber en Go: El nombre de la función en Go debe comenzar con una letra minúscula para funciones no exportadas (privadas) o mayúscula para funciones exportadas (públicas), aqui lo noté porque cuando llamaba por fuera del main con minuscula no podía llamarse a la funcion pero cuando le cambiaba a MAY la primera letra ahi si se definía la function como publica.
Si el nombre de la función o variable comienza con minúscula, será privada al paquete donde se define. Solo puede ser accedida desde dentro de ese mismo paquete.
Si el nombre comienza con mayúscula, será exportada (pública) y puede ser accedida desde otros paquetes.
Por ejm: Declarar una funcion que sume 2 numeros:
package main import "fmt" // Declarar una función que suma dos números func Suma(a,b int) int{ return a + b } func main(){ //Asignar la función a una variable var funcionSuma = Suma //Llamar a la función a través de la variable resultado := funcionSuma(1,3) //Return 5 //Imprimir resultado fmt.Println("Resultado Suma: ", resultado) }
Pointer
💀
Pointer
💀Este tipo de datos representa la dirección de memoria de una variable. Los punteros se utilizan para acceder y manipular el valor de una variable indirectamente, a través de su dirección de memoria.
Uso del&
y*
&
: Lo usas para obtener la dirección de memoria de una variable. Es como decir: "Dame la ubicación donde está este valor en la memoria."*
: Lo usas para acceder al valor que está almacenado en esa dirección. Una vez que tienes la dirección (guardada en el puntero), puedes "desreferenciarla" con*
para obtener el valor real en esa ubicación.x := 42 // `x` tiene el valor 42 p := &x // `p` guarda la dirección de memoria de `x` fmt.Println(*p) // `*p` accede al valor en la dirección, que es 42
Primero usas
&
para obtener la dirección (el puntero) y luego usas*
para acceder al valor en esa dirección.
Rapidez: El puntero no necesita "buscar" el valor en la memoria una vez que tiene la dirección. Es más rápido acceder directamente a un valor a través de su puntero, especialmente cuando trabajas con estructuras grandes o datos en lugares específicos de la memoria.
En resumenEl puntero (
*
) guarda la dirección de memoria donde está un valor, no el valor mismo.El operador
&
obtiene la dirección de memoria de una variable.El operador
*
desreferencia el puntero para acceder al valor en esa dirección.Eficiencia: Usar punteros es útil para evitar copias innecesarias de grandes estructuras o arreglos, haciendo el acceso a los datos más rápido y eficiente.
En Go, cuando se recibe un argumento como puntero se suele comprobar si es nulo o no antes de realizar cualquier operación en él para evitar excepciones en el programa.
Esta técnica se usa con frecuencia para comprobar la presencia de nil
:
if someVariable == nil {
// print an error or return from the method or fuction
}
Interfaces
:
Interfaces
:Este tipo de datos define un conjunto de métodos que una estructura debe implementar. Las interfaces se utilizan para definir un comportamiento común que se puede compartir entre diferentes tipos de estructuras.
Lo que hace una interfaz es poder definir un conjunto de metodos que podemos usar para una estructura en su implementacion, basicamente poder integrarle metodos a una estructura mediante la interfaz.
// Declarar una interfaz que define un método para obtener el área
type Figura interface {
Area() float64
}
// Declarar una estructura de tipo rectángulo
type Rectangulo struct {
ancho float64
alto float64
}
// Declarar una estructura de tipo círculo
type Circulo struct {
radio float64
}
// Implementar el método para obtener el área del rectángulo
func (r Rectangulo) Area() float64 {
return r.ancho * r.alto
}
// Implementar el método para obtener el área del círculo
func (c Circulo) Area() float64 {
return 3.1416 * c.radio * c.radio
}
// Declarar una función que recibe una figura y calcula su área
func ObtenerArea(figura Figura) float64 {
return figura.Area()
}
// Crear una variable de tipo rectángulo y calcular su área
rectangulo := Rectangulo{ancho: 2, alto: 4}
areaRectangulo := ObtenerArea(rectangulo) //area: 8
// Crear una variable de tipo círculo y calcular su área
circulo := Circulo{radio: 3}
areaCirculo := ObtenerArea(circulo)
// Imprimir las áreas de las figuras
fmt.Println("Área del rectángulo:", areaRectangulo)
fmt.Println("Área del círculo:", areaCirculo)
Es importante tener en cuenta que los tipos de datos de referencia en Go se utilizan para representar datos que no están directamente almacenados en una variable, sino que se encuentran en una ubicación de memoria separada.
Los punteros se utilizan para acceder a la ubicación de memoria y manipular el valor de una variable indirectamente. Las funciones se utilizan para encapsular un comportamiento y reutilizarlo en diferentes partes del programa.
Las interfaces se utilizan para definir un comportamiento común que se puede compartir entre diferentes tipos de estructuras.
Last updated