I am new to Golang. And I am trying to use a decorator which returns a function with a receiver. How can I do that?
type myStruct struct {
s string
}
func myFunc(s string) {
fmt.Println(s)
}
// Here I want to return a function with a receiver
func (*myStruct) myDecorator(fn func(string)) (*myStruct)func(string){
return (ms *myStruct)func(s string) {
fn(ms+s)
}
}
func main() {
ms := myStruct{"Hello"}
// Some func is function with receiver as myStruct pointer
someFunc := myDecorator(myFunc)
// This is expected to print "Hello world"
ms.someFunc(" world")
}
As noted in my comment, you cannot modify the method set of a type in the return from a function call, so directly extending the behavior of the myStruct struct is not possible in your "decorator" function as written.
I am actually using this decorator to wrap fmt.Sprintf, Sprintln, Sprint method to get Logger.Debugln, Logger.Debugf, Logger.Warning, ... methods, where Logger is a self-defined struct, since these functions shares almost the same behavior.
You also will not be able to pass around the fmt.Sprintf, fmt.Sprintln and fmt.Sprint functions in a generic way, as they share different signatures:
func Print(a ...interface{}) (n int, err error)
func Printf(format string, a ...interface{}) (n int, err error)
func Println(a ...interface{}) (n int, err error)
so you will need to wrap these methods separately.
It isn't entirely clear to me how you are seeking to wrap those methods to produce your Logger type.
If you require each of those methods at the top level of your logger, they will need to be explicitly declared in your logging package or on your Logger type's interface. You cannot dynamically bind each level function at runtime, despite their obvious similarities; go is a statically-typed language so your types must be declared upfront.
Defining the types explicitly will be the clearest solution, which is also in keeping with a key go proverb: "Clear is better than clever."
If necessary, you can declare each method as a simple wrapper of an internal method on your type which actually performs the printing logic, keeping repetition to a minimum.
Here's a quick example I threw together to show the logic for some Debug, Debugf and Debugln endpoints. You can see the core logic is handled by a generic set of methods on the Logger type, and you can imagine how endpoints for other log levels could be trivially implemented.
If repetition is really a problem, you could trivially write a code generator to automatically generate the log-level specific methods, calling on the core functionality explicitly declared in the various print functions. Remember you can declare receivers for a type in multiple source files in the same package, allowing some methods to be generated in some source files while others are implemented explicitly elsewhere.
package main
import (
"fmt"
"io"
"os"
)
type Level string
const (
Debug Level = "DEBUG"
Error = "ERROR"
// etc.
)
type Logger struct {
writer io.Writer
prependLevel bool
}
func (l *Logger) print(level Level, msg string) {
var s string
if l.prependLevel {
s = string(level) + ": "
}
s += msg
fmt.Fprint(l.writer, s)
}
func (l *Logger) printf(level Level, format string, a ...interface{}) {
l.print(level, fmt.Sprintf(format, a...))
}
func (l *Logger) println(level Level, msg string) {
l.printf(level, "%s\n", msg)
}
func (l *Logger) Debug(msg string) {
l.print(Debug, msg)
}
func (l *Logger) Debugf(format string, a ...interface{}) {
l.printf(Debug, format, a...)
}
func (l *Logger) Debugln(msg string) {
l.println(Debug, msg)
}
func main() {
logger := Logger{os.Stderr, true}
logger.Debugln("A plain message with a new line")
logger.Debugf(
("The most customizable log entry with some parameters: " +
"%s %v\n"),
"myStr", false,
)
logger.Debug("A bare print statement")
}
Playground link.
Third-party packages
In case you haven't yet done so, there are many third-party logging packages in Go which I would recommend considering, or at least assessing their interfaces to determine how others have approached similar tasks.
Logrus is a Go logger with levels, for example. You can see in their source files how they explicitly declare their interface for each function at each log level, while using a more comprehensive version of the method above to reduce repetition in the core logging implementation: Interface Formatter implementations
Related
I have two different interfaces (from two different packages) that I want to implement. But they conflict, like this:
type InterfaceA interface {
Init()
}
type InterfaceB interface {
Init(name string)
}
type Implementer struct {} // Wants to implement A and B
func (i Implementer) Init() {}
func (i Implementer) Init(name string) {} // Compiler complains
It says "Method redeclared". How can one struct implement both interfaces?
As already answered, this is not possible since Golang does not (and probably will not) support method overloading.
Look at Golang FAQ:
Experience with other languages told us that having a variety of methods with the same name but different signatures was occasionally useful but that it could also be confusing and fragile in practice. Matching only by name and requiring consistency in the types was a major simplifying decision in Go's type system.
It is not possible.
In go you must have a single method signature.
You should rename one method.
The method signatures must match. If you want dependency injection I would recommend the functional option pattern. Functional options are functions that return other functions that are called in a loop in the constructor. Here is an example of how to use functional options and the basics of interfaces in go.
package main
import (
"fmt"
"strconv"
)
type SomeData struct {
data string
}
// SomeData and SomeOtherData both implement SomeInterface and SomeOtherInterface
// SomeInterface and SomeOtherInterface both implement each other.
type SomeInterface interface {
String() string
Set(data string)
}
func (s *SomeData)String() string {
return s.data
}
func (s *SomeData)Set(data string) {
s.data = data
}
// SetDataOption is a functional option that can be used to inject a constructor dep
func SetDataOption(data string) func(*SomeData) {
return func(s *SomeData) {
s.Set(data)
}
}
// NewSomeData is the constructor; it takes in 0 to many functional options and calls each one in a loop.
func NewSomeData(options ...func(s *SomeData)) SomeInterface {
s := new(SomeData)
for _, o := range options {
o(s)
}
return s
}
//********************
type SomeOtherData struct {
data string
i int
}
type SomeOtherInterface interface {
String() string
Set(data string)
}
func (s *SomeOtherData)String() string {
return s.data + " " + strconv.Itoa(s.i)
}
func (s *SomeOtherData)Set(data string) {
s.data = data
}
func SetOtherDataOption(data string) func(*SomeOtherData) {
return func(s *SomeOtherData) {
s.Set(data)
}
}
func SetOtherIntOption(i int) func(*SomeOtherData) {
return func(s *SomeOtherData) {
s.i = i
}
}
// NewSomeOther data works just like NewSomeData only in this case, there are more options to choose from
// you can use none or any of them.
func NewSomeOtherData(options ...func(s *SomeOtherData)) SomeOtherInterface {
s := new(SomeOtherData)
for _, o := range options {
o(s)
}
return s
}
//*********************************
// HandleData accepts an interface
// Regardless of which underlying struct is in the interface, this function will handle
// either by calling the methods on the underlying struct.
func HandleData(si SomeInterface) {
fmt.Println(si) // fmt.Println calls the String() method of your struct if it has one using the Stringer interface
}
func main() {
someData := NewSomeData(SetDataOption("Optional constructor dep"))
someOtherData := NewSomeOtherData(SetOtherDataOption("Other optional constructor dep"), SetOtherIntOption(42))
HandleData(someData) // calls SomeData.String()
HandleData(someOtherData) // calls SomeOtherData.String()
someOtherData = someData // assign the first interface to the second, this works because they both implement each other.
HandleData(someOtherData) // calls SomeData.String() because there is a SomeData in the someOtherData variable.
}
I have the following
https://go.dev/play/p/s3VizCW1pio
func main() {
type Book struct {
// Bad: pointer changes zero value usefulness
io.ReadWriter
}
// later
var b Book
b.Read([]byte{'1'}) // panic nil value
}
From https://github.com/uber-go/guide
My question is, when we add io.ReadWriter to Book, should it compile at all if we haven't implemented the interface io.ReadWriter for Book?
There's clearly a gap in my understanding and any help would be greatly appreciated
Embedded Types
What you have here is called an embedded type. Embedded types allow you to place other types at the root of a struct and refer to them using their unqualified type name. The methods of the embedded type are available from the parent struct. From a compilation failure perspective, there is no difference between what you have and this:
type Book struct {
writer io.ReadWriter
}
In other words, your example does not require that you specify a value for writer for the same reason that my example does not -- an embedded value is treated just like any other value other than the embedded type's methods are available from the parent type. In either case, if a value is not provided for the field, then you'll get a runtime nil pointer error.
Should it compile at all if we haven't implemented the interface io.ReadWriter for Book?
It will compile but panic if you try to access the field or its methods. The solution is to provide an implementation by assigning to the embedded field's name.
package main
import (
"bytes"
"io"
)
type Book struct {
io.ReadWriter
}
func main() {
book := Book{
ReadWriter: &bytes.Buffer{},
}
}
Implementing the Interface
If all you want to do is create a Book struct that implements the io.ReadWriter interface, then you can get rid of the io.ReadWriter field on the struct entirely and just do something like this:
package main
import (
"io"
)
var _ io.ReadWriter = &Book{}
type Book struct {}
func (b *Book) Read(p []byte) (n int, err error) {
// Custom implementation here
return 0, err
}
func (b *Book) Write(p []byte) (n int, err error) {
// Custom implementation here
return 0, err
}
func main() {
book := Book{}
}
Custom Wrappers
You can do some pretty cool stuff by embedding types such as wrapping a lower-level implementation of io.ReadWriter (in this example) with your own custom logic before calling the embedded implementation.
var _ io.ReadWriter = &Book{}
type Book struct {
io.ReadWriter
}
func (b *Book) Read(p []byte) (n int, err error) {
// add a custom behavior before calling the underlying read method
return b.ReadWriter.Read(p)
}
func (b *Book) Write(p []byte) (n int, err error) {
// add a custom behavior before calling the underlying write method
return b.ReadWriter.Write(p)
}
func main() {
book := Book{
ReadWriter: &bytes.Buffer{},
}
}
What you did with type Book is that you embedded an io.ReadWriter into it. That means, Book type has a field of type io.ReadWriter, and since it is embedded, Book now has all the methods defined for io.ReadWriter. You have to set that field to point to an implementation of io.ReadWriter to use it:
var b Book
myFile,err:=op.Open("someFile") // myFile implements io.ReadWriter
b.ReadWriter=myFile
data:=make([]byte,1)
b.Read(data) // will read from myFile
Suppose I have a lot of different structs, but they all share a common field, such as "name". For example:
type foo struct {
name string
someOtherString string
// Other fields
}
type bar struct {
name string
someNumber int
// Other fields
}
Further on in the program, I repeatedly encounter the situation where I get pointers to these structs (so *foo, *bar, etc.) and need to perform operations depending on whether the pointer is nil or not, basically like so:
func workOnName(f *foo) interface{} {
if (f == nil) {
// Do lots of stuff
} else {
// Do lots of other stuff
}
// Do even more stuff
return something
}
This function, which only uses name, is the same across all structs. If these were not pointers, I know I could write a common interface for each struct that returns the name and use that as the type. But with pointers, none of this has worked. Go either complains while compiling, or the nil check doesn't work and Go panics. I haven't found anything smarter than to copy/paste the exact same code for every struct that I have, so basically to implement all the functions:
func (f *foo) workOnName() interface{}
func (b *bar) workOnName() interface{}
func (h *ham) workOnName() interface{}
// And so on...
Is there a way to do this better, i.e. to only implement a simple function (or even better, no function at all) for all my structs and simply write the complicated stuff once, for all the structs?
Edit: Thank you to the answers so far, but simply using an interface of the type:
func (f foo) Name() string {
return f.name
}
for some interface that provides Name() does not work, because the pointer is not recognized as nil. See this playground: https://play.golang.org/p/_d1qiZwnMe_f
You can declare an interface which declares a function returning a name:
type WithName interface {
Name() string
}
In order to implement that interface, you types (foo, bar, etc) need to have that method - not just the field, the method.
func (f foo) Name() string {
return f.name
}
Then, workOnName needs to receive a reference of that interface:
func workOnName(n WithName) interface{} {
if (n == nil || reflect.ValueOf(n).isNil()) {
// Do lots of stuff
} else {
// Do lots of other stuff
}
// Do even more stuff
return something
}
Keep in mind that the parameter n WithName is always treated as a pointer, not an object value.
I think that's the case for reflect.
Something like:
package main
import (
"fmt"
"reflect"
)
func SetFieldX(obj, value interface{}) {
v := reflect.ValueOf(obj).Elem()
if !v.IsValid() {
fmt.Println("obj is nil")
return
}
f := v.FieldByName("X")
if f.IsValid() && f.CanSet() {
f.Set(reflect.ValueOf(value))
}
}
func main() {
st1 := &struct{ X int }{10}
var stNil *struct{}
SetFieldX(st1, 555)
SetFieldX(stNil, "SSS")
fmt.Printf("%v\n%v\n", st1, stNil)
}
https://play.golang.org/p/OddSWT4JkSG
Note that IsValid checks more than just obj==nil but if you really want to distinguish cases of nil pointers and non-struct objects - you are free to implement it.
Going through some go sources in the net/http and related libraries, I came across something that made me curious. I'm looking at version 1.12 here.
func (p *ReverseProxy) handleUpgradeResponse(rw http.ResponseWriter, req *http.Request, res *http.Response) {
...
hj, ok := rw.(http.Hijacker)
...
conn, brw, err := hj.Hijack()
...
}
I've been seeing stuff like this in more places and also outside the standard library. What is happening here? Are some methods of an interface implementation hidden until a specific assertion happens? Why can't I just call Hijack() on the rw object?
The methods appear to be hidden, because the function takes an interface type. The interface of http.ResponseWriter does not define the Hijack() method. This is defined in the http.Hijacker interface. A concrete type may implement multiple interfaces. But even if such concrete type is passed into a scope where its type definition is an interface, additional methods will not be accessible. So in the questioned example, type assertion is performed to make make the Hijack() method available.
Some examples (playground):
package main
import (
"fmt"
)
type Ship interface {
Load(containers []string)
Condition() []string
}
type Sea interface {
Draft() int
}
// seaShip implements the Sea and Ship interfaces
type seaShip struct {
containers []string
}
// Load is only part of the Ship interface
func (ss *seaShip) Load(containers []string) {
ss.containers = append(ss.containers, containers...)
}
// Condition is only part of the Ship interface
func (ss *seaShip) Condition() []string {
return ss.containers
}
// Draft is only part of the Sea interface
func (ss *seaShip) Draft() int {
return len(ss.containers)
}
// Pirates is not defined in any interface and therefore can only be called on the concrete type
func (ss *seaShip) Pirates() string {
return "Help!"
}
// NewShip returns an implementation of the Ship interface
func NewShip() Ship {
return &seaShip{}
}
func main() {
ship := NewShip()
ship.Load([]string{"Beer", "Wine", "Peanuts"})
fmt.Println(ship.Condition())
// Won't compile, method is not part of interface!
// fmt.Println(ship.Draft())
// Assert to make Draft() available
sea := ship.(Sea)
fmt.Println(sea.Draft())
// Won't compile, methods are not part of interface!
// fmt.Println(sea.Condition())
// fmt.Println(sea.Pirates())
// Assert to the concrete type makes all methods available
ss := sea.(*seaShip)
fmt.Println(ss.Condition())
fmt.Println(ss.Pirates())
}
sort package:
type Interface interface {
Len() int
Less(i, j int) bool
Swap(i, j int)
}
...
type reverse struct {
Interface
}
What is the meaning of anonymous interface Interface in struct reverse?
In this way reverse implements the sort.Interface and we can override a specific method
without having to define all the others
type reverse struct {
// This embedded Interface permits Reverse to use the methods of
// another Interface implementation.
Interface
}
Notice how here it swaps (j,i) instead of (i,j) and also this is the only method declared for the struct reverse even if reverse implement sort.Interface
// Less returns the opposite of the embedded implementation's Less method.
func (r reverse) Less(i, j int) bool {
return r.Interface.Less(j, i)
}
Whatever struct is passed inside this method we convert it to a new reverse struct.
// Reverse returns the reverse order for data.
func Reverse(data Interface) Interface {
return &reverse{data}
}
The real value comes if you think what would you have to do if this approach was not possible.
Add another Reverse method to the sort.Interface ?
Create another ReverseInterface ?
... ?
Any of this change would require many many more lines of code across thousands of packages that want to use the standard reverse functionality.
Ok, the accepted answer helped me understand, but I decided to post an explanation which I think suits better my way of thinking.
The "Effective Go" has example of interfaces having embedded other interfaces:
// ReadWriter is the interface that combines the Reader and Writer interfaces.
type ReadWriter interface {
Reader
Writer
}
and a struct having embedded other structs:
// ReadWriter stores pointers to a Reader and a Writer.
// It implements io.ReadWriter.
type ReadWriter struct {
*Reader // *bufio.Reader
*Writer // *bufio.Writer
}
But there is no mention of a struct having embedded an interface. I was confused seeing this in sort package:
type Interface interface {
Len() int
Less(i, j int) bool
Swap(i, j int)
}
...
type reverse struct {
Interface
}
But the idea is simple. It's almost the same as:
type reverse struct {
IntSlice // IntSlice struct attaches the methods of Interface to []int, sorting in increasing order
}
methods of IntSlice being promoted to reverse.
And this:
type reverse struct {
Interface
}
means that sort.reverse can embed any struct that implements interface sort.Interface and whatever methods that interface has, they will be promoted to reverse.
sort.Interface has method Less(i, j int) bool which now can be overridden:
// Less returns the opposite of the embedded implementation's Less method.
func (r reverse) Less(i, j int) bool {
return r.Interface.Less(j, i)
}
My confusion in understanding
type reverse struct {
Interface
}
was that I thought that a struct always has fixed structure, i.e. fixed number of fields of fixed types.
But the following proves me wrong:
package main
import "fmt"
// some interface
type Stringer interface {
String() string
}
// a struct that implements Stringer interface
type Struct1 struct {
field1 string
}
func (s Struct1) String() string {
return s.field1
}
// another struct that implements Stringer interface, but has a different set of fields
type Struct2 struct {
field1 []string
dummy bool
}
func (s Struct2) String() string {
return fmt.Sprintf("%v, %v", s.field1, s.dummy)
}
// container that can embedd any struct which implements Stringer interface
type StringerContainer struct {
Stringer
}
func main() {
// the following prints: This is Struct1
fmt.Println(StringerContainer{Struct1{"This is Struct1"}})
// the following prints: [This is Struct1], true
fmt.Println(StringerContainer{Struct2{[]string{"This", "is", "Struct1"}, true}})
// the following does not compile:
// cannot use "This is a type that does not implement Stringer" (type string)
// as type Stringer in field value:
// string does not implement Stringer (missing String method)
fmt.Println(StringerContainer{"This is a type that does not implement Stringer"})
}
The statement
type reverse struct {
Interface
}
enables you to initialize reverse with everything that implements the interface Interface. Example:
&reverse{sort.Intslice([]int{1,2,3})}
This way, all methods implemented by the embedded Interface value get populated to the outside while you are still able to override some of them in reverse, for example Less to reverse the sorting.
This is what actually happens when you use sort.Reverse. You can read about embedding in the struct section of the spec.
I will give my explanation too. The sort package defines an unexported type reverse, which is a struct, that embeds Interface.
type reverse struct {
// This embedded Interface permits Reverse to use the methods of
// another Interface implementation.
Interface
}
This permits Reverse to use the methods of another Interface implementation. This is the so called composition, which is a powerful feature of Go.
The Less method for reverse calls the Less method of the embedded Interface value, but with the indices flipped, reversing the order of the sort results.
// Less returns the opposite of the embedded implementation's Less method.
func (r reverse) Less(i, j int) bool {
return r.Interface.Less(j, i)
}
Len and Swap the other two methods of reverse, are implicitly provided by the original Interface value because it is an embedded field. The exported Reverse function returns an instance of the reverse type that contains the original Interface value.
// Reverse returns the reverse order for data.
func Reverse(data Interface) Interface {
return &reverse{data}
}
I find this feature very helpful when writing mocks in tests.
Here is such an example:
package main_test
import (
"fmt"
"testing"
)
// Item represents the entity retrieved from the store
// It's not relevant in this example
type Item struct {
First, Last string
}
// Store abstracts the DB store
type Store interface {
Create(string, string) (*Item, error)
GetByID(string) (*Item, error)
Update(*Item) error
HealthCheck() error
Close() error
}
// this is a mock implementing Store interface
type storeMock struct {
Store
// healthy is false by default
healthy bool
}
// HealthCheck is mocked function
func (s *storeMock) HealthCheck() error {
if !s.healthy {
return fmt.Errorf("mock error")
}
return nil
}
// IsHealthy is the tested function
func IsHealthy(s Store) bool {
return s.HealthCheck() == nil
}
func TestIsHealthy(t *testing.T) {
mock := &storeMock{}
if IsHealthy(mock) {
t.Errorf("IsHealthy should return false")
}
mock = &storeMock{healthy: true}
if !IsHealthy(mock) {
t.Errorf("IsHealthy should return true")
}
}
By using:
type storeMock struct {
Store
...
}
One doesn't need to mock all Store methods. Only HealthCheck can be mocked, since only this method is used in the TestIsHealthy test.
Below the result of the test command:
$ go test -run '^TestIsHealthy$' ./main_test.go
ok command-line-arguments 0.003s
A real world example of this use case one can find when testing the AWS SDK.
To make it even more obvious, here is the ugly alternative - the minimum one needs to implement to satisfy the Store interface:
type storeMock struct {
healthy bool
}
func (s *storeMock) Create(a, b string) (i *Item, err error) {
return
}
func (s *storeMock) GetByID(a string) (i *Item, err error) {
return
}
func (s *storeMock) Update(i *Item) (err error) {
return
}
// HealthCheck is mocked function
func (s *storeMock) HealthCheck() error {
if !s.healthy {
return fmt.Errorf("mock error")
}
return nil
}
func (s *storeMock) Close() (err error) {
return
}
Embedding interfaces in a struct allows for partially "overriding" methods from the embedded interfaces. This, in turn, allows for delegation from the embedding struct to the embedded interface implementation.
The following example is taken from this blog post.
Suppose we want to have a socket connection with some additional functionality, like counting the total number of bytes read from it. We can define the following struct:
type StatsConn struct {
net.Conn
BytesRead uint64
}
StatsConn now implements the net.Conn interface and can be used anywhere a net.Conn is expected. When a StatsConn is initialized with a proper value implementing net.Conn for the embedded field, it "inherits" all the methods of that value; the key insight is, though, that we can intercept any method we wish, leaving all the others intact. For our purpose in this example, we'd like to intercept the Read method and record the number of bytes read:
func (sc *StatsConn) Read(p []byte) (int, error) {
n, err := sc.Conn.Read(p)
sc.BytesRead += uint64(n)
return n, err
}
To users of StatsConn, this change is transparent; we can still call Read on it and it will do what we expect (due to delegating to sc.Conn.Read), but it will also do additional bookkeeping.
It's critical to initialize a StatsConn properly, otherwise the field retains its default value nil causing a runtime error: invalid memory address or nil pointer dereference; for example:
conn, err := net.Dial("tcp", u.Host+":80")
if err != nil {
log.Fatal(err)
}
sconn := &StatsConn{conn, 0}
Here net.Dial returns a value that implements net.Conn, so we can use that to initialize the embedded field of StatsConn.
We can now pass our sconn to any function that expects a net.Conn argument, e.g:
resp, err := ioutil.ReadAll(sconn)
if err != nil {
log.Fatal(err)
And later we can access its BytesRead field to get the total.
This is an example of wrapping an interface. We created a new type that implements an existing interface, but reused an embedded value to implement most of the functionality. We could implement this without embedding by having an explicit conn field like this:
type StatsConn struct {
conn net.Conn
BytesRead uint64
}
And then writing forwarding methods for each method in the net.Conn interface, e.g.:
func (sc *StatsConn) Close() error {
return sc.conn.Close()
}
However, the net.Conn interface has many methods. Writing forwarding methods for all of them is tedious and unnecessary. Embedding the interface gives us all these forwarding methods for free, and we can override just the ones we need.
I will try another, low level approach to this.
Given the reverse struct:
type reverse struct {
Interface
}
This beside others means, that reverse struct has a field reverse.Interface, and as a struct fields, it can be nil or have value of type Interface.
If it is not nil, then the fields from the Interface are promoted to the "root" = reverse struct. It might be eclipsed by fields defined directly on the reverse struct, but that is not our case.
When You do something like:
foo := reverse{}, you can println it via fmt.Printf("%+v", foo) and got
{Interface:<nil>}
When you do the
foo := reverse{someInterfaceInstance}
It is equivalent of:
foo := reverse{Interface: someInterfaceInstance}
It feels to me like You declare expectation, that implementation of Interface API should by injected into your struct reverse in runtime. And this api will be then promoted to the root of struct reverse.
At the same time, this still allow inconsistency, where You have reverse struct instance with reverse.Interface = < Nil>, You compile it and get the panic on runtime.
When we look back to the specifically example of the reverse in OP, I can see it as a pattern, how you can replace/extend behaviour of some instance / implementation kind of in runtime contrary to working with types more like in compile time when You do embedding of structs instead of interfaces.
Still, it confuses me a lot. Especially the state where the Interface is Nil :(.