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)
type Sequence []int
// s = ...
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
type Stringer interface {
String() string
}
var value interface{} // Value provided by caller.
switch str := value.(type) {
case string:
return str
case Stringer:
return str.String()
}
**_type assertion**
value.(typeName)
“comma, ok” idiom
str, ok := value.(string)
if ok {
fmt.Printf("string value is: %q\n", str)
} else {
fmt.Printf("value is not a string\n")
}
an if``-``else
statement that’s equivalent to the type switch
if str, ok := value.(string); ok {
return str
} else if str, ok := value.(Stringer); ok {
return str.String()
}
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.