Interfaces

Interfaces in Go provide a way to specify the behavior of an object: if something can do this, then it can be used here.

Interfaces with only one or two methods are common in Go code, and are usually given a name derived from the method.

A type can implement multiple interfaces.


Conversions

It’s an idiom in Go programs to convert the type of an expression to access a different set of methods.

Type(value)

  1. type Sequence []int
  2. // s = ...
  3. fmt.Sprint([]int(s))

sort.IntSlice(s).Sort(), sort.IntSlice(s) is conversion or method invoking?


Interface conversions and type assertions

type switch
for each case in the switch, in a sense convert it to the type of that case

  1. type Stringer interface {
  2. String() string
  3. }
  4. var value interface{} // Value provided by caller.
  5. switch str := value.(type) {
  6. case string:
  7. return str
  8. case Stringer:
  9. return str.String()
  10. }


**_type assertion
**

value.(typeName)

“comma, ok” idiom

  1. str, ok := value.(string)
  2. if ok {
  3. fmt.Printf("string value is: %q\n", str)
  4. } else {
  5. fmt.Printf("value is not a string\n")
  6. }

an if``-``else statement that’s equivalent to the type switch

  1. if str, ok := value.(string); ok {
  2. return str
  3. } else if str, ok := value.(Stringer); ok {
  4. return str.String()
  5. }

Generality

  • If a type exists only to implement an interface and will never have exported methods beyond that interface, there is no need to export the type itself.
  • Exporting just the interface makes it clear the value has no interesting behavior beyond what is described in the interface.
  • It also avoids the need to repeat the documentation on every instance of a common method.

Interfaces and methods

Since almost anything can have methods attached, almost anything can satisfy an interface.

Since we can define a method for any type except pointers and interfaces, we can write a method for a function.

In this section we have made an HTTP server from a struct, an integer, a channel, and a function, all because interfaces are just sets of methods, which can be defined for (almost) any type.