Recebedores de Ponteiro
Parte da seção Lógica & Fluxo do Journey de GO da Coddy — lição 8 de 68.
Enquanto receivers de valor trabalham com cópias de structs, receivers de ponteiro trabalham diretamente com a instância original da struct. Quando você define um método com um receiver de ponteiro, o método pode modificar os dados originais porque ele recebe um ponteiro para a struct em vez de uma cópia.
Para criar um receptor de ponteiro, você adiciona um asterisco * antes do nome do tipo na declaração do receptor:
type Person struct {
Name string
Age int
}
func (p *Person) haveBirthday() {
p.Age++ // Isso modifica a struct original
}Neste exemplo, (p *Person) é um receptor de ponteiro (pointer receiver). Quando você chama o método haveBirthday em uma instância de Person, o método recebe um ponteiro para a struct original. Quaisquer alterações feitas nos campos da struct através deste ponteiro modificarão permanentemente os dados originais.
Recebedores de ponteiro são essenciais quando seus métodos precisam atualizar os campos da struct, tornando-os perfeitos para operações que alteram o estado dos seus dados.
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Desafio
FácilNeste desafio, você praticará a criação de métodos com receptores de ponteiro (pointer receivers) construindo um sistema simples de conta bancária. Você criará uma struct Account e definirá métodos que podem modificar o saldo da conta usando receptores de ponteiro.
Você receberá três entradas:
- Uma string representando o nome do titular da conta (ex:
"John Smith") - Uma string representando o saldo inicial da conta (ex:
"1000.50") - Uma string representando o valor de uma transação (ex:
"250.75")
Sua tarefa é:
- Definir uma struct
Accountcom dois campos:Name(string) eBalance(float64) - Criar um método chamado
depositcom um receptor de ponteiro que adiciona o valor fornecido ao saldo da conta - Criar um método chamado
withdrawcom um receptor de ponteiro que subtrai o valor fornecido do saldo da conta - Criar um método chamado
displayBalancecom um receptor de valor que imprime as informações da conta no formato:"Account: [name], Balance: $[balance]" - Analisar as entradas para criar uma instância de
Account - Chamar
displayBalancepara mostrar o saldo inicial - Chamar
depositcom o valor da transação - Chamar
displayBalancepara mostrar o saldo após o depósito - Chamar
withdrawcom o valor da transação - Chamar
displayBalancepara mostrar o saldo final
O saldo deve ser exibido com precisão de duas casas decimais. Este desafio demonstra como os receptores de ponteiro permitem que os métodos modifiquem os dados da struct original, ao contrário dos receptores de valor que trabalham com cópias.
Folha de consulta
Recebedores de ponteiro (pointer receivers) trabalham diretamente com a instância original da struct ao receber um ponteiro para a struct em vez de uma cópia. Isso permite que os métodos modifiquem os dados originais.
Para criar um recebedor de ponteiro, adicione um asterisco * antes do nome do tipo na declaração do recebedor:
type Person struct {
Name string
Age int
}
func (p *Person) haveBirthday() {
p.Age++ // Isso modifica a struct original
}Use recebedores de ponteiro quando seus métodos precisarem atualizar os campos da struct, tornando-os perfeitos para operações que alteram o estado dos seus dados.
Experimente você mesmo
package main
import (
"fmt"
"strconv"
)
// TODO: Defina a struct Account aqui
// TODO: Defina o método deposit com um pointer receiver aqui
// TODO: Defina o método withdraw com um pointer receiver aqui
// TODO: Defina o método displayBalance com um value receiver aqui
func main() {
// Ler a entrada
var name string
var initialBalanceStr string
var transactionAmountStr string
fmt.Scanln(&name)
fmt.Scanln(&initialBalanceStr)
fmt.Scanln(&transactionAmountStr)
// Converter as entradas de string para os tipos apropriados
initialBalance, _ := strconv.ParseFloat(initialBalanceStr, 64)
transactionAmount, _ := strconv.ParseFloat(transactionAmountStr, 64)
// TODO: Criar uma instância de Account
// TODO: Exibir o saldo inicial, realizar o depósito, exibir o saldo, realizar o saque, exibir o saldo final
}Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Lógica & Fluxo
1Fluxo de Controle Avançado
Switch com `fallthrough`Interrompendo Loops AninhadosContinuando um Loop EspecíficoA Instrução `goto`Recapitulação - Controle de Loop Avançado4Projeto: Lista de Tarefas Simples
Configuração do ProjetoAdicionando uma Tarefa2Structs e Métodos
Definindo Métodos em StructsRecebedores de ValorRecebedores de PonteiroEscolhendo RecebedoresMétodos vs FunçõesRecapitulação - Comportamento de Structs5Mapas em Profundidade
Mapas de StructsPonteiros como Valores de MapVerificando Mapas NilComparando MapasRecapitulação - Contador de Frequência de Palavras3Interfaces (O Básico)
O que é uma Interface?Definindo uma InterfaceImplementando uma InterfaceUsando Tipos de InterfaceInterface VaziaAsserções de TipoType SwitchRecapitulação - Formas e Comportamentos