Ru

Runas en Go

3 ejercicios

Acerca de Runas

El tipo rune de Go es un alias de int32. Dado este tipo int32 subyacente, el tipo rune almacena un valor entero con signo de 32 bits. Sin embargo, a diferencia de un tipo int32, el valor entero almacenado en un tipo rune representa un único carácter Unicode.

Unicode y los puntos de código Unicode

Unicode es un superconjunto de ASCII que representa los caracteres asignando un número único a cada carácter. Este número único se denomina punto de código Unicode. Unicode pretende representar todos los caracteres del mundo, incluidos los distintos alfabetos, números, símbolos e incluso emoji, como puntos de código Unicode.

En Go, el tipo rune representa un único punto de código Unicode.

La siguiente tabla contiene caracteres Unicode de ejemplo junto con su punto de código Unicode y su valor decimal:

Carácter Unicode Punto de código Unicode Valor decimal
0 U+0030 48
A U+0041 65
a U+0061 97
¿ U+00BF 191
π U+03C0 960
🧠 U+1F9E0 129504

UTF-8

UTF-8 es una codificación de caracteres de ancho variable que se usa para codificar cada punto de código Unicode en 1, 2, 3 o 4 bytes. Dado que un punto de código Unicode puede codificarse en un máximo de 4 bytes, el tipo rune tiene que ser capaz de contener hasta 4 bytes de datos. Por eso el tipo rune es un alias de int32, ya que un tipo int32 es capaz de contener hasta 4 bytes de datos.

Los archivos de código fuente de Go se codifican con UTF-8.

Cómo usar los runes

Las variables de tipo rune se declaran colocando un carácter entre comillas simples:

myRune := '¿'

Como rune no es más que un alias de int32, imprimir el tipo de un rune devuelve int32:

myRune := '¿'
fmt.Printf("myRune type: %T\n", myRune)
// Output: myRune type: int32

Del mismo modo, imprimir el valor de un rune devuelve su valor entero (decimal):

myRune := '¿'
fmt.Printf("myRune value: %v\n", myRune)
// Output: myRune value: 191

Para imprimir el carácter Unicode que representa el rune, usa el verbo de formato %c:

myRune := '¿'
fmt.Printf("myRune Unicode character: %c\n", myRune)
// Output: myRune Unicode character: ¿

Para imprimir el punto de código Unicode que representa el rune, usa el verbo de formato %U:

myRune := '¿'
fmt.Printf("myRune Unicode code point: %U\n", myRune)
// Output: myRune Unicode code point: U+00BF

Además de definir un rune envolviendo el carácter entre comillas simples, también puedes especificar el número hexadecimal o decimal:

myRune := rune(0xbf)
myRune = 191
fmt.Printf("myRune Unicode character: %c\n", myRune)
// Output: myRune Unicode character: ¿

Runes y strings

Los strings en Go se codifican con UTF-8, lo que significa que contienen caracteres Unicode. Los caracteres de un string se almacenan y se codifican en 1, 2, 3 o 4 bytes en función del carácter Unicode que representen.

En Go, los slices se usan para representar secuencias y se puede iterar sobre ellos usando range. Cuando iteramos sobre un string, Go convierte el string en una serie de runes, cada uno de los cuales ocupa 4 bytes (recuerda, ¡el tipo rune es un alias de int32!).

Aunque un string no es más que un slice de bytes, la palabra clave range itera sobre los runes de un string, no sobre sus bytes.

En este ejemplo, la variable index representa el índice inicial de la secuencia de bytes del rune actual y la variable char representa el rune actual:

myString := "❗hello"
for index, char := range myString {
  fmt.Printf("Index: %d\tCharacter: %c\t\tCode Point: %U\n", index, char, char)
}
// Output:
// Index: 0	Character: ❗		Code Point: U+2757
// Index: 3	Character: h		Code Point: U+0068
// Index: 4	Character: e		Code Point: U+0065
// Index: 5	Character: l		Code Point: U+006C
// Index: 6	Character: l		Code Point: U+006C
// Index: 7	Character: o		Code Point: U+006F

Como los runes pueden ocupar 1, 2, 3 o 4 bytes, la longitud de un string no siempre tiene por qué coincidir con el número de caracteres que contiene. Usa la función integrada len para obtener la longitud de un string en bytes y la función utf8.RuneCountInString para obtener el número de runes de un string:

import "unicode/utf8"

myString := "❗hello"
stringLength := len(myString)
numberOfRunes := utf8.RuneCountInString(myString)

fmt.Printf("myString - Length: %d - Runes: %d\n", stringLength, numberOfRunes)
// Output: myString - Length: 8 - Runes: 6

Conversión de tipos de runes

Un slice de runes se puede convertir a un string mediante conversión de tipos:

myRuneSlice := []rune{'e', 'x', 'e', 'r', 'c', 'i', 's', 'm'}
myString := string(myRuneSlice)
fmt.Println(myString)
// Output: exercism

Del mismo modo, un string se puede convertir a un slice de runes mediante conversión de tipos. Recuerda que, sin verbos de formato, imprimir un rune devuelve su valor entero (decimal):

myString := "exercism"
myRuneSlice := []rune(myString)
fmt.Println(myRuneSlice)
// Output: [101 120 101 114 99 105 115 109]
Editar en GitHub El enlace se abre en una nueva ventana o pestaña

Aprende Runas

La práctica está bloqueada

Desbloquea 2 ejercicios más para practicar Runas