Go Interfaces: Difference between revisions

From NovaOrdis Knowledge Base
Jump to navigation Jump to search
Line 26: Line 26:


A type (<tt>struct</tt>, <font color=red>anything else?</font>) implements an interface implicitly, doing nothing else but exposing all methods from the interface's method set. "Exposing" in this context means the methods in question [[Go_Concepts_-_Functions#Receivers|is declared to use the type as receiver]]. This is called [[Go Concepts - The Type System#Duck_Typing|duck typing]]. There is no "implements" or "extends" keyword in Go.
A type (<tt>struct</tt>, <font color=red>anything else?</font>) implements an interface implicitly, doing nothing else but exposing all methods from the interface's method set. "Exposing" in this context means the methods in question [[Go_Concepts_-_Functions#Receivers|is declared to use the type as receiver]]. This is called [[Go Concepts - The Type System#Duck_Typing|duck typing]]. There is no "implements" or "extends" keyword in Go.
The example that follows shows how a type <tt>B</tt> can be modified to implement interface <tt>A</tt>:
<pre>
//
// The interface A declares a method set containing a single method m()
//
type A interface {
    m()
}
//
// At this point, the struct B is not yet linked to the interface A in any way
// (it does not implement interface A)
//
type B struct {
    i int
}
//
// We make B implement interface A by declaring B as a pointer receiver for m()
// Since A only contains m(), B implements A by the virtue of duck typing
//
func (bPtr *B) m() {
    // simply reports the value of i
    fmt.Println((*bPtr).i)
}
...
//
// B now implements A, so A methods can be invoked on B
//
b := B{1}
b.m()
...
</pre>


Interface instances can be used as arguments to functions. See [[#Passing_Interfaces_to_Functions|passing interfaces to functions]].
Interface instances can be used as arguments to functions. See [[#Passing_Interfaces_to_Functions|passing interfaces to functions]].

Revision as of 18:18, 30 March 2016

Internal

Overview

An interface is a type declaration that defines a method set. The method set is a list of methods a type must expose in order to implement the interface. See making a type implement an interface.

  • Can only structs be interfaces, or there are other things that can be interfaces?

Declaration

The interface declaration is introduced by the type keyword, to indicated that this is a user-defined type, followed by the interface name and the keyword interface. Unlike in the struct's case, we don't define fields but a method set.

type MyInterface interface {
     functionName1() return_type
     functionName2() return_type
     ...
}

Making a Type Implement an Interface

A type (struct, anything else?) implements an interface implicitly, doing nothing else but exposing all methods from the interface's method set. "Exposing" in this context means the methods in question is declared to use the type as receiver. This is called duck typing. There is no "implements" or "extends" keyword in Go.

The example that follows shows how a type B can be modified to implement interface A:

//
// The interface A declares a method set containing a single method m()
//
type A interface {
    m()
}

//
// At this point, the struct B is not yet linked to the interface A in any way
// (it does not implement interface A)
//
type B struct {
    i int
}

//
// We make B implement interface A by declaring B as a pointer receiver for m()
// Since A only contains m(), B implements A by the virtue of duck typing
//
func (bPtr *B) m() {
    // simply reports the value of i
    fmt.Println((*bPtr).i)
}

...

//
// B now implements A, so A methods can be invoked on B
//
b := B{1}
b.m()

...

Interface instances can be used as arguments to functions. See passing interfaces to functions.

Passing Interfaces to Functions

Interface instances can be used as arguments to functions.

A pointer to the interface instance can be passed as argument to a function after declaring that the function accepts a parameter of that interface type in the function signature.

Passing an interface pointer insures that the function body can rely on the fact the interface methods are available on the passed instance.

When passing an interface to a function, you should always pass a pointer to the instance implementing the interface, not the value of the instance implementing the interface.

In the example below, the f() function expects an interface

func f(a A) {
}