Conceptos básicos de cadenas (strings) en Go

GolangGolangBeginner
Practicar Ahora

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

En la lección anterior, aprendimos que los caracteres en Go se codifican utilizando UTF-8 y se almacenan como tipos byte o rune. Ahora, analicemos las cadenas (strings), que son colecciones de caracteres. Exploremos este tema juntos.

Puntos de conocimiento:

  • ¿Qué es una cadena (string)?
  • Creación de una cadena (string)
  • Declaración de una cadena (string)
  • Funciones comunes de cadenas (strings)
  • Acceso a los elementos de una cadena (string)

Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL go(("Golang")) -.-> go/BasicsGroup(["Basics"]) go(("Golang")) -.-> go/DataTypesandStructuresGroup(["Data Types and Structures"]) go(("Golang")) -.-> go/FunctionsandControlFlowGroup(["Functions and Control Flow"]) go(("Golang")) -.-> go/ObjectOrientedProgrammingGroup(["Object-Oriented Programming"]) go(("Golang")) -.-> go/AdvancedTopicsGroup(["Advanced Topics"]) go/BasicsGroup -.-> go/values("Values") go/BasicsGroup -.-> go/variables("Variables") go/DataTypesandStructuresGroup -.-> go/strings("Strings") go/FunctionsandControlFlowGroup -.-> go/for("For") go/FunctionsandControlFlowGroup -.-> go/functions("Functions") go/ObjectOrientedProgrammingGroup -.-> go/struct_embedding("Struct Embedding") go/AdvancedTopicsGroup -.-> go/text_templates("Text Templates") go/AdvancedTopicsGroup -.-> go/number_parsing("Number Parsing") subgraph Lab Skills go/values -.-> lab-149069{{"Conceptos básicos de cadenas (strings) en Go"}} go/variables -.-> lab-149069{{"Conceptos básicos de cadenas (strings) en Go"}} go/strings -.-> lab-149069{{"Conceptos básicos de cadenas (strings) en Go"}} go/for -.-> lab-149069{{"Conceptos básicos de cadenas (strings) en Go"}} go/functions -.-> lab-149069{{"Conceptos básicos de cadenas (strings) en Go"}} go/struct_embedding -.-> lab-149069{{"Conceptos básicos de cadenas (strings) en Go"}} go/text_templates -.-> lab-149069{{"Conceptos básicos de cadenas (strings) en Go"}} go/number_parsing -.-> lab-149069{{"Conceptos básicos de cadenas (strings) en Go"}} end

¿Qué es una cadena (string)?

En el primer programa que aprendimos en Go, imprimimos la cadena (string) "hello, world".

Una cadena (string) es un tipo de dato básico en Go, también conocido como literal de cadena (string literal). Puede entenderse como una colección de caracteres y ocupa un bloque contiguo de memoria. Este bloque de memoria puede almacenar cualquier tipo de datos, como letras, texto, emojis, etc.

Sin embargo, a diferencia de otros lenguajes, las cadenas (strings) en Go son inmutables y no se pueden modificar. Esto significa que una vez que se crea una cadena (string), no se pueden cambiar sus caracteres individuales. Si necesita una versión modificada de una cadena (string), debe crear una nueva.

Creación de una cadena (string)

Las cadenas (strings) se pueden declarar de varias maneras. Echemos un vistazo al primer método. Crea un nuevo archivo llamado string.go:

touch ~/project/string.go

Escribe el siguiente código:

package main

import "fmt"

func main() {
    // Use the var keyword to create a string variable a
    var a string = "labex"
    a = "labex" // Assign "labex" to variable a

    // Declare variable b and assign its value
    var b string = "labs"

    // Type declaration can be omitted
    var c = "Monday"

    // Use := for quick declaration and assignment
    d := "Sunday"
    fmt.Println(a, b, c, d)
}

El código anterior demuestra cómo crear cadenas (strings) utilizando la palabra clave var y el operador :=. Si se asigna un valor al crear una variable con var, se puede omitir la declaración de tipo, como se muestra en la creación de la variable c. El operador := es una forma abreviada de declarar e inicializar una variable en Go. Infiere automáticamente el tipo de la variable a partir del valor asignado a ella. Usarlo hará que tu código sea más conciso.

go run string.go

La salida esperada es la siguiente:

labex labs Monday Sunday

Declaración de una cadena (string)

En la mayoría de los casos, usamos comillas dobles "" para declarar cadenas (strings). La ventaja de las comillas dobles es que se pueden utilizar como secuencias de escape. Por ejemplo, en el siguiente programa, usamos la secuencia de escape \n para crear una nueva línea:

package main

import "fmt"

func main() {
    x := "linux\nlabex"
    fmt.Println(x)
}
go run string.go

La salida esperada es la siguiente:

linux
labex

A continuación, se muestran algunas secuencias de escape comunes:

Símbolo Descripción
\n Nueva línea
\r Retorno de carro
\t Tabulación
\b Retroceso
\\ Barra invertida
\' Comilla simple
\" Comilla doble

Si desea preservar el formato original del texto o necesita usar múltiples líneas, puede usar acentos graves (backticks) para representarlas:

package main

import "fmt"

func main() {
    // Output the ASCII art of "labex"
    ascii := `
        ##        #####   #########  ########## ##    #
        ##       ##  ##  ##    ## ##       ##  #
        ##      ##    ## #########  #########    ##
        ##      ########## ##    ## ##        ##
        ##      ##    ## ##    ## ##       ##  #
        ########## ##    ## #########  ########## ##    #`
    fmt.Println(ascii)
}

Los acentos graves (backticks) se utilizan comúnmente en mensajes, plantillas HTML y otros casos en los que es necesario preservar el formato original de la salida. El texto dentro de los acentos graves se trata como un literal de cadena sin procesar (raw string literal), lo que significa que las secuencias de escape no se interpretan. Esto facilita la inclusión de texto de varias líneas y caracteres especiales sin tener que escaparlos.

Obtener la longitud de una cadena (string)

En la lección anterior, aprendimos que los caracteres en inglés y las puntuaciones generales ocupan un byte.

Por lo tanto, en Go, podemos usar la función len() para obtener la longitud en bytes de una cadena (string). Si no hay caracteres que ocupen múltiples bytes, la función len() se puede utilizar para medir con precisión la longitud de la cadena (string).

Si una cadena (string) contiene caracteres que ocupan múltiples bytes, se puede usar la función utf8.RuneCountInString para obtener el número real de caracteres en la cadena (string).

Veamos un ejemplo. Escribe el siguiente código en el archivo string.go:

package main

import (
    "fmt"
    "unicode/utf8"
)

func main() {
    // Declare two empty strings using var and :=
    var a string
    b := ""

    c := "labex"
    d := "abc"


    // Output byte length
    fmt.Printf("The value of a is %s, the byte length of a is: %d\n", a, len(a))
    fmt.Printf("The value of b is %s, the byte length of b is: %d\n", b, len(b))
    fmt.Printf("The value of c is %s, the byte length of c is: %d\n", c, len(c))
	fmt.Printf("The value of d is %s, the byte length of d is: %d\n", d, len(d))


    // Output string length
    fmt.Printf("The length of c is: %d\n", utf8.RuneCountInString(c))
	fmt.Printf("The length of d is: %d\n", utf8.RuneCountInString(d))
}
go run string.go

La salida esperada es la siguiente:

The value of a is, the byte length of a is: 0
The value of b is, the byte length of b is: 0
The value of c is labex, the byte length of c is: 5
The value of d is abc, the byte length of d is: 3
The length of c is: 5
The length of d is: 3

En el programa, primero declaramos dos cadenas (strings) vacías y las cadenas (strings) labex y abc. Puedes ver que sus longitudes en bytes y sus longitudes reales son las mismas, ya que solo contienen caracteres de un solo byte.

Acceso a elementos de una cadena (string)

Dado que las cadenas (strings) son esencialmente secuencias de bytes, podemos acceder a bytes o caracteres individuales en una cadena (string) utilizando su índice. En Go, la indexación de cadenas (strings) comienza desde 0, al igual que en los arrays.

Sin embargo, es importante recordar que acceder a elementos de una cadena (string) utilizando el índice devuelve un byte, no un carácter (rune). Si la cadena (string) contiene caracteres de múltiples bytes, debe tener cuidado al usar índices porque es posible que no obtenga el carácter completo. Para obtener caracteres individuales (rune) de forma segura, puede iterar a través de la cadena (string) utilizando un bucle for...range, que maneja correctamente la codificación UTF - 8.

Vamos a agregar el siguiente código al archivo string.go:

package main

import (
	"fmt"
	"unicode/utf8"
)

func main() {
	str := "Hello, world!"

	// Accessing byte by index
	fmt.Printf("Byte at index 0: %c\n", str[0]) // Output: H
	fmt.Printf("Byte at index 7: %c\n", str[7]) // Output: w

    // Iterate using for...range to safely get runes
    fmt.Println("Iterating through runes:")
    for index, char := range str {
        fmt.Printf("Index: %d, Char: %c\n", index, char)
    }

	// Getting the number of runes
	fmt.Printf("Number of runes (characters) in the string: %d\n", utf8.RuneCountInString(str))

}

Ahora ejecuta el programa:

go run string.go

La salida es:

Byte at index 0: H
Byte at index 7: w
Iterating through runes:
Index: 0, Char: H
Index: 1, Char: e
Index: 2, Char: l
Index: 3, Char: l
Index: 4, Char: o
Index: 5, Char:,
Index: 6, Char:
Index: 7, Char: w
Index: 8, Char: o
Index: 9, Char: r
Index: 10, Char: l
Index: 11, Char: d
Index: 12, Char:!
Number of runes (characters) in the string: 13

En esta salida, puede ver que:

  1. Acceder a una cadena (string) por un índice específico devuelve un byte.
  2. Usar un bucle for...range le permite iterar correctamente a través de los runes.

Este ejemplo destaca la diferencia clave entre byte y rune y la importancia de usar los métodos adecuados al manejar caracteres en cadenas (strings) de Go.

Conversión entre cadenas (strings) y enteros

Podemos utilizar funciones del paquete strconv para convertir entre cadenas (strings) y enteros:

package main

import (
    "fmt"
    "strconv"
)

func main() {
    // Declare a string a and an integer b
    a, b := "233", 223

    // Use Atoi to convert a string to an integer
    c, _ := strconv.Atoi(a)

    // Use Sprintf and Itoa functions respectively
    // to convert an integer to a string
    d1 := fmt.Sprintf("%d", b)
    d2 := strconv.Itoa(b)

    fmt.Printf("The type of a: %T\n", a)   // string
    fmt.Printf("The type of b: %T\n", b)   // int
    fmt.Printf("The type of c: %T\n", c)   // int
    fmt.Printf("The type of d1: %T\n", d1) // string
    fmt.Printf("The type of d2: %T\n", d2) // string
}
go run string.go

La salida esperada es la siguiente:

The type of a: string
The type of b: int
The type of c: int
The type of d1: string
The type of d2: string

En el programa, utilizamos la función Sprintf() del paquete fmt, que tiene el siguiente formato:

func Sprintf(format string, a...interface{}) string

format es una cadena (string) con secuencias de escape, a es una constante o variable que proporciona valores para las secuencias de escape, y ... significa que puede haber múltiples variables del mismo tipo que a. La cadena (string) después de la función indica que Sprintf devuelve una cadena (string). Aquí hay un ejemplo de uso de esta función:

a = fmt.Sprintf("%d+%d=%d", 1, 2, 3)
fmt.Println(a) // 1+2=3

En este fragmento de código, se pasan tres variables enteras 1, 2 y 3 a format. El carácter de escape de entero %d en format se reemplaza por los valores enteros, y la función Sprintf devuelve el resultado después del reemplazo, 1+2=3.

También, tenga en cuenta que cuando se utiliza strconv.Atoi() para convertir una cadena (string) a un entero, la función devuelve dos valores, el entero convertido val y el código de error err. Debido a que en Go, si se declara una variable, se debe utilizarla, podemos utilizar un guión bajo _ para ignorar la variable err.

Cuando strconv.Atoi() convierte correctamente, err devuelve nil. Cuando ocurre un error durante la conversión, err devuelve el mensaje de error, y el valor de val será 0. Puedes cambiar el valor de la cadena (string) a y reemplazar el guión bajo con una variable normal para probarlo tú mismo. Esto es una buena práctica para el manejo de errores, que es una parte crucial de la programación en Go.

Concatenación de cadenas (strings)

La forma más sencilla de concatenar dos o más cadenas (strings) es utilizar el operador +. También podemos utilizar la función fmt.Sprintf() para concatenar cadenas (strings). Echemos un vistazo a un ejemplo:

package main

import (
    "fmt"
)

func main() {
    a, b := "lab", "ex"
    // Concatenate using the simplest method, +
    c1 := a + b
    // Concatenate using the Sprintf function
    c2 := fmt.Sprintf("%s%s", a, b)
    fmt.Println(a, b, c1, c2) // lab ex labex labex
}
go run string.go

La salida esperada es la siguiente:

lab ex labex labex

En el programa, también utilizamos la función Sprintf() del paquete fmt para concatenar cadenas (strings) e imprimir los resultados. Ambos métodos son formas comunes de concatenar cadenas (strings), y la elección entre ellos a menudo depende de la legibilidad y las preferencias personales.

Eliminación de espacios en blanco al principio y al final de una cadena (string)

Podemos utilizar la función strings.TrimSpace para eliminar los espacios en blanco al principio y al final de una cadena (string). La función toma una cadena (string) como entrada y devuelve la cadena (string) con los espacios en blanco al principio y al final eliminados. El formato es el siguiente:

func TrimSpace(s string) string

A continuación, se muestra un ejemplo:

package main

import (
    "fmt"
    "strings"
)

func main() {
    a := " \t \n  labex \n \t labs"
    fmt.Println(strings.TrimSpace(a))
}
go run string.go

La salida esperada es la siguiente:

labex
         labs

Tenga en cuenta que strings.TrimSpace() solo elimina los espacios en blanco al principio y al final de la cadena (string), los espacios en blanco dentro de la cadena (string) permanecen igual.

Resumen

Para resumir lo que hemos aprendido en esta lección:

  • La relación entre cadenas (strings) y caracteres.
  • Dos formas de declarar cadenas (strings), utilizando comillas dobles y acentos graves (backticks).
  • Acceso a elementos de una cadena (string) utilizando índices (acceso a bytes) y for...range (acceso a runes).
  • Obtener la longitud de una cadena (string) utilizando len() (longitud en bytes) y utf8.RuneCountInString (longitud en caracteres/runes).
  • Conversión entre cadenas (strings) y enteros utilizando strconv.Atoi() y strconv.Itoa().
  • Concatenación de cadenas (strings) utilizando el operador + y fmt.Sprintf().
  • Eliminación de espacios en blanco al principio y al final de una cadena (string) utilizando strings.TrimSpace().

En esta lección, hemos explicado las cadenas (strings) que utilizamos en la vida diaria. Hemos aprendido sobre la relación entre cadenas (strings) y caracteres, hemos dominado la creación y declaración de cadenas (strings), y hemos adquirido algunos conocimientos sobre funciones comunes de cadenas (strings). También hemos aprendido cómo acceder de forma segura a caracteres individuales en una cadena (string), especialmente cuando se trata de caracteres de múltiples bytes, y ahora comprendemos algunos métodos cruciales de manipulación de cadenas (strings). Esto te da una base sólida para trabajar con datos de cadenas (strings) en Go.