Methods and interfaces
This lesson covers methods and interfaces, the constructs that define objects and their behavior.

The Go Authors
https://golang.org

* Methods

Go does not have classes.
However, you can define methods on types.

A method is a function with a special _receiver_ argument.

The receiver appears in its own argument list between the `func` keyword and
the method name.

In this example, the `Abs` method has a receiver of type `Vertex` named `v`.

.play methods/methods.go

* Methods are functions

Remember: a method is just a function with a receiver argument.

Here's `Abs` written as a regular function with no change in functionality.

.play methods/methods-funcs.go

* Methods continued

You can declare a method on non-struct types, too.

In this example we see a numeric type `MyFloat` with an `Abs` method.

You can only declare a method with a receiver whose type is defined in the same
package as the method.
You cannot declare a method with a receiver whose type is defined in another
package (which includes the built-in types such as `int`).

.play methods/methods-continued.go

* Pointer receivers

You can declare methods with pointer receivers.

This means the receiver type has the literal syntax `*T` for some type `T`.
(Also, `T` cannot itself be a pointer such as `*int`.)

For example, the `Scale` method here is defined on `*Vertex`.

Methods with pointer receivers can modify the value to which the receiver
points (as `Scale` does here).
Since methods often need to modify their receiver, pointer receivers are more
common than value receivers.

Try removing the `*` from the declaration of the `Scale` function on line 16
and observe how the program's behavior changes.

With a value receiver, the `Scale` method operates on a copy of the original
`Vertex` value.
(This is the same behavior as for any other function argument.)
The `Scale` method must have a pointer receiver to change the `Vertex` value
declared in the `main` function.

.play methods/methods-pointers.go

* Pointers and functions

Here we see the `Abs` and `Scale` methods rewritten as functions.

Again, try removing the `*` from line 16.
Can you see why the behavior changes?
What else did you need to change for the example to compile?

(If you're not sure, continue to the next page.)

.play methods/methods-pointers-explained.go

* Methods and pointer indirection

Comparing the previous two programs, you might notice that
functions with a pointer argument must take a pointer:

	var v Vertex
	ScaleFunc(v, 5)  // Compile error!
	ScaleFunc(&v, 5) // OK

while methods with pointer receivers take either a value or a pointer as the
receiver when they are called:

	var v Vertex
	v.Scale(5)  // OK
	p := &v
	p.Scale(10) // OK

For the statement `v.Scale(5)`, even though `v` is a value and not a pointer,
the method with the pointer receiver is called automatically.
That is, as a convenience, Go interprets the statement `v.Scale(5)` as
`(&v).Scale(5)` since the `Scale` method has a pointer receiver.

.play methods/indirection.go

* Methods and pointer indirection (2)

The equivalent thing happens in the reverse direction.

Functions that take a value argument must take a value of that specific type:

	var v Vertex
	fmt.Println(AbsFunc(v))  // OK
	fmt.Println(AbsFunc(&v)) // Compile error!

while methods with value receivers take either a value or a pointer as the
receiver when they are called:

	var v Vertex
	fmt.Println(v.Abs()) // OK
	p := &v
	fmt.Println(p.Abs()) // OK

In this case, the method call `p.Abs()` is interpreted as `(*p).Abs()`.

.play methods/indirection-values.go

* Choosing a value or pointer receiver

There are two reasons to use a pointer receiver.

The first is so that the method can modify the value that its receiver points to.

The second is to avoid copying the value on each method call.
This can be more efficient if the receiver is a large struct, for example.

In this example, both `Scale` and `Abs` are with receiver type `*Vertex`,
even though the `Abs` method needn't modify its receiver.

In general, all methods on a given type should have either value or pointer
receivers, but not a mixture of both.
(We'll see why over the next few pages.)

.play methods/methods-with-pointer-receivers.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.

*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).

.play methods/interfaces.go

* Interfaces are implemented implicitly

A type implements an interface by implementing its methods.
There is no explicit declaration of intent, no "implements" keyword.

Implicit interfaces decouple the definition of an interface from its
implementation, which could then appear in any package without prearrangement.

.play methods/interfaces-are-satisfied-implicitly.go

* Interface values

Under the hood, interface values can be thought of as a tuple of a value and a
concrete type:

	(value, type)

An interface value holds a value of a specific underlying concrete type.

Calling a method on an interface value executes the method of the same name on
its underlying type.

.play methods/interface-values.go

* Interface values with nil underlying values

If the concrete value inside the interface itself is nil,
the method will be called with a nil receiver.

In some languages this would trigger a null pointer exception,
but in Go it is common to write methods that gracefully handle being called
with a nil receiver (as with the method `M` in this example.)

Note that an interface value that holds a nil concrete value is itself non-nil.

.play methods/interface-values-with-nil.go

* Nil interface values

A nil interface value holds neither value nor concrete type.

Calling a method on a nil interface is a run-time error because there is no
type inside the interface tuple to indicate which _concrete_ method to call.

.play methods/nil-interface-values.go

* The empty interface

The interface type that specifies zero methods is known as the _empty_interface_:

	interface{}

An empty interface may hold values of any type.
(Every type implements at least zero methods.)

Empty interfaces are used by code that handles values of unknown type.
For example, `fmt.Print` takes any number of arguments of type `interface{}`.

.play methods/empty-interface.go

* Type assertions

A _type_assertion_ provides access to an interface value's underlying concrete value.

	t := i.(T)

This statement asserts that the interface value `i` holds the concrete type `T`
and assigns the underlying `T` value to the variable `t`.

If `i` does not hold a `T`, the statement will trigger a panic.

To _test_ whether an interface value holds a specific type,
a type assertion can return two values: the underlying value
and a boolean value that reports whether the assertion succeeded.

	t, ok := i.(T)

If `i` holds a `T`, then `t` will be the underlying value and `ok` will be true.

If not, `ok` will be false and `t` will be the zero value of type `T`,
and no panic occurs.

Note the similarity between this syntax and that of reading from a map.

.play methods/type-assertions.go

* Type switches

A _type_switch_ is a construct that permits several type assertions in series.

A type switch is like a regular switch statement, but the cases in a type
switch specify types (not values), and those values are compared against
the type of the value held by the given interface value.

	switch v := i.(type) {
	case T:
		// here v has type T
	case S:
		// here v has type S
	default:
		// no match; here v has the same type as i
	}

The declaration in a type switch has the same syntax as a type assertion `i.(T)`,
but the specific type `T` is replaced with the keyword `type`.

This switch statement tests whether the interface value `i`
holds a value of type `T` or `S`.
In each of the `T` and `S` cases, the variable `v` will be of type
`T` or `S` respectively and hold the value held by `i`.
In the default case (where there is no match), the variable `v` is
of the same interface type and value as `i`.

.play methods/type-switches.go

* Stringers

One of the most ubiquitous interfaces is [[//golang.org/pkg/fmt/#Stringer][`Stringer`]] defined by the [[//golang.org/pkg/fmt/][`fmt`]] package.

	type Stringer interface {
		String() string
	}

A `Stringer` is a type that can describe itself as a string. The `fmt` package
(and many others) look for this interface to print values.

.play methods/stringer.go

* Exercise: Stringers

Make the `IPAddr` type implement `fmt.Stringer` to print the address as
a dotted quad.

For instance, `IPAddr{1,`2,`3,`4}` should print as `"1.2.3.4"`.

.play methods/exercise-stringer.go

* Errors

Go programs express error state with `error` values.

The `error` type is a built-in interface similar to `fmt.Stringer`:

	type error interface {
		Error() string
	}

(As with `fmt.Stringer`, the `fmt` package looks for the `error` interface when
printing values.)

Functions often return an `error` value, and calling code should handle errors
by testing whether the error equals `nil`.

	i, err := strconv.Atoi("42")
	if err != nil {
		fmt.Printf("couldn't convert number: %v\n", err)
		return
	}
	fmt.Println("Converted integer:", i)

A nil `error` denotes success; a non-nil `error` denotes failure.

.play methods/errors.go

* Exercise: Errors

Copy your `Sqrt` function from the [[/flowcontrol/8][earlier exercise]] and modify it to return an `error` value.

`Sqrt` should return a non-nil error value when given a negative number, as it doesn't support complex numbers.

Create a new type

	type ErrNegativeSqrt float64

and make it an `error` by giving it a

	func (e ErrNegativeSqrt) Error() string

method such that `ErrNegativeSqrt(-2).Error()` returns `"cannot`Sqrt`negative`number:`-2"`.

*Note:* A call to `fmt.Sprint(e)` inside the `Error` method will send the program into an infinite loop. You can avoid this by converting `e` first: `fmt.Sprint(float64(e))`. Why?

Change your `Sqrt` function to return an `ErrNegativeSqrt` value when given a negative number.

.play methods/exercise-errors.go

* Readers

The `io` package specifies the `io.Reader` interface,
which represents the read end of a stream of data.

The Go standard library contains [[https://golang.org/search?q=Read#Global][many implementations]] of these interfaces, including files, network connections, compressors, ciphers, and others.

The `io.Reader` interface has a `Read` method:

	func (T) Read(b []byte) (n int, err error)

`Read` populates the given byte slice with data and returns the number of bytes
populated and an error value. It returns an `io.EOF` error when the stream
ends.

The example code creates a
[[//golang.org/pkg/strings/#Reader][`strings.Reader`]]
and consumes its output 8 bytes at a time.

.play methods/reader.go

* Exercise: Readers

Implement a `Reader` type that emits an infinite stream of the ASCII character
`'A'`.

.play methods/exercise-reader.go

* Exercise: rot13Reader

A common pattern is an [[https://golang.org/pkg/io/#Reader][io.Reader]] that wraps another `io.Reader`, modifying the stream in some way.

For example, the [[https://golang.org/pkg/compress/gzip/#NewReader][gzip.NewReader]] function takes an `io.Reader` (a stream of compressed data) and returns a `*gzip.Reader` that also implements `io.Reader` (a stream of the decompressed data).

Implement a `rot13Reader` that implements `io.Reader` and reads from an `io.Reader`, modifying the stream by applying the [[https://en.wikipedia.org/wiki/ROT13][rot13]] substitution cipher to all alphabetical characters.

The `rot13Reader` type is provided for you.
Make it an `io.Reader` by implementing its `Read` method.

.play methods/exercise-rot-reader.go

* Images

[[https://golang.org/pkg/image/#Image][Package image]] defines the `Image` interface:

	package image

	type Image interface {
		ColorModel() color.Model
		Bounds() Rectangle
		At(x, y int) color.Color
	}

*Note*: the `Rectangle` return value of the `Bounds` method is actually an
[[https://golang.org/pkg/image/#Rectangle][`image.Rectangle`]], as the
declaration is inside package `image`.

(See [[https://golang.org/pkg/image/#Image][the documentation]] for all the details.)

The `color.Color` and `color.Model` types are also interfaces, but we'll ignore that by using the predefined implementations `color.RGBA` and `color.RGBAModel`. These interfaces and types are specified by the [[https://golang.org/pkg/image/color/][image/color package]]

.play methods/images.go

* Exercise: Images

Remember the [[/moretypes/18][picture generator]] you wrote earlier? Let's write another one, but this time it will return an implementation of `image.Image` instead of a slice of data.

Define your own `Image` type, implement [[https://golang.org/pkg/image/#Image][the necessary methods]], and call `pic.ShowImage`.

`Bounds` should return a `image.Rectangle`, like `image.Rect(0,`0,`w,`h)`.

`ColorModel` should return `color.RGBAModel`.

`At` should return a color; the value `v` in the last picture generator corresponds to `color.RGBA{v,`v,`255,`255}` in this one.

.play methods/exercise-images.go

* Congratulations!

You finished this lesson!

You can go back to the list of [[/list][modules]] to find what to learn next, or continue with the [[javascript:click('.next-page')][next lesson]].
