Fundamentos de Ponteiros em Go
Parte da seção Programação Orientada a Objetos do Journey de GO da Coddy. Lição 19 de 107.
Um ponteiro é uma variável que armazena o endereço de memória de outra variável. Em vez de armazenar um valor diretamente, ele armazena o local onde esse valor reside na memória. Os ponteiros são fundamentais para Go e essenciais para a manipulação eficiente de dados.
Para criar um ponteiro, use o operador & para obter o endereço de uma variável e o operador * para declarar um tipo de ponteiro ou acessar o valor nesse endereço.
x := 42
p := &x // p contém o endereço de memória de x
fmt.Println(p) // 0xc000018030 (endereço de memória)
fmt.Println(*p) // 42 (valor nesse endereço)O operador & significa "endereço de" e retorna um ponteiro. O operador *, quando usado em um ponteiro, significa "valor em" e é chamado de desreferenciação. Você também pode modificar o valor original por meio do ponteiro.
x := 10
p := &x
*p = 25 // altera o valor através do ponteiro
fmt.Println(x) // 25 (variável original alterada)O tipo pointer é escrito como *T, em que T é o tipo apontado. Um pointer para um int tem o tipo *int.
var p *int // declara um ponteiro para int
x := 100
p = &x // p agora aponta para xO valor zero de um ponteiro é nil, o que significa que ele não aponta para nada. Tentar desreferenciar um ponteiro nil causa um pânico em tempo de execução; portanto, sempre garanta que os ponteiros sejam inicializados antes do uso.
Desafio
FácilVamos criar um simples trocador de valores que demonstra o poder dos ponteiros para modificar variáveis por meio de seus endereços de memória.
Você organizará seu código em dois arquivos:
swap.go: Crie uma função chamadaSwapValuesque recebe dois ponteiros*intcomo parâmetros. Essa função deve trocar os valores para os quais esses ponteiros apontam; depois de chamá-la, cada variável deverá conter o valor original da outra. A função não retorna nada; ela modifica os valores diretamente por meio dos ponteiros.main.go: Leia dois números inteiros da entrada, armazene-os em variáveis e use sua funçãoSwapValuespara trocar seus valores. Imprima ambos os valores antes e depois da troca para mostrar a alteração.
As seguintes entradas serão fornecidas:
- Linha 1: Primeiro número inteiro
- Linha 2: Segundo número inteiro
Formato da saída:
Before: a=[first] b=[second]
After: a=[first] b=[second]Por exemplo, dados 10 e 25, sua saída deverá ser:
Before: a=10 b=25
After: a=25 b=10Lembre-se de usar o operador & ao passar suas variáveis para a função e o operador * dentro da função para acessar e modificar os valores reais.
Experimente você mesmo
package main
import "fmt"
func main() {
// Lê dois inteiros da entrada
var a, b int
fmt.Scanln(&a)
fmt.Scanln(&b)
// Imprime os valores antes da troca
fmt.Printf("Before: a=%d b=%d\n", a, b)
// TODO: Chame a função SwapValues com ponteiros para a e b
// Lembre-se de usar o operador & para passar os endereços
// Imprime os valores depois da troca
fmt.Printf("After: a=%d b=%d\n", a, b)
}
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação Orientada a Objetos
1Fundamentos de OOP em Go
Arquivos ExternosWorkspace e Módulos do GoPacotes e ImportsNomes Exportados vs. Não ExportadosIntrodução à OOP em GoStructs como ClassesDefinindo Métodos em StructsReceptores de Ponteiro vs. de ValorInicialização de StructsFunções ConstrutorasRecapitulação — Calculadora Simples4Interfaces
Introdução às InterfacesImplementação ImplícitaInterface como ContratoInterface Vazia (any)Asserção de TipoSwitch de TipoComposição de InterfacesInterfaces Stringer e ErrorRecapitulação - Calculadora de Formas7Encapsulamento
Campos Exportados vs. Não ExportadosEncapsulamento no Nível de PacoteMétodos Getters e SettersOcultação de Informações em GoRecapitulação - Registros de Alunos10Genéricos (Go 1.18+)
Introdução aos genéricosParâmetros de tipoRestrições de tipoStructs genéricasAlternativa para métodos genéricosRecapitulação - Coleção genérica13Padrões de Projeto — Parte 1
Introdução aos Padrões de ProjetoPadrão SingletonPadrão FactoryPadrão Abstract FactoryPadrão ObserverPadrão Strategy2Tipos e Structs em Profundidade
Tipos Básicos e CompostosDefinições de Tipos PersonalizadosTags de StructStructs AnônimasStructs AninhadasValores Zero e PadrõesRecapitulação - Livro de Contatos5Composição em vez de herança
Por que Go não tem herançaNoções básicas de incorporação de structsPromoção de métodosIncorporação de várias structsIncorporação vs agregaçãoOcultação de métodos incorporadosRecapitulação - Hierarquia de funcionários8Tratamento de Erros e OOP
A interface errorTipos de Erro PersonalizadosEncapsulamento de Erros (fmt.Errorf)Erros Sentinelaerrors.Is() e errors.As()Panic, Defer e RecoverRecapitulação - Analisador de Arquivos3Ponteiros e Memória
Fundamentos de Ponteiros em GoPonteiros para StructsPassagem por Valor vs. ReferênciaA Função new()Coleta de Lixo em GoRecapitulação - Construtor de Lista Ligada6Polimorfismo em Go
Polimorfismo via InterfacesDuck Typing em GoRegras de Satisfação de InterfacesColeções PolimórficasInjeção de DependênciasRecapitulação - Processador de Pagamentos9Concorrência e OOP
Fundamentos de GoroutinesCanais e comunicaçãoCanais com e sem bufferInstrução selectsync.Mutex e sync.RWMutexsync.WaitGroupDesign de structs thread-safeRevisão - Worker PoolPratique por conta própria: Compilador de Go online