Introdução
Na seção anterior, discutimos os tipos numéricos mais utilizados. Nesta etapa, vamos aprender sobre os tipos de caracteres na linguagem Go.
Conteúdos Abordados:
- Codificação ASCII
- Codificação UTF-8
- Conjunto de Caracteres Unicode
byterune
Na seção anterior, discutimos os tipos numéricos mais utilizados. Nesta etapa, vamos aprender sobre os tipos de caracteres na linguagem Go.
Conteúdos Abordados:
byteruneNos primórdios da computação, utilizava-se o formato de codificação ASCII (American Standard Code for Information Interchange). Ele representava caracteres usando 7 bits, o que permitia um total de 128 (2^7) combinações. Os caracteres do bit 0 ao 31, além do bit 127, representavam caracteres de controle não exibíveis, enquanto os caracteres do bit 32 ao 126 representavam letras maiúsculas e minúsculas do cotidiano, números e sinais de pontuação. Consulte a tabela para mais detalhes.
Com a evolução dos computadores, surgiu a necessidade de suportar diferentes idiomas. A codificação ASCII mostrou-se insuficiente para esse propósito. Consequentemente, diversos idiomas desenvolveram seus próprios formatos de codificação, como o GB2312 para chinês simplificado, EUC-KR para coreano e KOI8-R para russo.
No entanto, com a enorme variedade de famílias linguísticas no mundo, tornou-se necessário um formato de codificação único que pudesse unificar todos os idiomas. O Unicode foi criado justamente para suprir essa necessidade.
Em 1991, o Unicode Consortium lançou a primeira versão do conjunto de caracteres Unicode. Seu objetivo era unificar todos os idiomas em um único formato de codificação, permitindo que computadores em todo o mundo exibissem e processassem textos com mais facilidade, evitando problemas de compatibilidade em ambientes multilíngues.
Contudo, o Unicode era apenas um conjunto de caracteres; ele definia os códigos dos caracteres, mas não como eles deveriam ser armazenados fisicamente. Isso dificultou sua adoção em larga escala por muito tempo, até a ascensão da Internet.
Com o desenvolvimento contínuo da Internet, o UTF-8, uma implementação de codificação Unicode, ganhou popularidade. Trata-se de uma codificação de comprimento variável, o que significa que diferentes símbolos podem ter diferentes tamanhos de bytes no UTF-8.
Por exemplo, letras do alfabeto inglês, que estão dentro da faixa ASCII, são representadas por 1 byte. O caractere 'y' (valor Unicode 121) ocupa 1 byte.
Para o uso cotidiano, a maioria dos caracteres chineses ocupa 3 bytes. Por exemplo, o caractere '实' (valor Unicode 23454) ocupa 3 bytes.
No entanto, existem alguns caracteres chineses que ocupam 4 bytes. Isso ocorre porque existem mais de 100.000 caracteres chineses, mas, conforme a estrutura técnica, 3 bytes só podem representar pouco mais de 60.000 caracteres, exigindo que uma pequena parcela utilize 4 bytes.
Outra vantagem da codificação UTF-8 é a sua compatibilidade retroativa com o ASCII. Na verdade, o ASCII é um subconjunto do UTF-8. Os primeiros 128 caracteres no UTF-8 correspondem um para um aos caracteres ASCII. Isso significa que softwares que originalmente usavam ASCII podem continuar sendo utilizados com pouca ou nenhuma modificação. Devido a essas vantagens, o UTF-8 tornou-se gradualmente o formato de codificação preferido mundialmente.
Os criadores da linguagem de programação Go, Rob Pike e Ken Thompson, também foram os inventores do UTF-8, por isso o Go possui uma afinidade especial com este formato. O Go exige que os arquivos de código-fonte sejam salvos em codificação UTF-8. Ao manipular caracteres de texto, o UTF-8 é a escolha padrão. Além disso, a biblioteca padrão oferece diversas funções relacionadas à codificação e decodificação UTF-8.
O tipo byte é um apelido (alias) para uint8 e ocupa um byte (8 bits). Ele pode ser usado para representar todos os caracteres da tabela ASCII. No entanto, como o byte possui uma faixa limitada de valores (256 ou 2^8), ao lidar com caracteres compostos, como os caracteres chineses ou símbolos complexos, precisamos utilizar o tipo rune.
Crie um novo arquivo chamado byte.go e insira o seguinte código:
cd ~/project
touch byte.go
package main
import "fmt"
func main() {
var a byte = 76
fmt.Printf("Value of a: %c\n", a)
var b uint8 = 76
fmt.Printf("Value of b: %c\n", b)
var c byte = 'L'
fmt.Printf("Value of c: %c\n", c)
}
Após executar o programa, o seguinte resultado será exibido:
go run byte.go
Value of a: L
Value of b: L
Value of c: L
O marcador %c é utilizado para exibir caracteres. É possível notar que o tipo byte e o tipo uint8 produzem a mesma saída quando possuem o mesmo valor. Consultando a tabela ASCII, vemos que o valor ASCII da letra 'A' é 65. Quando usamos o marcador de número inteiro %d para exibir o valor, ele também resulta em 65.
Portanto, fica evidente que o byte no Go é equivalente ao uint8 dos tipos inteiros. O mesmo princípio se aplica ao rune, mas ele representa uma faixa diferente de valores inteiros.
O tipo rune é um apelido para int32 e ocupa quatro bytes (32 bits). Ele é utilizado para representar caracteres compostos, como emojis.
Atualize o arquivo byte.go com o seguinte código:
package main
import "fmt"
func main() {
var a rune = '😊' // Emoji de sorriso
fmt.Printf("Value of a: %c\n", a)
var b int32 = 9829 // Representação decimal de um caractere Unicode (Símbolo de coração)
fmt.Printf("Value of b: %c\n", b)
var c rune = 0x1F496 // Representação hexadecimal de um caractere Unicode (Emoji de coração brilhante)
fmt.Printf("Value of c: %c\n", c)
var d rune = '\u0041' // Caractere Unicode representado pelo seu code point (Letra maiúscula 'A')
fmt.Printf("Value of d: %c\n", d)
var e rune = '\U0001F609' // Caractere Unicode representado pelo seu code point (Emoji de rosto piscando)
fmt.Printf("Value of e: %c\n", e)
}
Após executar o programa, a seguinte saída será exibida:
go run byte.go
Nota: Execute o programa no Terminal do Desktop ou do WebIDE, mas evite executá-lo na aba Terminal localizada no topo da VM do LabEx.
Value of a: 😊
Value of b: ♥
Value of c: 💖
Value of d: A
Value of e: 😉
a representa o emoji de sorriso '😊'.b é inicializada com a representação decimal de um caractere Unicode (9829), que corresponde ao símbolo de coração '♥'.c é inicializada com a representação hexadecimal de um caractere Unicode (0x1F496), que corresponde ao emoji de coração brilhante '💖'.d representa a letra maiúscula 'A' usando o formato Unicode \u0041.e representa o emoji de rosto piscando '😉' usando o formato \U com o code point 0001F609.Nota: Em Go, aspas simples e aspas duplas não são a mesma coisa. Aspas simples são usadas para representar caracteres individuais, enquanto aspas duplas são usadas para declarar strings (cadeias de caracteres). Portanto, deve-se usar aspas simples ao declarar tipos byte e rune, caso contrário, ocorrerá um erro.
Agora, vamos reforçar o que aprendemos. Crie um novo arquivo chamado rune.go e insira o código abaixo. Complete o código de modo que o número hexadecimal 0x1F648 seja atribuído à variável a e o programa exiba seu valor corretamente.
rune.go deve ser colocado no diretório ~/project.package main
import "fmt"
func main() {
var a rune = 0x1F648
fmt.Printf("The value of a is: %c\n", a)
}
Vamos recapitular o que aprendemos nesta seção:
byte pode ser usado para representar caracteres ASCII, enquanto o tipo de dado rune é utilizado para representar caracteres Unicode.byte é essencialmente um apelido para inteiros de 8 bits, e o rune para inteiros de 32 bits.Nesta seção, explicamos primeiro os conceitos de ASCII, UTF-8 e Unicode. Em seguida, detalhamos a relação entre os tipos de caracteres byte e rune com os tipos de dados inteiros.