# Interface: Pointers vs Values in Go

### Interfaces

An interface type is defined as a set of method signatures. A value of interface type can hold any value that implements those methods. Take a look at the below example taken from [Go tour](https://go.dev/tour/methods/9).

```go
package main

import (
	"fmt"
	"math"
)

type Abser interface {
	Abs() float64
}

func main() {
	var a Abser
	f := MyFloat(-math.Sqrt2)
	v := Vertex{3, 4}

	a = f  // a MyFloat implements Abser
	a = &v // a *Vertex implements Abser

	// In the following line, v is a Vertex (not *Vertex)
	// and does NOT implement Abser.
	a = v

	fmt.Println(a.Abs())
}

type MyFloat float64

func (f MyFloat) Abs() float64 {
	if f < 0 {
		return float64(-f)
	}
	return float64(f)
}

type Vertex struct {
	X, Y float64
}

func (v *Vertex) Abs() float64 {
	return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
```

**<mark>Note: There is an error in the example code on line 22. Vertex (the value type) doesn't implement Abser because the Abs method is defined only on *Vertex (the pointer type).</mark>**

But if i write `func (v Vertex) abs()` then also `a = &v` works! why?  
  
In Go, when you define a method with a receiver type (like `v *Vertex` or `v Vertex`), the receiver can be a **pointer** or a **value** type. This distinction is important because it determines what can call the method.

### The original case: `func (v *Vertex) Abs()`

In our original code, the `Abs()` method is defined with a **pointer receiver**:

```go

func (v *Vertex) Abs() float64 {
	return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
```

This means the method can only be called on a `*Vertex` (a pointer to a `Vertex`), not a `Vertex` itself.

* When you do `a = &v`, you're assigning a pointer to `v` (`*Vertex`), which works fine because the method `Abs()` is defined on `*Vertex`, and so `&v` implements `Abser`.
    

However, when you do `a = v` (without the `&`), `v` is of type `Vertex`, not `*Vertex`. Since the method is defined on `*Vertex`, `v` does **not** implement the `Abser` interface, hence the error.

### What happens if you change the method to `(v Vertex) Abs()`?

If you change the method signature to use a **value receiver**:

```go

func (v Vertex) Abs() float64 {
	return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
```

Now the method is defined on the `Vertex` type (the value type), so it can be called on both **values** of type `Vertex` and **pointers** of type `*Vertex`. This is because Go will automatically **dereference** the pointer for you.

* If you have a value `v` of type `Vertex`, calling `v.Abs()` works.
    
* If you have a pointer `&v` of type `*Vertex`, calling `(&v).Abs()` works too because Go automatically dereferences the pointer behind the scenes.
    

### Why does `a = &v` work with a value receiver?

When the method is defined with a value receiver like this:

```go

func (v Vertex) Abs() float64 {
	return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
```

It can be called on a pointer (`*Vertex`) as well. The reason is that Go will implicitly **dereference** the pointer when needed. So, even though the method expects a value (`Vertex`), you can still pass a pointer (`*Vertex`) because Go will automatically turn `*v` into `v` by dereferencing.

This implicit dereferencing works because a value receiver is less restrictive: the method doesn't modify the original struct (since it's a copy), so Go allows calling it on a pointer too, as it's safe!
