Receptores de ponteiro em métodos
Altere o estado de uma struct por meio de receptores de ponteiro
Receptores de ponteiro em métodos é uma aula grátis de Go Academy no CoddyKit. Esta é a aula 3 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Go Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Go Academy inclui 4 aulas no total.
Recapitulação: Receptor de Valor versus Ponteiro
Um receptor de valor opera sobre uma cópia da estrutura. Um receptor de ponteiro opera sobre o original. Use receptores de ponteiro sempre que um método precisar modificar o estado.
Mutação com Receptor de Ponteiro
Somente um receptor de ponteiro pode alterar a estrutura:
package main
import "fmt"
type Stack struct{ items []int }
func (s *Stack) Push(v int) { s.items = append(s.items, v) }
func (s *Stack) Pop() int {
n := len(s.items) - 1
v := s.items[n]
s.items = s.items[:n]
return v
}
func main() {
var st Stack
st.Push(1); st.Push(2)
fmt.Println(st.Pop()) // 2
}Regra de Consistência
Se algum método de um tipo precisar de um receptor de ponteiro, todos os métodos deverão usar receptores de ponteiro. Misturá-los causa problemas para satisfazer interfaces:
package main
import "fmt"
type Counter struct{ n int }
func (c *Counter) Inc() { c.n++ } // pointer
func (c *Counter) Val() int { return c.n } // pointer too
func main() {
c := &Counter{}
c.Inc(); c.Inc()
fmt.Println(c.Val()) // 2
}Satisfação de Interfaces
Um método com receptor de ponteiro está apenas no conjunto de métodos de *T, não de T. Isso afeta a satisfação de interfaces:
package main
import "fmt"
type Writer interface{ Write([]byte) }
type File struct{ name string }
func (f *File) Write(b []byte) { fmt.Println(string(b)) }
func main() {
var w Writer = &File{"out.txt"} // OK
// var w Writer = File{} — compile error
w.Write([]byte("hello"))
}Obtenção Automática do Endereço
Go obtém automaticamente o endereço ao chamar um método com receptor de ponteiro sobre um valor endereçável:
package main
import "fmt"
type Box struct{ V int }
func (b *Box) Double() { b.V *= 2 }
func main() {
b := Box{5}
b.Double() // Go does (&b).Double()
fmt.Println(b.V) // 10
}Valores Não Endereçáveis
Não é possível chamar métodos com receptor de ponteiro sobre valores não endereçáveis (elementos de mapas e valores retornados por funções que não foram atribuídos a variáveis):
package main
type T struct{ V int }
func (t *T) Set(v int) { t.V = v }
func getT() T { return T{} }
func main() {
var t T
t.Set(1) // OK — t is addressable
// getT().Set(1) — ERROR: cannot take address of getT()
_ = t
}Receptores para Estruturas Grandes
Use sempre receptores de ponteiro para estruturas grandes, a fim de evitar cópias dispendiosas em cada chamada de método:
package main
type Image struct{ pixels [1024][1024]uint8 }
// Value receiver copies 1MB per call!
func (img Image) Bad() uint8 { return img.pixels[0][0] }
// Pointer receiver — zero copy
func (img *Image) Good() uint8 { return img.pixels[0][0] }
func main() { _ = Image{} }Receptores de Ponteiro Nil
Métodos com receptores de ponteiro podem tratar nil de maneira adequada:
package main
import "fmt"
type List struct{ head *node }
type node struct{ val int; next *node }
func (l *List) Len() int {
if l == nil { return 0 }
count := 0
for n := l.head; n != nil; n = n.next { count++ }
return count
}
func main() {
var l *List
fmt.Println(l.Len()) // 0
}Incorporação e Receptores de Ponteiro
Ao incorporar um tipo com receptores de ponteiro, a estrutura externa também deverá ser usada como ponteiro para obter os métodos promovidos:
package main
import "fmt"
type Base struct{ V int }
func (b *Base) Set(v int) { b.V = v }
type Derived struct{ Base }
func main() {
d := &Derived{}
d.Set(42) // promoted pointer-receiver method
fmt.Println(d.V) // 42
}Cópia de Mutexes
Nunca copie uma estrutura que contenha um sync.Mutex — use sempre um receptor de ponteiro ou passe por ponteiro. Copiar um mutex bloqueado resulta em um deadlock:
package main
import "sync"
type Safe struct {
mu sync.Mutex
v int
}
// Correct: pointer receiver
func (s *Safe) Set(v int) {
s.mu.Lock()
defer s.mu.Unlock()
s.v = v
}
func main() { _ = Safe{} }go vet Detecta Erros
Execute go vet ./... para detectar erros comuns relacionados a receptores de ponteiro, como cópias de mutexes e bloqueios. Ele faz parte dos fluxos de go build e das verificações de CI.
Verificação Rápida
Um método com receptor de ponteiro pertence ao conjunto de métodos de quais tipos?
Recapitulação
Principais conclusões:
- Receptores de ponteiro fazem mutações; receptores de valor não
- Mantenha todos os métodos de um tipo usando a mesma espécie de receptor
- Somente
*Tsatisfaz interfaces que exigem métodos com receptores de ponteiro - Nunca copie estruturas com mutexes — use receptores de ponteiro
Proposta de Prática
Implemente uma estrutura Queue com os métodos Enqueue(int), Dequeue() (int, bool) e Len() int, todos com receptores de ponteiro e respaldados por uma fatia []int.
Perguntas Frequentes
A aula “Receptores de ponteiro em métodos” é grátis?
Sim — o texto completo de “Receptores de ponteiro em métodos” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Go Academy, atualize para CoddyKit PRO. O curso de Go Academy inclui 4 aulas no total.
O que vou aprender em “Receptores de ponteiro em métodos”?
Altere o estado de uma struct por meio de receptores de ponteiro Você pratica Go Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Go Academy?
Nenhuma experiência prévia é necessária. Go Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 4.
Quanto tempo leva a aula “Receptores de ponteiro em métodos”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Go Academy?
Sim. Cada aula de Go Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- O que são ponteiros?
- Ponteiros e funções
- Receptores de ponteiro em métodos
- new() e quando usar ponteiros