APRESENTAÇÃO
QUEM SÃO VOCÊS?
ACORDOS DE TIME
Introdução aos conceitos de linguagem de programação
GO
Definição
Porque usar Go?
Quem usa Go?
Aplicabilidade da linguagem Go
Instalação e configuração do ambiente
Tipos Básicos, Operadores e Variáveis
Estrutura de controle de fluxo
Arrays, Slices e Maps
AGENDA
Ponteiros
Structs
AGENDA
Comando em Português para Go
// Mostre a mensagem "Olá, mundo!"
println("Olá, mundo!")Citem um comando em português.
// Guarde o nome "Ana" em uma variável
nome := "Ana"// Some 2 com 3 e guarde o resultado
resultado := 2 + 3// Se a idade for maior ou igual a 18, diga "Pode votar"
if idade >= 18 {
fmt.Println("Pode votar")
}
// Repita de 0 até 4 e mostre o número
for i := 0; i < 5; i++ {
fmt.Println(i)
}
TIPOS DE LINGUAGEM
Definições
write()
exit()
data()
Linguagem de máquina
Linguagem de montagem
LINGUAGEM COMPILADA
LINGUAGEM COMPILADA X INTERPRETADA
package main
import "fmt"
func main() {
fmt.Println("Olá, mundo!")
}
go build main.go
./main
main.exe
print("Olá, mundo!")
python programa.py “Enquanto o Python precisa estar instalado em qualquer máquina que vá rodar seu script, com Go você pode compilar e enviar só o executável.”
LINGUAGEM COMPILADA X INTERPRETADA
| Característica | Compilada | Interpretada |
|---|---|---|
| Tradução | Todo o código de uma vez | Linha por linha |
| Velocidade de execução | Mais rápida | Pode ser mais lenta |
| Portabilidade | Menos portável | Mais portável |
| Detecção de erros | Antes da execução (em tempo de compilação) | Durante a execução (em tempo real) |
| Gera arquivo executável? | Sim | Não |
| Exemplo de linguagem | C, C++, Rust, GO | Python, JavaScript |
LINGUAGEM INTERPRETADA X COMPILADA - PARA FIXAR
RANKING DE LINGUAGENS DE PROGRAMAÇÃO
RANKING DE LINGUAGENS DE PROGRAMAÇÃO
|
Python |
|
RANKING DE LINGUAGENS DE PROGRAMAÇÃO
TypeScript
RANKING DE LINGUAGENS DE PROGRAMAÇÃO
C++
RANKING DE LINGUAGENS DE PROGRAMAÇÃO
Go
Dito isso iremos trabalhar com...
DEFINIÇÃO
DEFINIÇÃO
Objetivos principais:
PORQUE USAR GO?
PORQUE USAR GO?
QUEM USA GO?
APLICABILIDADE DA LINGUAGEM GO
💾 Backend Web e APIs
Go possui frameworks leves (como Gin, Echo) para criação de APIs RESTful com alta performance.
Excelente desempenho em resposta e uso de memória.
⚙️ Ferramentas de Linha de Comando (CLI)
Go produz binários leves e multiplataforma, perfeitos para utilitários CLI.
Simples de empacotar e distribuir.
Exemplos:
kubectl, helm, hugo (gerador de site estático)
☁️ Cloud Computing e Microserviços
Excelente para desenvolver microserviços em arquiteturas distribuídas.
Ferramentas famosas escritas em Go:
Docker
Kubernetes
Prometheus
Terraform
🧩 Desenvolvimento de Sistemas Concorrentes
Go é projetada com suporte nativo à concorrência via goroutines e channels.
Ideal para sistemas que exigem alta escalabilidade, como servidores web, proxies e serviços em tempo real.
Exemplos:
Servidores HTTP de alto desempenho
Chat em tempo real
Processamento paralelo de dados
INSTALAÇÃO E CONFIGURAÇÃO DO AMBIENTE
INSTALAÇÃO E CONFIGURAÇÃO DO AMBIENTE
INSTALAÇÃO E CONFIGURAÇÃO DO AMBIENTE
INSTALAÇÃO E CONFIGURAÇÃO DO AMBIENTE
Marque todas as opções quando chegar na tela abaixo.
INSTALAÇÃO E CONFIGURAÇÃO DO AMBIENTE
Criando primeiro projeto no GoLand.
Clique em New Project/Novo Projeto.
INSTALAÇÃO E CONFIGURAÇÃO DO AMBIENTE
Defina o nome do projeto ProjetoGo.
Clique no botão create.
ESTRUTURA DO PROJETO GO
Primeiro projeto criado entenda a estrutura de um projeto GO:
go.mod: Usado para rastrear as dependências do projeto e definir o módulo. Esse arquivo é gerado ao rodar go mod init.
main.go: Ponto de entrada da aplicação.
README.md: Contém a descrição e as instruções do projeto.
ESTRUTURA DE UM PROGRAMA GO
Explicando o Programa “Hello and welcome”:
package main: Declara que este é o pacote principal e o código será compilado como um executável.
import "fmt": Importa o pacote fmt, que contém funções para entrada e saída de dados (ex.: Println).
func main(): A função principal. É onde o código começa a ser executado.
fmt.Println("Hello and welcome!"): Usa a função Println do pacote fmt para imprimir "Hello and welcome!" no console.
COMPILAÇÃO E EXECUÇÃO NO GO
O Go compila diretamente para um binário executável, que pode ser executado nativamente no sistema.
Para compilar e executar um programa GO, use os comandos abaixo no terminal da IDE GoLand:
Execução
Compilação
SINTAXE BÁSICA E TIPOS DE DADOS EM GO
package main
import "fmt"
func main() {
// declaração explícita com var
var nome string
var idade int
// declaração com atribuição
var sobrenome string = "Vasconcelos"
var peso float64 = 85.6
// atribuição curta (somente dentro de funções)
cor := "pardo"
temFilhos := true
nome = "Raimundo José"
idade = 37
println("Nome: ", nome)
println("Idade: ", idade)
println("Sobrenome: ", sobrenome)
fmt.Printf("Peso: %.2f\n", peso)
println("Cor: ", cor)
println("TemFilhos: ", temFilhos)
}Em Go, as variáveis podem ser declaradas de várias maneiras:
Usando a palavra-chave var.
Usando a atribuição curta := (somente dentro de funções).
TIPOS DE DADOS
func tiposDeDados() {
idade := 21 // Inteiro
altura := 1.75 // Ponto flutuante
nome := "Ana" // String
vivo := true // Booleano
println("Idade: ", idade)
println("Altura: ", altura)
println("Nome: ", nome)
println("Vivo: ", vivo)
}Inteiros: int, int8, int16, int32, int64 (e suas versões sem sinal uint).
Pontos flutuantes: float32, float64.
Strings: Cadeias de caracteres (imutáveis).
Booleanos: bool (verdadeiro ou falso).
TIPOS DE DADOS - CONSTANTES
func constante() {
const pi = 3.14
const nome = "GoLang"
println("PI: ", pi)
println("Nome: ", nome)
}Constantes em Go são declaradas com a palavra-chave const.
Diferente das variáveis, seu valor não pode ser alterado após a atribuição.
TIPOS DE DADOS - CONVERSÃO DE TIPOS
func conversaoDeTipos() {
var nota int = 85
var notaMedia float64 = float64(nota) / 10
fmt.Println(notaMedia)
}Em Go, a conversão de tipos deve ser feita de forma explícita.
Sintaxe para conversão:
var inteiro int = 10
var flutuante float64 = float64(inteiro)
var novoInteiro int = int(flutuante)
ENTRADA E SAÍDA
O pacote fmt em Go é utilizado para formatar e imprimir dados no console, assim como para ler entradas do usuário. Aqui está um resumo dos principais comandos de entrada e saída:
Entrada (Input):
fmt.Scan(): Lê entradas de uma ou mais variáveis, separadas por espaços.
fmt.Scanln(): Similar ao Scan(), mas lê até o fim da linha (após o "Enter").
fmt.Scanf():Lê a entrada com base em um formato especificado (similar ao Printf, mas para entrada).
Saída (Output):
fmt.Println(): Imprime uma ou mais variáveis no console com uma nova linha no final.
fmt.Printf(): Imprime com formatação especificada, sem adicionar automaticamente uma nova linha.
// Entrada e Saída de Dados
var input1 string
var input2 string
fmt.Printf("Entre com 2 palavras - (Scan): ")
fmt.Scan(&input1, &input2)
fmt.Printf("Texto Lido - (Scan): %s - %s\n", input1, input2)
var input3 string
fmt.Printf("Digite um texto - (Scanln): ")
fmt.Scanln(&input3)
fmt.Printf("Texto digitado - (Scanln): %s\n", input3)
var input4 string
var input5 int
fmt.Printf("Digite um texto - (Scanf): ")
fmt.Scanf("%s", &input4)
fmt.Printf("Texto digitado: %s\n", input4)
fmt.Printf("Digite um numero - (Scanf): ")
fmt.Scanf("%d", &input5)
fmt.Printf("numero digitado - (Scanf): %d\n", input5)ENTRADA E SAÍDA
Em Go, para ler uma entrada de texto que contém espaços, você pode usar o método fmt.Scanln() ou bufio.Reader junto com os.Stdin para capturar a linha inteira.
// Entrada de Dados - bufio
reader := bufio.NewReader(os.Stdin)
fmt.Printf("Digite um texto com espaços:")
texto, _ := reader.ReadString('\n')
fmt.Printf("Você digitou: %s", texto)OPERADORES ARITMÉTICOS
Go suporta os operadores aritméticos básicos:
// Operadores aritméticos
a := 10
b := 3
fmt.Println(a + b) // Soma: 13
fmt.Println(a - b) // Subtração: 7
fmt.Println(a * b) // Multiplicação: 30
fmt.Println(a / b) // Divisão: 3
fmt.Println(a % b) // Módulo: 1OPERADORES RELACIONAIS
Operadores relacionais em Go:
// Operadores Relacionais
x := 10
y := 5
fmt.Println(x > y) // true
fmt.Println(x <= y) // false
fmt.Println(x == 10) // true
fmt.Println(x != y) // trueOPERADORES LÓGICOS
# Definindo variáveis
a = 10
b = 5
c = 7
# Exemplo sem parênteses usando 'and' e operadores relacionais
resultado = a > b and b < c
print("Resultado de a > b and b < c: ", resultado) # Output: True
# Exemplo sem parênteses usando 'or' e operadores relacionais
resultado = a < b or c >= b
print("Resultado de a < b or c >= b: ", resultado) # Output: True
# Exemplo sem parênteses usando 'not' para inverter o resultado
resultado = not a == b
print("Resultado de not a == b: ", resultado) # Output: TrueOperadores relacionais em Go:
EXERCÍCIO DE FIXAÇÃO
Crie um programa que peça ao usuário para inserir três números inteiros. O programa deve calcular e exibir a média aritmética desses três números.
package main
import "fmt"
func main() {
var num1, num2, num3 int
fmt.Println("Digite o primeiro número:")
fmt.Scanln(&num1)
fmt.Println("Digite o segundo número:")
fmt.Scanln(&num2)
fmt.Println("Digite o terceiro número:")
fmt.Scanln(&num3)
media := (num1 + num2 + num3) / 3
fmt.Printf("A média dos números é: %d\n", media)
}EXERCÍCIO DE FIXAÇÃO
Calculadora Simples
Criar uma calculadora que pede dois números e realiza as quatro operações básicas.
func calculadoraSimples() {
var num1, num2 float64
// Entrada de dados
fmt.Println("Digite o primeiro número:")
fmt.Scanln(&num1)
fmt.Println("Digite o segundo número:")
fmt.Scanln(&num2)
// Operações
soma := num1 + num2
subtracao := num1 - num2
multiplicacao := num1 * num2
divisao := num1 / num2
// Saída
fmt.Printf("Soma: %.2f\n", soma)
fmt.Printf("Subtração: %.2f\n", subtracao)
fmt.Printf("Multiplicação: %.2f\n", multiplicacao)
fmt.Printf("Divisão: %.2f\n", divisao)
}EXERCÍCIO DE FIXAÇÃO
Login
Criar uma algoritmo que simule o login de um usuário.
package main
import "fmt"
func main() {
var usuario, senha string
var ativo bool = true
// Dados simulados
usuarioCorreto := "admin"
senhaCorreta := "1234"
fmt.Println("Digite o nome de usuário:")
fmt.Scanln(&usuario)
fmt.Println("Digite a senha:")
fmt.Scanln(&senha)
// Verificação de login com operadores lógicos
if usuario == usuarioCorreto && senha == senhaCorreta && ativo {
fmt.Println("Login realizado com sucesso!")
} else if usuario == usuarioCorreto && senha == senhaCorreta && !ativo {
fmt.Println("Usuário correto, mas conta inativa.")
} else if usuario == usuarioCorreto || senha == senhaCorreta {
fmt.Println("Usuário ou senha corretos, mas combinação inválida.")
} else {
fmt.Println("Usuário e senha incorretos.")
}
// Exemplo de negação
if !(usuario == usuarioCorreto && senha == senhaCorreta) {
fmt.Println("Tentativa de login inválida.")
}
}IMPORTAÇÕES
Seguindo a seguinte estrutura de projeto, vejamos como podemos realizar a importação de módulos.
meu_projeto/
├── main.go
└── util/
└── mensagens.go//mensagens.go
package util
import "fmt"
func Ola(nome string) {
fmt.Printf("Olá, %s!\n", nome)
}//main.go
package main
import (
"meu_projeto/util" // importa o pacote local
)
func main() {
util.Ola("Mundo")
}IMPORTAÇÕES
Também é possível criar "alias" ou apelidos para as importações:
meu_projeto/
├── main.go
└── util/
└── mensagens.goimport alias "caminho/do/pacote"//main.go
package main
import (
msg "meu_projeto/util" // importa o pacote local
)
func main() {
msg.Ola("Mundo")
}ESTRUTURA DE DECISÃO
Estruturas de decisão (ou estruturas condicionais) são usadas para controlar o fluxo de execução de um programa com base em condições. Em Go, a principal estrutura de decisão é o bloco if, que pode ser complementado pelos blocos else if e else para verificar múltiplas condições e tomar diferentes decisões.
ESTRUTURA DE DECISÃO
if: Avalia uma condição e, se for verdadeira, executa o bloco de código associado.
else if: Permite verificar outras condições se a condição if anterior for falsa.
else: Executa um bloco de código quando todas as condições anteriores são falsas.
if condicao {
// Código se condição for verdadeira
} else if outraCondicao {
// Código se a outra condição for verdadeira
} else {
// Código se nenhuma condição for verdadeira
}ESTRUTURA DE DECISÃO
package main
import "fmt"
func main(){
idade := 20
if idade >= 18 {
fmt.Println("Maior de idade")
} else {
fmt.Println("Menor de idade")
}
}
Condicionais if, else permite executar blocos de código com base em condições.
ESTRUTURA DE DECISÃO
package main
import (
"fmt"
)
func main() {
var numero int
fmt.Print("Digite um número inteiro: ")
fmt.Scanln(&numero)
if numero > 0 && numero%2 == 0 {
fmt.Println("O número digitado é par.")
} else if numero > 0 && numero%2 != 0 {
fmt.Println("O número digitado é ímpar.")
} else {
fmt.Println("O número digitado é zero ou negativo.")
}
}Condicional else if verifica múltiplas condições.
ESTRUTURA DE DECISÃO
# Exemplo de estrutura aninhada
func podeDirigir() {
var idade, possuiCarteira int
fmt.Println("Digite sua idade: ")
fmt.Scan(&idade)
fmt.Println("Digite 1 se possui carteira ou 0 senão possui: ")
fmt.Scan(&possuiCarteira)
temCarteira := 1 == possuiCarteira
if idade >= 18 {
if temCarteira {
println("Você pode dirigir")
} else {
println("Você não pode dirigir sem carteira.")
}
} else {
println("Você é menor de idade e não pode dirigir.")
}
}ESTRUTURA DE DECISÃO
O switch é uma alternativa mais organizada para múltiplos if-else, especialmente quando há várias condições a serem avaliadas.
switch valor {
case padrão1:
// bloco de código
case padrão2:
// outro bloco
default:
// caso padrão (equivalente ao 'else')
}ESTRUTURA DE DECISÃO
dia := 2
switch dia {
case 1:
fmt.Println("Domingo")
case 2:
fmt.Println("Segunda")
default:
fmt.Println("Outro dia")
}ESTRUTURA DE DECISÃO
switch {
case idade < 18:
fmt.Println("Menor de idade")
case idade >= 18:
fmt.Println("Maior de idade")
}ESTRUTURA DE REPETIÇÃO
O for é o único loop disponível no Go, e pode ser utilizado de diversas formas. Ele pode ser semelhante ao while em outras linguagens, ou usado de forma tradicional com contadores.
for inicialização; condição; incremento {
// Código a ser executado
}for i := 0; i < 5; i++ {
fmt.Println(i)
}Em Go, a única estrutura de repetição é o for, mas ela é bem flexível e cobre os usos de while, do-while e for tradicional de outras linguagens.
Um for pode se comportar como um loop while.
i := 0
for i < 5 {
fmt.Println(i)
i++
}ESTRUTURA DE REPETIÇÃO
for {
fmt.Println("Executando para sempre...")
break // ou use return para sair
}Um Loop Infinito (como while true)
Controle de Loop usando continue
for i := 1; i <= 10; i++ {
if i%2 == 0 {
continue // Pula para a próxima iteração se for par
}
fmt.Println(i) // Só imprime números ímpares
}ESTRUTURA DE REPETIÇÃO
for i := 0; i < 10; i++ {
if i == 5 {
break // Sai do loop quando i for igual a 5
}
fmt.Println(i)
}Controle de Loop com break interrompe imediatamente.
Usando range para itera sobre arrays, slices, strings, mapas ou canais.
numeros := []int{10, 20, 30}
for indice, valor := range numeros {
fmt.Printf("Índice %d: valor %d\n", indice, valor)
}ESTRUTURA DE REPETIÇÃO
texto := "GoLang"
for i, c := range texto {
fmt.Printf("Posição %d: Letra %c\n", i, c)
}Percorrendo uma string (For com range)
Jogo de Adivinhação de Números
O programa gera um número aleatório entre 1 e 10. O usuário deve adivinhar o número. O programa informa se o palpite é alto ou baixo.
Use for e break para repetir até acertar.
EXERCÍCIOS DE FIXAÇÃO
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
rand.Seed(time.Now().UnixNano()) // Garante números aleatórios diferentes a cada execução
numeroSecreto := rand.Intn(10) + 1 // Gera número de 1 a 10
var palpite int
fmt.Println("Adivinhe o número (entre 1 e 10):")
for {
fmt.Print("Digite seu palpite: ")
fmt.Scanln(&palpite)
if palpite < numeroSecreto {
fmt.Println("Muito baixo!")
} else if palpite > numeroSecreto {
fmt.Println("Muito alto!")
} else {
fmt.Println("Parabéns! Você acertou!")
break
}
}
}ARRAYS, SLICES E MAPS
O que é um Array?
Um array é uma sequência de elementos de tamanho fixo e de mesmo tipo. O tamanho do array deve ser especificado na sua criação e não pode ser alterado depois.
// Declaração de um array de 5 inteiros
var numeros [5]int
fmt.Println(numeros)
ARRAYS, SLICES E MAPS
// Inicializando Array
arrayNumeros[0] = 1
arrayNumeros[1] = 2
arrayNumeros[2] = 3
arrayNumeros[3] = 4
arrayNumeros[4] = 5
// Mostrando os valores do array
fmt.Println(arrayNumeros)
ARRAYS, SLICES E MAPS
arrayNomes := [4]string{"Pedro", "Louie", "Maria", "Lourenzo"}
fmt.Println(arrayNomes) // Output: [Pedro Louie Maria Lourenzo]ARRAYS, SLICES E MAPS
// Tamanho do Array utilizando len
arrayNumeros := [5]int{1, 2, 3, 4, 5}
fmt.Printf("Tamanho do Array é [%d]", len(arrayNumeros)) //Output: Tamanho do Array é [5]
for i := 0; i < 5; i++ {
arrayNumeros[i] = i + 10
}
fmt.Println(arrayNumeros) //Output: [10 11 12 13 14]ARRAYS, SLICES E MAPS
for index, value := range arrayNumeros {
fmt.Println("Índice:", index, "Valor: ", value)
}
/*Output:
Índice: 0 Valor: 10
Índice: 1 Valor: 11
Índice: 2 Valor: 12
Índice: 3 Valor: 13
Índice: 4 Valor: 14*/ARRAYS, SLICES E MAPS
// Declarando array 2D de 3 linhas e 3 colunas
array2D := [3][3]int{
{11, 12, 13},
{15, 16, 17},
{19, 20, 21},
}
// Iterando sobre o array 2D
for i := 0; i < len(array2D); i++ {
for j := 0; j < len(array2D[i]); j++ {
fmt.Printf(" %d ", array2D[i][j])
}
fmt.Print("\n")
}
/*Output:
11 12 13
15 16 17
19 20 21
*/EXERCÍCIOS DE FIXAÇÃO
Desenvolva um programa em Go que permita ao usuário visualizar os números que ele escolheu para um sorteio da Loteria Federal.
Instruções:
Exemplo:
Informe os seus números: 06 12 23 34 42 50
O que é um Slice?
ARRAYS, SLICES E MAPS
// Slice criado diretamente do array
sliceNumeros := []int{1, 2, 3, 4, 5}
fmt.Println("Slices numeros: ", sliceNumeros)
// Slice criado vazio
slicesLetras := make([]string, 2)
fmt.Println("Slices letras: ", slicesLetras)A função append() é usada para adicionar elementos a um slice, aumentando seu tamanho dinamicamente.
ARRAYS, SLICES E MAPS
// Add elemento ao sliceNumeros
sliceNumeros := []int{1, 2, 3, 4, 5}
sliceNumeros = append(sliceNumeros, 6)
fmt.Println("Slices numeros: ", sliceNumeros)
// Add elemento ao sliceLetras
slicesLetras = append(slicesLetras, "A")
slicesLetras = append(slicesLetras, "B")
slicesLetras = append(slicesLetras, "C")
slicesLetras = append(slicesLetras, "D")
slicesLetras = append(slicesLetras, "E")
fmt.Println("Slices letras: ", slicesLetras)Detalhando: Um slice em Go é uma estrutura que contém:
// Exemplo
s := make([]int, 0, 5) // make: defini uma capacidade
// Neste exemplo:
// O length é 0;
// A capacity é 5;
// Um array interno de tamanho 5 é alocado para armazenar os dados.
ARRAYS, SLICES E MAPS
Quando usamos:
s = append(s, 1)
/*
o Go:
1. Verifica se ainda há capacidade disponível no array subjacente.
Se houver, ele apenas adiciona o valor no próximo espaço e incrementa o length.
Se não houver capacidade suficiente, o Go:
2. Cria um novo array maior (geralmente o dobro da capacidade anterior),
3. Copia todos os elementos antigos para esse novo array,
4. Adiciona o novo elemento,
E o slice agora aponta para esse novo array.
*/ARRAYS, SLICES E MAPS
Exemplo de comportamento interno:
s := []int{1, 2, 3}
fmt.Println(len(s), cap(s)) // 3 3
s = append(s, 4) // Capacidade estourou!
fmt.Println(len(s), cap(s)) // 4 6 (por exemplo)
//O Go internamente realoca a memória e cria um novo array com uma capacidade maior.
ARRAYS, SLICES E MAPS
💡 Exemplo visual do append com realocação de memória
s := make([]int, 0, 3) // slice com capacidade 3
s = append(s, 1)
s = append(s, 2)
s = append(s, 3)
s = append(s, 4) // aqui a capacidade estoura!ARRAYS, SLICES E MAPS
Antes do append(4):
┌─────┬─────┬─────┐
│ 1 │ 2 │ 3 │ ← slice s (capacidade cheia)
└─────┴─────┴─────┘
Depois do append(4):
┌─────┬─────┬─────┬─────┬─────┬─────┐
│ 1 │ 2 │ 3 │ 4 │ │ │ ← novo array criado
└─────┴─────┴─────┴─────┴─────┴─────┘
↑
slice s agora aponta para este novo array
Como saber se dois slices apontam para o mesmo array?
s1 := []int{1, 2, 3}
s2 := s1
s3 := append(s1, 4, 5, 6, 7) // provavelmente vai realocar
fmt.Printf("s1 pointer: %p\n", &s1[0])
fmt.Printf("s2 pointer: %p\n", &s2[0])
fmt.Printf("s3 pointer: %p\n", &s3[0])
// Output:
// s1 pointer: 0x14000120000
// s2 pointer: 0x14000120000 (mesmo que s1)
// s3 pointer: 0x14000124000 (diferente! novo array criado)ARRAYS, SLICES E MAPS
Iterando sobre Slices: Assim como arrays, slices também podem ser percorridos com um for ou range para iterar sobre os seus elementos
// Iterando slice com for
for i := 0; i < len(sliceNumeros); i++ {
fmt.Println("Slices letras: ", sliceNumeros[i])
}
// Iterando slice com for e range
for i, v := range slicesLetras {
fmt.Printf("Índice: %d, Valor: %s\n", i, v)
}ARRAYS, SLICES E MAPS
Removendo elementos do slice: Remover um elemento de um slice envolve criar um novo slice, excluindo o elemento desejado.
sliceNumeros := []int{1, 2, 3, 4, 5}
sliceNumeros = append(sliceNumeros, 6)
fmt.Println("Slices numeros: ", sliceNumeros)
// Output: Slices numeros: [1 2 3 4 5 6]
sliceNumeros = append(sliceNumeros[:2])
fmt.Println("Slices numeros: ", sliceNumeros)
// Output: Slices numeros: [1 2]
sliceNumeros = append(sliceNumeros[0:2],
sliceNumeros[3:]...)
fmt.Println("Slices numeros: ", sliceNumeros)
// Output: Slices numeros: [1 2 4 5 6]ARRAYS, SLICES E MAPS
sliceNumeros[:2] equivale a sliceNumeros[0:2]
Inclui o índice 0 e 1 (mas não o 2)
A operação não remove os elementos do slice original — ela apenas cria uma nova fatia que aponta para os mesmos elementos até o índice 2.
O que é um Map?
// Cria um map com chave do tipo
// string e valor do tipo int e vazio
mapNomes := make(map[string]int)
fmt.Println("Map Nomes: ", mapNomes)
// Output: Map Nomes: map[]
// Inserindo valores no mapNomes
mapNomes["Raimundo"] = 37
mapNomes["Maria"] = 18
mapNomes["Ana"] = 20
mapNomes["Paula"] = 22
fmt.Println("Map Nomes: ", mapNomes)
//Output: Map Nomes: map[Louie:6 Lourenzo:1 Thálita:36 Vanilton:34]ARRAYS, SLICES E MAPS
Criando map diretamente com uma literal sem o uso do make.
// Criando um map literal sem make
mapProduto := map[int]string{
1: "Resistor 1k Ohm 5%",
2: "Diodo 1N4007",
3: "LED Difuso 5mm Azul",
}
fmt.Println("Map Produto: ", mapProduto)
//Output: Map Produto: map[1:Resistor 1k Ohm 5% 2:Diodo 1N4007 3:LED Difuso 5mm Azul]ARRAYS, SLICES E MAPS
Adicionando itens no Map que já está inicializado.
// Adicionando itens no mapProduto
mapProduto[4] = "Capacitor"
mapProduto[5] = "Placa montada"
fmt.Println("Map Produto: ", mapProduto)
// Output: Map Produto: map[1:Resistor 1k Ohm 5% 2:Diodo 1N4007 3:LED Difuso 5mm Azul 4:Capacitor 5:Placa montada]
Verificando se uma chave existe: Ao acessar um valor, você pode verificar se a chave realmente existe no map usando o segundo valor de retorno da expressão map[chave].
// Verificando se a chave existe em um map
valor, existe := mapProduto[6]
fmt.Println("Map Produto: ", valor, " - ", existe)
// Output: Map Produto: - falseARRAYS, SLICES E MAPS
Removendo elementos com delete(): Você pode remover uma chave e seu valor associado do map usando a função delete().
// Removendo elementos do map com a função delete()
delete(mapProduto, 4)
fmt.Println("Map Produto: ", mapProduto)
// Output: Map Produto: map[1:Resistor 1k Ohm 5% 2:Diodo 1N4007 3:LED Difuso 5mm Azul 5:Placa montada]
Iterando sobre um map com range: Você pode usar um loop range para iterar sobre os pares chave-valor do map.
// Iterando sobre o map usando range
for chave, valor := range mapProduto {
fmt.Printf("Chave: %d, Valor: %s\n", chave, valor)
}ARRAYS, SLICES E MAPS
Tamanho de um map: Você pode usar a função len() para obter o número de pares chave-valor presentes no map.
// Tamanho de um map usando a função len()
fmt.Println("Map Produto: ", len(mapProduto))Map de Maps: Você pode criar mapas cujos valores também são mapas. Isso é útil para representar estruturas mais complexas, como uma tabela de dados ou um dicionário aninhado.
// Criando um map de maps
estoque := map[int]map[string]string{
1: {
"nome": "Resistor 1k",
"categoria": "Eletrônico",
},
2: {
"nome": "LED Azul",
"categoria": "Eletrônico",
},
}
// Acessando um valor
fmt.Println("Produto 1:", estoque[1]["nome"])ARRAYS, SLICES E MAPS
Map de Maps: Percorrendo o mapa de mapas.
// Iterando sobre o map de maps
for id, produto := range estoque {
fmt.Println("ID:", id)
for chave, valor := range produto {
fmt.Printf(" %s: %s\n", chave, valor)
}
}ARRAYS, SLICES E MAPS
EXERCÍCIOS DE FIXAÇÃO
Verificador de Palíndromo:
Escreva um programa que verifique se uma palavra inserida pelo usuário é um palíndromo. Uma palavra é considerada palíndromo se ela pode ser lida da mesma forma de trás para frente, como "arara" ou "radar".
Requisitos:
EXERCÍCIOS DE FIXAÇÃO
Ordenação de Números:
Crie um programa que leia uma lista de números inteiros e os ordene em ordem crescente. Não utilize funções prontas de ordenação, como sort.Sort(). Implemente o algoritmo Bubble Sort manualmente.
Requisitos:
EXERCÍCIOS DE FIXAÇÃO
Soma de Números Pares:
Escreva um programa que solicite uma lista de números inteiros e calcule a soma de todos os números pares presentes na lista.
Requisitos:
PONTEIROS EM GO
O que é um Ponteiro?
Declaração e Uso de Ponteiros:
package main
import "fmt"
func declaracaoPonteiro() {
a := 42 // variável normal
p := &a // p é um ponteiro para a variável a
fmt.Println(p) // Imprime o endereço de memória de a
fmt.Println(*p) // Acessa o valor de a através do ponteiro p
}PONTEIROS EM GO
Quando Usar Ponteiros?
func alterarValor(num *int) {
*num = *num + 10 // Modifica o valor da variável apontada
}
func executarAlteraValor() {
x := 20
alterarValor(&x) // Passamos o endereço de x
fmt.Println(x) // Resultado: 30 (x foi alterado)
}PONTEIROS EM GO
STRUCT EM GO
O que é uma Struct?
Em Go, uma struct (estrutura) é um tipo de dado composto que permite agrupar variáveis de diferentes tipos em uma única unidade lógica. Essas variáveis são chamadas de campos da struct. As structs são muito úteis para organizar dados relacionados em uma única estrutura, como dados de uma pessoa, um produto, um carro, etc. São semelhantes a "objetos" em outras linguagens, mas sem herança.
STRUCT EM GO
Declaração de Structs: Para definir uma struct, usamos a palavra-chave type para nomeá-la, seguida de struct, e depois definimos seus campos.
package main
type Pessoa struct {
Nome string
Idade int
Cidade string
}STRUCT EM GO
Criando e Usando Instâncias de Struct: Podemos criar uma instância da struct e atribuir valores aos seus campos.
func mainStruct() {
// Criando uma instância de Pessoa e definindo valores.
pessoa := Pessoa{
Nome: "Vanilton",
Idade: 34,
Cidade: "Manaus",
}
fmt.Println(pessoa) // Output: {Vanilton 34 Manaus}
fmt.Println("Nome: ", pessoa.Nome) // Output: Nome: Vanilton
}
STRUCT EM GO
Acessando e Modificando Campos: Para acessar ou modificar um campo, usamos a notação ponto (.) seguido pelo nome do campo.
pessoa.Idade = 31
pessoa.Cidade = "Manaus"
fmt.Println("Nova idade:", pessoa.Idade)
fmt.Println("Nova cidade:", pessoa.Cidade)Funções com Structs: Podemos passar structs para funções e manipular seus campos. Para evitar a cópia dos dados, é comum passar o ponteiro da struct para a função.
func atualizarIdade(p *Pessoa, novaIdade int) {
p.Idade = novaIdade // Modifica o campo Idade da struct
} STRUCT EM GO
Structs Aninhadas: Uma struct pode conter outras structs como campos, permitindo construir estruturas de dados mais complexas.
type Endereco struct {
Rua string
Numero int
Cidade string
}
type Pessoa struct {
Nome string
Idade int
Endereco Endereco
}// Criando uma instância de Pessoa e definindo valores
pessoa := Pessoa{
Nome: "Ana",
Idade: 28,
Endereco: Endereco{
Rua: "Rua das Flores",
Numero: 123,
Cidade: "Rio de Janeiro",
},
}
fmt.Println(pessoa)
fmt.Println("Nome:", pessoa.Nome)
fmt.Println("Cidade:", pessoa.Endereco.Cidade)STRUCT EM GO
Modificando um campo do tipo struct aninhado.
// Modificando cidade na struct endereco
pessoa.Endereco.Cidade = "Salvador"
fmt.Println("Nova cidade:", pessoa.Endereco.Cidade)EXERCÍCIO DE FIXAÇÃO
Criar uma aplicação que armazena dados de livros usando structs e manipula essas informações.
Instruções:
EXCEÇÕES
Em Go, não existem exceções no estilo tradicional como em linguagens como Java, Python ou C#. Em vez disso, Go utiliza um sistema explícito de tratamento de erros baseado em valores de retorno e, em situações mais críticas, a função panic.
O que são exceções?
Exceções são eventos que ocorrem durante a execução de um programa que interrompem o fluxo normal do código. Elas podem ser causadas por uma variedade de problemas, como tentar acessar um índice inexistente em uma lista, dividir por zero, abrir um arquivo que não existe, entre outros.
EXCEÇÕES
Retorno explícito de erro
Funções em Go normalmente retornam dois valores: o resultado esperado e um valor do tipo error. O código do consumidor verifica se o erro é nil.
EXCEÇÕES
package main
import (
"errors"
"fmt"
)
func dividir(a, b float64) (float64, error) {
if b == 0 {
return 0, errors.New("divisão por zero não permitida")
}
return a / b, nil
}
func main() {
resultado, err := dividir(10, 0)
if err != nil {
fmt.Println("Erro:", err)
return
}
fmt.Println("Resultado:", resultado)
}Panic e Recover
Use panic para situações inesperadas ou irreversíveis, e recover para capturar um panic e evitar que o programa encerre abruptamente.
EXCEÇÕES
package main
import "fmt"
func podeEntrarEmPanico() {
defer func() {
if r := recover(); r != nil {
fmt.Println("Recuperado do panic:", r)
}
}()
panic("algo deu muito errado")
}
func main() {
podeEntrarEmPanico()
fmt.Println("Continuando execução após recover")
}EXCEÇÕES
package main
import (
"errors"
"fmt"
)
// Struct Endereco
type Endereco struct {
Rua string
Numero int
Cidade string
}
// Struct Pessoa
type Pessoa struct {
Nome string
Idade int
Endereco Endereco
}
func main() {
// Criando pessoa com erro de idade
pessoa := Pessoa{
Nome: "Ana",
Idade: -5,
Endereco: Endereco{
Rua: "Rua das Flores",
Numero: 123,
Cidade: "Salvador",
},
}
// Tratamento de erro com if
if err := verificarIdade(pessoa); err != nil {
fmt.Println("Erro ao verificar idade:", err)
} else {
fmt.Println("Idade válida:", pessoa.Idade)
}
// Teste com panic/recover
pessoa.Endereco.Cidade = "" // Vai causar panic
operacaoCritica(pessoa)
fmt.Println("Programa continua após recover.")
}// Função que verifica idade válida
func verificarIdade(p Pessoa) error {
if p.Idade < 0 {
return errors.New("idade inválida: não pode ser negativa")
}
return nil
}
// Função que simula algo crítico
func operacaoCritica(p Pessoa) {
defer func() {
if r := recover(); r != nil {
fmt.Println("Recuperado de um panic:", r)
}
}()
if p.Endereco.Cidade == "" {
panic("cidade não pode estar vazia")
}
fmt.Println("Operação crítica realizada com sucesso")
}
EXCEÇÕES
Resumindo:
valor, _ := dividir(10, 2)
fmt.Println("Resultado:", valor)REFERÊNCIAS