Lidar com ponteiros pela primeira vez assusta quem vem de linguagens como JavaScript, Python ou Java, onde a gestão de memória é automática
Mas a ideia é mais simples do que parece.
O que são ponteiros?
Toda variável ocupa um espaço na memória, e esse espaço possui um endereço.
Um ponteiro é uma variável que guarda o endereço de outra variável, em vez de guardar diretamente o seu valor.
x := 10
p := &x
fmt.Println(*p) // 10
x guarda 10.
p guarda o endereço de x.
E *p acessa o valor que está naquele endereço.
Operadores Cruciais
&: Descobre o "endereço de" uma variável.
*: Acessa ou modifica o "valor apontado por" um ponteiro.
Tambem é sintaxe para indicar uma variavel é do tipo ponteiro
Por que usar ponteiros?
Principalmente para trabalhar com a mesma instância de um dado, evitando cópias desnecessárias.
func changeName(user *User) {
user.Name = "João"
}
user := User{Name: "Lucas"}
changeName(&user)
fmt.Println(user.Name) // João
A função recebeu o endereço do user, então modificou o objeto original.
Sem ponteiro:
func changeName(user User) {
user.Name = "João"
}
A função receberia uma cópia e o user original não seria alterado.
Um exemplo real
Em uma API, podemos criar uma única instância do banco:
db, _ := sql.Open("postgres", dsn)
userRepo := NewUserRepository(db)
orderRepo := NewOrderRepository(db)
E os repositories podem compartilhar a mesma instância:
type UserRepository struct {
db *sql.DB
}
*sql.DB
│
┌────────┴────────┐
↓ ↓
UserRepository OrderRepository
A ideia principal que estou levando do estudo de Go:
Ponteiros permitem trabalhar com a mesma instância de um dado, em vez de necessariamente criar cópias.
E uma regra prática:
- Use valor por padrão.
Use ponteiro quando precisar:
- compartilhar/modificar a mesma instância,
- representar
nil/null - evitar uma cópia relevante ou muito grande.
Top comments (0)