Go Interfaces: Difference between revisions
Line 25: | Line 25: | ||
=Making a Type Implement an Interface= | =Making a Type Implement an Interface= | ||
A type (<tt>struct</tt>, <font color=red>anything else?</font>) can be made to implement an interface by making the type to expose all methods from the interface's method set. "Exposing" in this context means that the methods | A type (<tt>struct</tt>, <font color=red>anything else?</font>) can be made to implement an interface by making the type to expose all methods from the interface's method set. "Exposing" in this context means that the methods [[Go_Concepts_-_Functions#Receivers|are declared to use the type in question as value or pointer receiver]]. | ||
This is called [[Go Concepts - The Type System#Duck_Typing|duck typing]]. There is no "implements" or "extends" keyword in Go. | This is called [[Go Concepts - The Type System#Duck_Typing|duck typing]]. There is no "implements" or "extends" keyword in Go. |
Revision as of 18:42, 30 March 2016
Internal
Overview
An interface is a type declaration that defines a method set. The method set is a list of method signatures designating 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, followed by the method set declaration between curly braces. The method set contains method signatures, so the interface type does not define behavior, but contract. Unlike in the struct's case, we don't define fields.
type MyInterface interface { functionName1() return_type functionName2() return_type ... }
Making a Type Implement an Interface
A type (struct, anything else?) can be made to implement an interface by making the type to expose all methods from the interface's method set. "Exposing" in this context means that the methods are declared to use the type in question as value or pointer 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 value receiver for // m(). Pointer receiver also works. Since A only contains m(), B implements // A by the virtue of duck typing // func (b B) m() { // simply reports the value of i fmt.Println(b.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
Interfaces can be used as arguments to functions. Passing an interface pointer insures that the function body can rely on the fact the interface methods are available on the passed instance.
With the example above, we declare a function f() that expects an interface A and we pass a B instance when invoking the function:
... func f(a A) { a.m() } ... b := B{1} f(b) ...
Note that the B instance can be passed by value (as in the example above) or by reference (as in the example below). Both cases work:
... b := B{1} f(&b) ...
or (same thing)
... bPtr := new(B) f(bPtr) ...