/*
* 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)
}