# 6. Pointer Receiver Code

Methods with pointer receivers don't require that a pointer is used to call the method. The pointer will automatically be derived from the value.

```go
type circle struct {
	x int
	y int
    radius int
}

func (c *circle) grow() {
    c.radius *= 2
}

func main() {
    c := circle{
        x: 1,
        y: 2,
        radius: 4,
    }

    // notice c is not a pointer in the calling function
    // but the method still gains access to a pointer to c
    c.grow()
    fmt.Println(c.radius)
    // prints 8
}
```

## Go Pointer Receiver - Automatic Conversion Notes

### The Key Concept

When you have a **pointer receiver method**, you can call it on a **regular value** (not a pointer). Go automatically converts it for you.

### Example Breakdown

```go
type circle struct {
    x      int
    y      int
    radius int
}

func (c *circle) grow() {
    c.radius *= 2
}

func main() {
    c := circle{x: 1, y: 2, radius: 4}  // c is a VALUE, not a pointer
    c.grow()  // Go automatically does (&c).grow()
    fmt.Println(c.radius)  // 8
}
```

### What Go Does Automatically

You write:

```go
c.grow()
```

Go translates to:

```go
(&c).grow()  // Takes address automatically
```

### Both Work the Same

```go
func (c *circle) grow() {
    c.radius *= 2
}

func main() {
    c := circle{radius: 4}
    
    // Method 1: Call on value (Go auto-converts)
    c.grow()
    fmt.Println(c.radius)  // 8
    
    // Method 2: Call on pointer explicitly
    (&c).grow()
    fmt.Println(c.radius)  // 16
    
    // Method 3: Use pointer variable
    ptr := &c
    ptr.grow()
    fmt.Println(c.radius)  // 32
}
```

All three ways work!

### Why This Matters

Without auto-conversion, you'd have to write:

```go
c := circle{radius: 4}
(&c).grow()  // Annoying!
```

With auto-conversion, you just write:

```go
c := circle{radius: 4}
c.grow()  // Clean!
```

### Complete Example

```go
type user struct {
    name     string
    loggedIn bool
}

// Pointer receiver - can modify
func (u *user) login() {
    u.loggedIn = true
}

// Pointer receiver - can modify
func (u *user) logout() {
    u.loggedIn = false
}

func main() {
    // Create a regular value (not a pointer)
    bob := user{name: "Bob", loggedIn: false}
    
    // Call pointer receiver method on value
    bob.login()  // Go does (&bob).login()
    fmt.Println(bob.loggedIn)  // true
    
    bob.logout()  // Go does (&bob).logout()
    fmt.Println(bob.loggedIn)  // false
}
```

### The Reverse Also Works

You can call **value receiver** methods on **pointers**:

```go
type circle struct {
    radius int
}

// Value receiver
func (c circle) getArea() float64 {
    return 3.14 * float64(c.radius) * float64(c.radius)
}

func main() {
    c := &circle{radius: 5}  // c is a POINTER
    
    area := c.getArea()  // Go does (*c).getArea()
    fmt.Println(area)
}
```

### Summary of Auto-Conversions

| Method Type        | Call On      | What Go Does                |
| ------------------ | ------------ | --------------------------- |
| `func (c *circle)` | value `c`    | `(&c).method()`             |
| `func (c *circle)` | pointer `&c` | `(&c).method()` (no change) |
| `func (c circle)`  | value `c`    | `c.method()` (no change)    |
| `func (c circle)`  | pointer `&c` | `(*&c).method()`            |

### Key Takeaways

{% stepper %}
{% step %}
Pointer receiver method can be called on a value.
{% endstep %}

{% step %}
Go auto-converts `c.grow()` → `(&c).grow()`.
{% endstep %}

{% step %}
Makes code cleaner - don't need `&` everywhere.
{% endstep %}

{% step %}
Still modifies original - even though you call on value.
{% endstep %}

{% step %}
Works both ways - value receivers work on pointers too.
{% endstep %}
{% endstepper %}

Bottom line: Write methods naturally with `.` notation. Go handles the pointer conversion automatically.

### Assignment

Fix the bug in the code so that `setMessage` sets the `message` field of the given email struct, and the new value persists outside the scope of the `setMessage` method.

Correct approach: use a pointer receiver so the method modifies the original struct. Example fixed code:

```go
package main

import "fmt"

type email struct {
    message string
}

// Use pointer receiver so changes persist
func (e *email) setMessage(m string) {
    e.message = m
}

func main() {
    em := email{message: "old"}
    em.setMessage("new") // Go does (&em).setMessage("new")
    fmt.Println(em.message) // prints "new"
}
```

Explanation: With a value receiver (func (e email) setMessage...), the method operates on a copy, and changes are not reflected on the caller's variable. Using a pointer receiver (func (e \*email) setMessage...) ensures the original struct is modified.
