Interfaces
/* * Go has the idea of an interface, which is a similar idea to what Java calls * an interface: a list of operations. It can represent any type (almost always * struct) which has (at least) that set of methods. An interface may be empty, * where it can represent anything, a bit like a Java Object. */ package main import "fmt" // Integer generator. type IntGen interface { gen() int } // Use the integer generator to simply print a series of its values. // We use the func nextSome(source IntGen, count int) { fmt.Printf("The next %d items:", count) for i := 0; i < count; i++ { fmt.Print(" ", source.gen()) } fmt.Println() } // Generator that always returns 42. type ReallyBoring struct { } func (me *ReallyBoring) gen() int { return 42 } // Generator which counts. type Count struct { at int } func (me *Count) gen() int { // Keep and increment ret := me.at me.at++ return ret } // Generator which make powers of two. type Pwr struct { at int } func (me *Pwr) gen() int { // Since there is no constructor, the object is always created // with at set to zero, which won't really do. Could make an init // method which would have to be called, but this is less error-prone. if me.at == 0 { me.at = 1 } // Keep and double. ret := me.at me.at *= 2 return ret } // Generator that rotates through the contents of an array. type RptSeries struct { loc int cont []int } func (me *RptSeries) gen() int { // Init ret to zero in case the list is empty (never set). ret := 0 // If there's some data take the next one, and advance. if len(me.cont) > 0 { ret = me.cont[me.loc] me.loc = (me.loc + 1) % len(me.cont) } return ret } // Set the contents. func (me *RptSeries) set(s []int) { me.loc = 0 me.cont = s } func main() { // Here we are using the interface with various objects // that implement it. But since the parameter's interface type is // automatically a pointer, we have to send & to something that // is not declared with *. That's just dumb. var rb ReallyBoring nextSome(&rb, 10) var cnt Count nextSome(&cnt, 10) var pwr Pwr nextSome(&pwr, 10) var ser RptSeries fred := [7]int { 3, 9, 18, 12, 2, 21, 9 } ser.set(fred[:]) nextSome(&ser, 10) }