Saiba mais sobre tipos de dados básicos

Concluído

Go é uma linguagem fortemente tipada . Cada variável declarada está vinculada a um tipo de dados específico e só aceitará valores que correspondam a esse tipo.

Em Go, você tem quatro categorias de tipos de dados:

  • Tipos básicos: números, cadeias de caracteres e booleanos
  • Tipos de agregados: matrizes e estruturas
  • Tipos de referência: ponteiros, fatias, mapas, funções e canais
  • Tipos de interface: interface

Neste módulo, abordamos apenas os tipos básicos. Não se preocupe se você não sabe quais são os outros tipos. Vamos abordá-los nos próximos módulos.

Vamos começar explorando os tipos de dados numéricos.

Números inteiros

Em termos gerais, a palavra-chave para definir um tipo inteiro é int. Mas Go também fornece os int8tipos , int16, int32, e , que int64 são ints com um tamanho de 8, 16, 32 ou 64 bits, respectivamente. Quando você está usando um sistema operacional de 32 bits, se você apenas usar into , o tamanho geralmente é de 32 bits. Em sistemas de 64 bits, o int tamanho é geralmente de 64 bits. Mas esse comportamento pode diferir de um computador para outro. Você pode usar uinto . Mas só use esse tipo se precisar representar um valor como um número não assinado por um determinado motivo. Go também fornece uint8, uint16, uint32, e uint64 tipos.

Aqui está um exemplo de como usar os vários tipos de inteiros em Go:

var integer8 int8 = 127
var integer16 int16 = 32767
var integer32 int32 = 2147483647
var integer64 int64 = 9223372036854775807
fmt.Println(integer8, integer16, integer32, integer64)

Na maioria das vezes, você usará int, mas precisa saber sobre os outros tipos inteiros porque, em Go, int não é o mesmo que int32, mesmo que o tamanho natural do inteiro seja de 32 bits. Em outras palavras, você precisará lançar explicitamente quando um elenco for necessário. E se você tentar executar uma operação matemática entre diferentes tipos, você receberá um erro. Por exemplo, suponha que você tenha este código:

var integer16 int16 = 127
var integer32 int32 = 32767
fmt.Println(integer16 + integer32)

Quando você executa o programa, você receberá este erro:

invalid operation: integer16 + integer32 (mismatched types int16 and int32)

Como você pode ver, quando você converte um valor de um tipo para outro em Go, você precisa declarar explicitamente o novo tipo. Falaremos sobre como moldar tipos corretamente no final deste módulo.

À medida que você progride em seu aprendizado Go, você pode ouvir sobre runas. A rune é simplesmente um alias para int32 o tipo de dados. Ele é usado para representar um caractere Unicode (ou um ponto de código Unicode). Por exemplo, suponha que você tenha o seguinte código:

rune := 'G'
fmt.Println(rune)

Você pode esperar ver o programa ser impresso G no prompt de comando quando executar o trecho de código anterior. Mas você vê o número 71, que representa o caractere Unicode para G. Falaremos mais sobre runas nos próximos módulos.

Você pode aprender sobre os intervalos para cada tipo observando o código-fonte Go. Conhecer os intervalos de cada tipo irá ajudá-lo a escolher o tipo de dados adequado, e você também evitará o desperdício de bits na memória.

Desafio 1

Defina outra variável do tipo int e use o valor da integer32 variável ou integer64 para confirmar o tamanho natural da variável no seu sistema. Se você estiver em um sistema de 32 bits e usar um valor superior a 2.147.483.647, obterá um erro de estouro semelhante a este: constant 9223372036854775807 overflows int.

Solução para desafios:

package main

import "fmt"

func main() {
   var integer32 int = 2147483648
   fmt.Println(integer32)
}

Desafio 2

Declare uma variável não assinada como uint, e inicialize-a com um valor negativo como -10. Quando você tenta executar o programa, você deve obter um erro como este: constant -10 overflows uint.

Solução para desafios:

package main

import "fmt"

func main() {
   var integer uint = -10
   fmt.Println(integer)
}

Números de vírgula flutuante

Go fornece tipos de dados para dois tamanhos de números de vírgula flutuante: float32 e float64. Você pode usar esses tipos quando precisar armazenar grandes números e eles não se encaixarem em nenhum dos tipos inteiros mencionados anteriormente. A diferença entre esses dois tipos é o tamanho máximo de bits que eles podem conter. Veja as seguintes linhas para saber como usar esses dois tipos:

var float32 float32 = 2147483647
var float64 float64 = 9223372036854775807
fmt.Println(float32, float64)

Você pode encontrar os limites desses dois tipos usando as math.MaxFloat32 constantes e math.MaxFloat64 , que estão disponíveis no math pacote. Use o código a seguir para imprimir os valores máximos de ponto flutuante no prompt de comando:

package main

import (
    "fmt"
    "math"
)    

func main() {
    fmt.Println(math.MaxFloat32, math.MaxFloat64)
}

Os tipos de vírgula flutuante também são úteis quando você precisa usar números decimais. Por exemplo, você pode escrever algo como este código:

const e = 2.71828
const Avogadro = 6.02214129e23
const Planck = 6.62606957e-34

Observe que, com o código anterior, Go infere os tipos de dados dos valores usados.

Booleanos

Um tipo booleano tem apenas dois valores possíveis: true e false. Você declara um tipo booleano usando a palavra-chave bool. Go é diferente de outras linguagens de programação. Em Go, você não pode converter implicitamente um tipo booleano para 0 ou 1. É preciso fazê-lo explicitamente.

Assim, você pode declarar uma variável booleana como esta:

var featureFlag bool = true

Usaremos tipos de dados booleanos no próximo módulo quando falarmos sobre instruções de fluxo de controle em Go. Também os usaremos em módulos posteriores.

Cadeias

Finalmente, vamos olhar para o tipo de dados mais comum em qualquer linguagem de programação: string. Em Go, a palavra-chave string é usada para representar um tipo de dados de cadeia de caracteres. Para inicializar uma variável de cadeia de caracteres, você precisa definir seu valor entre aspas duplas ("). As aspas simples (') são usadas para caracteres únicos (e para runas, como vimos em uma seção anterior).

Por exemplo, o código a seguir mostra duas maneiras de declarar e inicializar uma variável de cadeia de caracteres:

var firstName string = "John"
lastName := "Doe"
fmt.Println(firstName, lastName)

Às vezes, você precisará escapar dos personagens. Para fazer isso em Go, você usa uma barra invertida (\) antes do personagem. Por exemplo, aqui estão os exemplos mais comuns de uso de caracteres de escape:

  • \n para novas linhas
  • \r para devoluções de transporte
  • \t para separadores
  • \' para aspas simples
  • \" para aspas duplas
  • \\ para barras invertidas

Use o seguinte trecho de código para testar caracteres de escape:

fullName := "John Doe \t(alias \"Foo\")\n"
fmt.Println(fullName)

Você deve ver a seguinte saída (incluindo a nova linha):

John Doe        (alias "Foo")

Valores predefinidos

Até agora, quase todas as vezes que declaramos uma variável, a inicializamos com um valor. Mas em Go, ao contrário de outras linguagens de programação, todos os tipos de dados têm um valor padrão quando você não inicializa uma variável. Esse recurso é útil porque você não precisa verificar se uma variável foi inicializada antes de usá-la.

Aqui está uma lista de alguns valores padrão para os tipos que exploramos até agora:

  • 0 para int tipos (e todos os seus subtipos, como int64)
  • +0.000000e+000 para float32 e float64 tipos
  • false para bool tipos
  • Um valor vazio para string tipos

Execute o seguinte trecho de código para confirmar os valores padrão listados anteriormente:

var defaultInt int
var defaultFloat32 float32
var defaultFloat64 float64
var defaultBool bool
var defaultString string
fmt.Println(defaultInt, defaultFloat32, defaultFloat64, defaultBool, defaultString)

Você pode usar um código como este para determinar o valor padrão para um tipo de dados que não exploramos aqui.

Conversões de tipos

Em uma seção anterior, confirmamos que o casting implícito não funciona no Go. Em Go, o casting precisa ser feito explicitamente. O Go oferece algumas maneiras nativas de converter um tipo de dados em um tipo de dados diferente. Por exemplo, uma maneira é usar a função interna para cada tipo, assim:

var integer16 int16 = 127
var integer32 int32 = 32767
fmt.Println(int32(integer16) + integer32)

Outra abordagem para fundição no Go é usar o pacote strconv. Por exemplo, para converter a string em um int, e vice-versa, você pode usar este código:

package main

import (
    "fmt"
    "strconv"
)

func main() {
    i, _ := strconv.Atoi("-42")
    s := strconv.Itoa(-42)
    fmt.Println(i, s)
}

Execute o código anterior e confirme se ele é executado e impresso -42 duas vezes.

Observe que há um sublinhado (_) usado como o nome de uma variável no código anterior. Em Go, os _ meios que não vamos usar o valor dessa variável, e que queremos ignorá-lo. Caso contrário, o programa não será compilado porque precisamos usar todas as variáveis que declaramos. Voltaremos a este assunto e você aprenderá o que o _ normalmente representa nos próximos módulos.