Go Pointers
āĻĒāϝāĻŧā§āύā§āĻāĻžāϰ āĻšāϞ⧠āĻāĻŽāύ āĻāĻāĻāĻŋ āĻā§āϝāĻžāϰāĻŋāϝāĻŧā§āĻŦāϞ āϝāĻž āĻ āύā§āϝ āĻāĻāĻāĻŋ āĻā§āϝāĻžāϰāĻŋāϝāĻŧā§āĻŦāϞā§āϰ āĻŽā§āĻŽā§āϰāĻŋ āĻ ā§āϝāĻžāĻĄā§āϰā§āϏ āϧāϰ⧠āϰāĻžāĻā§āĨ¤ āϏāĻšāĻ āĻāĻžāώāĻžāϝāĻŧ: āĻĒāϝāĻŧā§āύā§āĻāĻžāϰ āĻā§āϝāĻžāϞ⧠āύāĻŋāĻā§ āύāĻž āϰā§āĻā§ āĻā§āϝāĻžāϞā§āĻāĻŋ āĻā§āĻĨāĻžāϝāĻŧ āĻāĻā§ āϏā§āĻāĻž āĻāĻžāύā§āĨ¤
đ āĻ ā§āϝāĻžāύāĻžāϞāĻāĻŋ: āĻā§āϝāĻžāϰāĻŋāϝāĻŧā§āĻŦāϞ āĻšāϞ⧠āĻŦāĻžāĻĄāĻŧāĻŋ, āĻĒāϝāĻŧā§āύā§āĻāĻžāϰ āĻšāϞ⧠āϏā§āĻ āĻŦāĻžāĻĄāĻŧāĻŋāϰ āĻ āĻŋāĻāĻžāύāĻž.
ā§§. Core Operators đ
| Operator | āύāĻžāĻŽ | āĻāĻžāĻ | āĻāĻĻāĻžāĻšāϰāĻŖ |
|---|---|---|---|
& | Address-of | āĻā§āϝāĻžāϰāĻŋāϝāĻŧā§āĻŦāϞā§āϰ āĻŽā§āĻŽā§āϰāĻŋ āĻ ā§āϝāĻžāĻĄā§āϰā§āϏ āĻŦā§āϰ āĻāϰ⧠| ptr := &x |
* | Dereference | āĻĒāϝāĻŧā§āύā§āĻāĻžāϰā§āϰ āĻ ā§āϝāĻžāĻĄā§āϰā§āϏ⧠āĻĨāĻžāĻāĻž āĻā§āϝāĻžāϞ⧠āĻĒāĻĄāĻŧā§/āĻĒāϰāĻŋāĻŦāϰā§āϤāύ āĻāϰ⧠| fmt.Println(*ptr) |
*T | Pointer type | T āĻāĻžāĻāĻĒā§āϰ āĻĒāϝāĻŧā§āύā§āĻāĻžāϰ āĻĄāĻŋāĻā§āϞā§āϝāĻŧāĻžāϰ āĻāϰ⧠| var p *int |
x := 42
ptr := &x // ptr = x-āĻāϰ āĻŽā§āĻŽā§āϰāĻŋ āĻ
ā§āϝāĻžāĻĄā§āϰā§āϏ (āϝā§āĻŽāύ 0xc000014070)
fmt.Println(x) // 42 â āϏāϰāĻžāϏāϰāĻŋ āĻā§āϝāĻžāϞā§
fmt.Println(&x) // 0xc... â x-āĻāϰ āĻ
ā§āϝāĻžāĻĄā§āϰā§āϏ
fmt.Println(ptr) // 0xc... â ptr-āĻ āĻĨāĻžāĻāĻž āĻ
ā§āϝāĻžāĻĄā§āϰā§āϏ (same)
fmt.Println(*ptr) // 42 â ptr-āĻāϰ āĻ
ā§āϝāĻžāĻĄā§āϰā§āϏ⧠āϝāĻž āĻāĻā§
*ptr = 100 // x-āĻāϰ āĻā§āϝāĻžāϞ⧠āĻĒāϰāĻŋāĻŦāϰā§āϤāύ āĻāϰāĻž āĻšāϞā§
fmt.Println(x) // 100 â
⧍. āĻā§āύ āĻĒāϝāĻŧā§āύā§āĻāĻžāϰ āĻĻāϰāĻāĻžāϰ?
| āĻāĻžāϰāĻŖ | āĻŦā§āϝāĻžāĻā§āϝāĻž |
|---|---|
| āĻĢāĻžāĻāĻļāύā§āϰ āĻā§āϤāϰ āĻĨā§āĻā§ original āĻĒāϰāĻŋāĻŦāϰā§āϤāύ | Go-āϤ⧠āϏāĻŦ argument copy āĻšāĻŋāϏā§āĻŦā§ āϝāĻžāϝāĻŧ; pointer āĻĻāĻŋāϞ⧠original āĻĒāϰāĻŋāĻŦāϰā§āϤāύ āϏāĻŽā§āĻāĻŦ |
| āĻŦāĻĄāĻŧ struct-āĻāϰ copy āĻāĻĄāĻŧāĻžāύ⧠| Pointer āĻĒāĻžāϏ āĻāϰāϞ⧠āĻĒā§āϰ⧠struct copy āĻšāϝāĻŧ āύāĻž â performance āĻāĻžāϞ⧠|
| Optional value āĻĒā§āϰāĻāĻžāĻļ āĻāϰāĻž | nil āĻĻāĻŋāϝāĻŧā§ âāĻā§āύ⧠āĻā§āϝāĻžāϞ⧠āύā§āĻâ āĻŦā§āĻāĻžāύ⧠āϝāĻžāϝāĻŧ |
// â Copy āĻšāϝāĻŧ â original āĻĒāϰāĻŋāĻŦāϰā§āϤāύ āĻšāϝāĻŧ āύāĻž
func doubleWrong(n int) {
n = n * 2
}
// â
Pointer â original āĻĒāϰāĻŋāĻŦāϰā§āϤāύ āĻšāϝāĻŧ
func double(n *int) {
*n = *n * 2
}
func main() {
x := 5
doubleWrong(x)
fmt.Println(x) // 5 â āĻ
āĻĒāϰāĻŋāĻŦāϰā§āϤāĻŋāϤ
double(&x)
fmt.Println(x) // 10 â
}ā§Š. Pointer āĻāĻŦāĻ Struct (Production Usage)
type User struct {
Name string
Email string
}
// â Value â struct-āĻāϰ copy āĻĒāĻžāϏ āĻšāϝāĻŧ
func greetValue(u User) {
u.Name = "Changed" // original-āĻ āĻā§āύ⧠āĻĒā§āϰāĻāĻžāĻŦ āύā§āĻ
}
// â
Pointer â original struct āĻĒāĻžāϏ āĻšāϝāĻŧ
func greetPointer(u *User) {
u.Name = "Changed" // original āĻĒāϰāĻŋāĻŦāϰā§āϤāύ āĻšāϝāĻŧ
}
func main() {
u := User{Name: "Rahim", Email: "rahim@email.com"}
greetValue(u)
fmt.Println(u.Name) // "Rahim" â āĻ
āĻĒāϰāĻŋāĻŦāϰā§āϤāĻŋāϤ
greetPointer(&u)
fmt.Println(u.Name) // "Changed" â
}đĄ Note: Struct field access-āĻ Go āϏā§āĻŦāϝāĻŧāĻāĻā§āϰāĻŋāϝāĻŧāĻāĻžāĻŦā§ pointer dereference āĻāϰā§āĨ¤ āϤāĻžāĻ
(*u).NameāύāĻž āϞāĻŋāĻā§ āϏāϰāĻžāϏāϰāĻŋu.NameāϞā§āĻāĻž āϝāĻžāϝāĻŧāĨ¤
ā§Ē. nil Pointer â āϏāĻŦāĻā§āϝāĻŧā§ Common Bug â ī¸
Pointer declare āĻāϰāϞ⧠āĻāĻŋāύā§āϤ⧠initialize āύāĻž āĻāϰāϞ⧠āĻāϰ default value āĻšāϝāĻŧ nil.
var ptr *int // nil â āĻā§āύ⧠āĻ
ā§āϝāĻžāĻĄā§āϰā§āϏ āύā§āĻ
fmt.Println(ptr) // <nil>
fmt.Println(*ptr) // đĨ panic: nil pointer dereferenceāϏāĻŽāĻžāϧāĻžāύ â āϏāĻŦāϏāĻŽāϝāĻŧ nil check āĻāϰā§āύ:
func printValue(ptr *int) {
if ptr == nil {
fmt.Println("āĻā§āύ⧠āĻā§āϝāĻžāϞ⧠āύā§āĻ")
return
}
fmt.Println(*ptr)
}new() āĻĻāĻŋāϝāĻŧā§ initialized pointer āϤā§āϰāĻŋ:
ptr := new(int) // *int āϤā§āϰāĻŋ, zero value (0) āĻĻāĻŋāϝāĻŧā§ initialize
*ptr = 42
fmt.Println(*ptr) // 42ā§Ģ. Value vs Pointer â āĻā§āύāĻāĻž āĻāĻāύ? đĨ
| āĻĒāϰāĻŋāϏā§āĻĨāĻŋāϤāĻŋ | āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§āύ |
|---|---|
| āĻā§āĻ āĻĄā§āĻāĻž, āĻļā§āϧ⧠read āĻāϰāĻŦā§āύ | Value |
| āĻĢāĻžāĻāĻļāύ⧠original āĻĒāϰāĻŋāĻŦāϰā§āϤāύ āĻāϰāϤ⧠āĻšāĻŦā§ | Pointer |
| āĻŦāĻĄāĻŧ struct āĻĒāĻžāϏ āĻāϰāĻā§āύ | Pointer |
| âāĻā§āϝāĻžāϞ⧠āύā§āĻâ āĻŦā§āĻāĻžāϤ⧠āĻšāĻŦā§ (optional) | Pointer (nil) |
sync.Mutex āĻŦāĻž non-copyable type | Pointer (āĻŦāĻžāϧā§āϝāϤāĻžāĻŽā§āϞāĻ) |
| Slice, Map, Channel āĻĒāĻžāϏ āĻāϰāĻā§āύ | Value (āĻāĻā§āϞ⧠āύāĻŋāĻā§āĻ reference type) |
ā§Ŧ. Go āϏāĻŦāϏāĻŽāϝāĻŧ Pass by Value (Most Asked Interview Topic) đĨ
āĻāĻāĻŋ Go-āϰ āϏāĻŦāĻā§āϝāĻŧā§ āĻŦā§āĻļāĻŋ āĻāĻŋāĻā§āĻā§āϏ āĻāϰāĻž interview āĻĒā§āϰāĻļā§āύāĻā§āϞā§āϰ āĻāĻāĻāĻŋāĨ¤
Go-āϤ⧠āĻĢāĻžāĻāĻļāύ⧠argument āĻĒāĻžāϏ āĻāϰāĻžāϰ āϏāĻŽāϝāĻŧ āϏāĻŦāϏāĻŽāϝāĻŧ āĻāĻāĻāĻŋ copy āϤā§āϰāĻŋ āĻšāϝāĻŧāĨ¤ Pointer āĻĒāĻžāϏ āĻāϰāϞā§āĻ copy āĻšāϝāĻŧ â āϤāĻŦā§ āϏā§āĻā§āώā§āϤā§āϰ⧠address-āĻāϰ copy āĻšāϝāĻŧāĨ¤
func changeValue(n int) {
n = 99 // int-āĻāϰ copy, original āĻ
āĻĒāϰāĻŋāĻŦāϰā§āϤāĻŋāϤ
}
func changePointer(n *int) {
*n = 99 // address-āĻāϰ copy, āĻāĻŋāύā§āϤ⧠āϏā§āĻ address-āĻ āĻāĻŋāϝāĻŧā§ original āĻĒāϰāĻŋāĻŦāϰā§āϤāύ āĻāϰāĻž āĻšāϝāĻŧ
}
func main() {
x := 10
changeValue(x)
fmt.Println(x) // 10 â āĻ
āĻĒāϰāĻŋāĻŦāϰā§āϤāĻŋāϤ
changePointer(&x)
fmt.Println(x) // 99 â
â original āĻĒāϰāĻŋāĻŦāϰā§āϤāĻŋāϤ
}| āĻā§ āĻĒāĻžāϏ āĻšāϝāĻŧ | āĻāĻĒāĻŋ āĻšāϝāĻŧ | Original āĻĒāϰāĻŋāĻŦāϰā§āϤāύ āĻšāϝāĻŧ? |
|---|---|---|
int, string, struct (value) | āĻĒā§āϰ⧠āĻā§āϝāĻžāϞā§āϰ āĻāĻĒāĻŋ | â āύāĻž |
*int, *struct (pointer) | address-āĻāϰ āĻāĻĒāĻŋ (ā§Ē/ā§Ž āĻŦāĻžāĻāĻ) | â āĻšā§āϝāĻžāĻ (dereference āĻāϰāϞā§) |
đĄ āĻŽā§āϞ āĻāĻĨāĻž: Pointer āĻĒāĻžāϏ āĻāϰāĻž āĻŽāĻžāύ⧠âpass by referenceâ āύāϝāĻŧāĨ¤ Go-āϤ⧠reference āύā§āĻāĨ¤ Pointer āĻšāϞ⧠address-āĻāϰ value â āϏā§āĻāĻžāĻ copy āĻšāĻŋāϏā§āĻŦā§āĻ āϝāĻžāϝāĻŧāĨ¤
ā§. Pointer vs Reference Type (Interview Critical)
Go-āϤ⧠āĻāĻŋāĻā§ built-in type āĻāĻā§ āϝā§āĻā§āϞ⧠āĻāϤāĻŋāĻŽāϧā§āϝ⧠reference-āĻāϰ āĻŽāϤ⧠āĻāĻāϰāĻŖ āĻāϰā§:
| Type | Pointer āĻĻāϰāĻāĻžāϰ? | āĻāĻžāϰāĻŖ |
|---|---|---|
int, string, bool, struct | â āĻĻāϰāĻāĻžāϰ āĻšāϞ⧠| Value type â copy āĻšāϝāĻŧ |
slice | â āϏāĻžāϧāĻžāϰāĻŖāϤ āύāĻž | Internal pointer āĻāĻā§ |
map | â āύāĻž | Reference type |
channel | â āύāĻž | Reference type |
interface | â āύāĻž | Reference type |
// Map-āĻ pointer āĻĻāϰāĻāĻžāϰ āύā§āĻ â āĻĢāĻžāĻāĻļāύ⧠āĻĒāĻžāϏ āĻāϰāϞā§āĻ original update āĻšāϝāĻŧ
func addUser(m map[string]int, name string) {
m[name] = 1 // â
original map-āĻ update āĻšāϝāĻŧ
}ā§Ž. Common Mistakes â ī¸
| āĻā§āϞ | āϏāĻŽāϏā§āϝāĻž | āϏāĻŽāĻžāϧāĻžāύ |
|---|---|---|
| nil pointer dereference | runtime panic | āĻŦā§āϝāĻŦāĻšāĻžāϰā§āϰ āĻāĻā§ if ptr != nil āĻā§āĻ āĻāϰā§āύ |
| Loop variable pointer | āϏāĻŦ pointer āĻāĻāĻ āĻļā§āώ āĻā§āϝāĻžāϞ⧠āĻĻā§āĻāĻžāϝāĻŧ | loop-āĻāϰ āĻā§āϤāϰ⧠āĻāϞāĻžāĻĻāĻž āĻā§āϝāĻžāϰāĻŋāϝāĻŧā§āĻŦāϞ āϤā§āϰāĻŋ āĻāϰā§āύ |
| Slice/Map-āĻ āĻ āĻāĻžāϰāĻŖā§ pointer | unnecessary complexity | āĻāϰāĻž āύāĻŋāĻā§āĻ reference, pointer āϞāĻžāĻā§ āύāĻž |
new() āĻ &{} confusion | â | āĻĻā§āĻā§āĻ āĻāĻžāĻ āĻāϰā§, &Struct{} āĻŦā§āĻļāĻŋ idiomatic |
// â Classic loop pointer bug
ptrs := make([]*int, 3)
for i := 0; i < 3; i++ {
ptrs[i] = &i // āϏāĻŦ pointer āĻļā§āώ⧠i=3 āĻĻā§āĻāĻžāĻŦā§!
}
// â
āϏāĻŽāĻžāϧāĻžāύ â local copy āϤā§āϰāĻŋ āĻāϰā§āύ
for i := 0; i < 3; i++ {
v := i
ptrs[i] = &v
}⧝. Interview Cheat Sheet
Q: āĻĒāϝāĻŧā§āύā§āĻāĻžāϰ āĻā§ āĻāĻŦāĻ āĻā§āύ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻž āĻšāϝāĻŧ?
āĻĒāϝāĻŧā§āύā§āĻāĻžāϰ āĻāĻāĻāĻŋ āĻā§āϝāĻžāϰāĻŋāϝāĻŧā§āĻŦāϞā§āϰ āĻŽā§āĻŽā§āϰāĻŋ āĻ ā§āϝāĻžāĻĄā§āϰā§āϏ āϧāϰ⧠āϰāĻžāĻā§āĨ¤ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻšāϝāĻŧ: original value āĻĒāϰāĻŋāĻŦāϰā§āϤāύ āĻāϰāϤā§, āĻŦāĻĄāĻŧ struct copy āĻāĻĄāĻŧāĻžāϤ⧠āĻāĻŦāĻ optional value āĻĒā§āϰāĻāĻžāĻļ āĻāϰāϤā§āĨ¤
Q: & āĻāĻŦāĻ *-āĻāϰ āĻĒāĻžāϰā§āĻĨāĻā§āϝ āĻā§?
&āĻĻāĻŋāϝāĻŧā§ āĻā§āϝāĻžāϰāĻŋāϝāĻŧā§āĻŦāϞā§āϰ āĻ ā§āϝāĻžāĻĄā§āϰā§āϏ āύā§āĻāϝāĻŧāĻž āĻšāϝāĻŧāĨ¤*āĻĻāĻŋāϝāĻŧā§ āĻĒāϝāĻŧā§āύā§āĻāĻžāϰā§āϰ āĻ ā§āϝāĻžāĻĄā§āϰā§āϏ⧠āĻĨāĻžāĻāĻž āĻā§āϝāĻžāϞ⧠access āĻāϰāĻž āĻšāϝāĻŧ (dereference)āĨ¤
Q: Pointer-āĻāϰ zero value āĻā§?
nilâ āĻŽāĻžāύ⧠āĻāĻāĻŋ āĻā§āύ⧠āĻŽā§āĻŽā§āϰāĻŋ āĻ ā§āϝāĻžāĻĄā§āϰā§āϏ point āĻāϰāĻā§ āύāĻžāĨ¤
Q: Slice āĻŦāĻž Map-āĻ āĻāĻŋ Pointer āĻĻāϰāĻāĻžāϰ?
āϏāĻžāϧāĻžāϰāĻŖāϤ āύāĻžāĨ¤ Slice āĻ Map āύāĻŋāĻā§āĻ internally reference type â āĻĢāĻžāĻāĻļāύ⧠āĻĒāĻžāϏ āĻāϰāϞ⧠original-āĻ āĻāĻžāĻ āĻšāϝāĻŧāĨ¤
Q: new(T) āĻāĻŦāĻ &T{}-āĻāϰ āĻĒāĻžāϰā§āĻĨāĻā§āϝ? đ
āĻĻā§āĻā§āĻ
*Treturn āĻāϰā§āĨ¤new(T)zero value āĻĻāĻŋāϝāĻŧā§ initialize āĻāϰā§āĨ¤&T{field: value}āĻĻāĻŋāϝāĻŧā§ āύāĻŋāϰā§āĻĻāĻŋāώā§āĻ āĻā§āϝāĻžāϞ⧠āĻĻā§āĻāϝāĻŧāĻž āϝāĻžāϝāĻŧ â production-āĻ&T{}āĻŦā§āĻļāĻŋ āĻŦā§āϝāĻŦāĻšā§āϤāĨ¤
Q: Go-āϤ⧠āĻāĻŋ Pass by Reference āĻāĻā§?
āύā§āĻāĨ¤ Go āϏāĻŦāϏāĻŽāϝāĻŧ Pass by ValueāĨ¤ Pointer āĻĒāĻžāϏ āĻāϰāϞā§āĻ address-āĻāϰ āĻāĻāĻāĻŋ copy āϝāĻžāϝāĻŧ â reference āϝāĻžāϝāĻŧ āύāĻžāĨ¤
Q: nil pointer dereference āĻā§āĻāĻžāĻŦā§ āĻāĻĄāĻŧāĻžāĻŦā§āύ?
Pointer āĻŦā§āϝāĻŦāĻšāĻžāϰā§āϰ āĻāĻā§ āϏāĻŦāϏāĻŽāϝāĻŧ
if ptr != nilāĻā§āĻ āĻāϰā§āύāĨ¤ āĻ āĻĨāĻŦāĻžnew()āĻŦāĻž&T{}āĻĻāĻŋāϝāĻŧā§ initialize āĻāϰ⧠āύāĻŋāύāĨ¤