1 Introducción a los tipos de datos en el lenguaje Go
En el lenguaje Go, los tipos de datos son la base de la programación, determinando la forma de los datos que las variables pueden almacenar. Los tipos de datos básicos proporcionados por el lenguaje Go se dividen principalmente en las siguientes categorías:
Tipo de dato | Descripción | Uso de memoria |
---|---|---|
bool | Tipo booleano, utilizado para almacenar verdadero o falso | 1 byte |
int, uint | Enteros con y sin signo, el tamaño predeterminado depende de la plataforma del sistema | 4 o 8 bytes |
int8, uint8 | Enteros con y sin signo de 8 bits | 1 byte |
int16, uint16 | Enteros con y sin signo de 16 bits | 2 bytes |
int32, uint32 | Enteros con y sin signo de 32 bits | 4 bytes |
int64, uint64 | Enteros con y sin signo de 64 bits | 8 bytes |
float32 | Número de punto flotante de 32 bits | 4 bytes |
float64 | Número de punto flotante de 64 bits | 8 bytes |
complex64 | Número complejo con partes reales e imaginarias de 32 bits | 8 bytes |
complex128 | Número complejo con partes reales e imaginarias de 64 bits | 16 bytes |
byte | Similar a uint8 | 1 byte |
rune | Similar a int32, representa un punto de código Unicode | 4 bytes |
string | Tipo cadena de texto | Dependiente de la longitud de la cadena |
error | Interfaz de error, utilizada para devolver información de error | Sin tamaño fijo |
Estos tipos pueden ser elegidos según diferentes necesidades, como cálculos numéricos, procesamiento de texto o control lógico.
2 Tipos de datos enteros
2.1 Visión general de los tipos enteros
El lenguaje Go tiene varios tipos enteros incorporados, clasificados de la siguiente manera:
- Enteros con signo:
int8
,int16
,int32
(orune
),int64
, eint
- Enteros sin signo:
uint8
(obyte
),uint16
,uint32
,uint64
, yuint
Los tamaños de int
y uint
son de 4 bytes en sistemas de 32 bits y de 8 bytes en sistemas de 64 bits. Los rangos de valores de los tipos de datos enteros se muestran en la siguiente tabla:
Tipo | Rango de valores |
---|---|
int8 | -128 a 127 |
uint8 | 0 a 255 |
int16 | -32768 a 32767 |
uint16 | 0 a 65535 |
int32 | -2147483648 a 2147483647 |
uint32 | 0 a 4294967295 |
int64 | -9223372036854775808 a 9223372036854775807 |
uint64 | 0 a 18446744073709551615 |
2.2 Uso de variables enteras
La sintaxis básica para declarar una variable entera es la siguiente:
var nombre_variable tipo_de_dato = valor_inicial
Código de ejemplo:
package main
import "fmt"
func main() {
var a int = 10 // Variable entera con signo
var b uint = 20 // Variable entera sin signo
var c int8 = -128 // Valor más pequeño de int8
fmt.Println(a, b, c)
}
2.3 Operaciones enteras
El lenguaje Go soporta operadores aritméticos comunes, como la suma (+
), resta (-
), multiplicación (*
), división (/
), y módulo (%
), así como operadores a nivel de bits como el AND a nivel de bits (&
), OR (|
), XOR (^
), desplazamiento a la izquierda (<<
), y desplazamiento a la derecha (>>
).
package main
import "fmt"
func main() {
x := 10
y := 3
// Operaciones aritméticas
fmt.Println(x + y) // Suma
fmt.Println(x - y) // Resta
fmt.Println(x * y) // Multiplicación
fmt.Println(x / y) // División
fmt.Println(x % y) // Módulo
// Operaciones a nivel de bits
fmt.Println(x & y) // AND a nivel de bits
fmt.Println(x | y) // OR a nivel de bits
fmt.Println(x ^ y) // XOR a nivel de bits
fmt.Println(x << 1) // Desplazamiento a la izquierda por 1
fmt.Println(x >> 1) // Desplazamiento a la derecha por 1
}
3 Tipos de datos de punto flotante
3.1 Visión general de los tipos de datos de punto flotante
En el lenguaje Go, los tipos de punto flotante incluyen float32
y float64
, correspondientes a datos de punto flotante de 32 bits y 64 bits. En general, se recomienda utilizar float64
ya que proporciona un rango más grande y una precisión más precisa.
-
float32
tiene aproximadamente 23 bits significativos, lo que proporciona alrededor de 7 dígitos decimales de precisión. -
float64
tiene aproximadamente 52 bits significativos, lo que proporciona alrededor de 16 dígitos decimales de precisión.
3.2 Uso de variables de punto flotante
Las variables de punto flotante se pueden declarar directamente proporcionando literales o utilizando la palabra clave var
:
package main
import "fmt"
func main() {
var f1 float32 = 3.14 // Especificar explícitamente el tipo float32
f2 := 3.14 // Inferido automáticamente como tipo float64
fmt.Println(f1, f2)
}
3.3 Aritmética de punto flotante y problemas
La aritmética de punto flotante puede llevar a la pérdida de precisión. Realizar operaciones con una precisión muy alta es un problema común, especialmente al restar dos números muy cercanos.
package main
import "fmt"
func main() {
f1 := .1
f2 := .2
f3 := f1 + f2
fmt.Println(f3) // La salida puede no ser el .3 esperado debido a problemas de precisión
// Solucionar problemas de precisión utilizando salida formateada
fmt.Printf("%.1f\n", f3) // Salida corregida a .3
}
4 Tipo de dato booleano
4.1 Visión general del tipo de dato booleano
Booleano es el tipo de dato más simple y solo puede tener dos valores: true
(verdadero) y false
(falso). Ocupa una posición muy importante en las declaraciones condicionales y las estructuras de control de bucles.
4.2 Uso de variables booleanas
Declarar y usar variables booleanas:
package main
import "fmt"
func main() {
var exito bool = true
var fallido bool = false
fmt.Println("Operación exitosa:", exito)
fmt.Println("Operación fallida:", fallido)
}
Los valores booleanos a menudo se utilizan en declaraciones condicionales:
package main
import "fmt"
func main() {
a := 10
b := 20
fmt.Println("a == b:", a == b) // falso
fmt.Println("a < b:", a < b) // verdadero
}
5 Tipo de dato cadena
5.1 Visión general de la cadena
Una cadena es una colección de caracteres. En el lenguaje Go, las cadenas son inmutables. Cada cadena consta de dos partes: un puntero al arreglo de bytes subyacente y una longitud. Las cadenas pueden contener cualquier dato, incluidos bytes.
5.2 Uso de variables de cadena
Las variables de cadena generalmente se declaran utilizando comillas dobles "
para crear, pero también puedes usar comillas invertidas ` para crear cadenas de varias líneas:
package main
import "fmt"
func main() {
var s1 string = "hola"
s2 := "mundo"
s3 := `Esto es una
cadena de
varias líneas`
fmt.Println(s1)
fmt.Println(s2)
fmt.Println(s3)
}
Una vez que se crea una cadena, su contenido no se puede cambiar. La siguiente operación es ilegal y provocará un error de compilación:
s := "hola"
s[] = 'H` // Error de compilación: el contenido de la cadena es inmutable
5.3 Operaciones de cadena
Las cadenas son muy comunes e importantes en la programación. El lenguaje Go proporciona un conjunto rico de funciones integradas para la manipulación de cadenas. Aquí tienes algunas operaciones comúnmente utilizadas.
5.3.1 Concatenación de cadenas
En el lenguaje Go, puedes usar el operador más (+
) para concatenar cadenas, que es el método más directo. Además, al tratar con la concatenación frecuente de múltiples cadenas, se recomienda utilizar strings.Builder
para un mejor rendimiento.
package main
import (
"fmt"
"strings"
)
func main() {
// Concatenar cadenas utilizando +
hola := "¡Hola, "
mundo := "Mundo!"
resultado := hola + mundo
fmt.Println(resultado) // Salida: ¡Hola, Mundo!
// Concatenar cadenas utilizando strings.Builder
var sb strings.Builder
sb.WriteString("¡Hola, ")
sb.WriteString("Mundo!")
fmt.Println(sb.String()) // Salida: ¡Hola, Mundo!
}
5.3.2 División de cadenas
La división de cadenas se puede realizar utilizando la función strings.Split
, la cual divide la cadena en una lista basada en el delimitador especificado.
paquete principal
import (
"fmt"
"strings"
)
func main() {
// Definir una cadena
oración := "Go es un lenguaje de programación de código abierto"
// Dividir la cadena por el espacio
palabras := strings.Split(oración, " ")
para _, palabra := rango palabras {
fmt.Printf("%s\n", palabra)
}
// Salida:
// Go
// es
// un
// lenguaje
// de
// programación
// código
// abierto
}
5.3.3 Acceso por índice
En Go, una cadena es una secuencia inmutable de bytes. Puedes usar índices para acceder a bytes específicos en una cadena. Sin embargo, es importante tener en cuenta que debido a que una cadena puede contener caracteres de varios bytes (como caracteres codificados en UTF-8), acceder directamente a ellos puede no devolver el carácter único esperado.
paquete principal
import "fmt"
func main() {
s := "Hola, 世界"
para i := 0; i < len(s); i++ {
fmt.Printf("%d: %x\n", i, s[i])
}
// Nota: esto mostrará la representación hexadecimal de los bytes, no los caracteres
}
Para iterar a través de la cadena por carácter, puedes usar el bucle range
.
paquete principal
import "fmt"
func main() {
s := "Hola, 世界"
para índice, valorRune := rango s {
fmt.Printf("%d: %U '%c'\n", índice, valorRune, valorRune)
}
// Salida: índice, codificación Unicode y el carácter en sí para cada carácter
}
5.3.4 Obteniendo la longitud
La función len
puede obtener la longitud de una cadena, es decir, la longitud de la secuencia de bytes subyacente. Para cadenas UTF-8, si necesitas obtener el número de caracteres (runas), debes usar la función utf8.RuneCountInString
. Esto puede manejar correctamente los caracteres de varios bytes.
paquete principal
import (
"fmt"
"unicode/utf8"
)
func main() {
s := "Hola, 世界"
fmt.Println("Longitud en bytes:", len(s)) // Muestra la longitud de bytes
fmt.Println("Longitud en runas:", utf8.RuneCountInString(s)) // Muestra la longitud de caracteres
}
Desde el ejemplo anterior, podemos ver que el lenguaje Go proporciona funciones de biblioteca completas para operaciones de cadena, facilitando la realización de diversas tareas de procesamiento de cadenas. Al codificar, es importante prestar atención a la distinción entre bytes y caracteres, especialmente al tratar con conjuntos de caracteres no ASCII.