I am learning Go and have the following working code:
$GOPATH/src/mvctest/main.go
package main
import (
"fmt"
"mvctest/model"
)
func main() {
// Initialise the data model
employees := model.NewPeople("Employee")
// Populate the model
employees.Add(model.NewPerson("Joe", 99))
employees.Add(model.NewPerson("Sue", 45))
employees.Add(model.Person{Name: "Tom", Age: 22}) // break encaps a bit
// Test retrieval from model
fmt.Printf("You have %d employees.\n", employees.Count())
for i := 0; i < employees.Count(); i++ {
f, err := employees.Person(i)
if err != nil {
fmt.Printf("Unable to get employee %d because %v", i, err)
return
}
fmt.Printf("Employee %d is %s\n", i+1, f)
}
// Test error handling for impossible values
test(employees, -1)
test(employees, 42)
}
// Tests whether a person can be retrieved using an index value
func test(ppl *model.People, i int) *model.Person {
p, err := ppl.Person(i)
if err != nil {
fmt.Printf("Unable to get %s %d because %v\n", ppl.Group(), i, err)
return nil
}
return p
}
$GOPATH/src/mvctest/model/model.go
package model
import (
"errors"
"fmt"
)
// ------------------------------------------------------
type Person struct {
Name string
hatsize int
Age int
}
func (p *Person) String() string {
return fmt.Sprintf("%s aged %d.", p.Name, p.Age)
}
func NewPerson(name string, age int) Person {
return Person{name, 0, age}
}
// ------------------------------------------------------
type People struct {
group string
list []Person
}
func (ppl *People) SetGroup(g string) {
ppl.group = g
}
func (ppl *People) Group() string {
return ppl.group
}
func (ppl *People) Add(p Person) {
ppl.list = append(ppl.list, p)
}
func (ppl *People) Count() int {
return len(ppl.list)
}
func (ppl *People) Person(i int) (*Person, error) {
n := len(ppl.list)
if i < 0 || i >= n {
return nil,
errors.New(fmt.Sprintf("%s index %d is out of range %d-%d.",
ppl.group, i, 0, len(ppl.list)-1))
}
return &ppl.list[i], nil
}
func NewPeople(group string) *People {
ppl := new(People)
ppl.group = group
return ppl
}
Output
You have 3 employees.
Employee 1 is Joe aged 99.
Employee 2 is Sue aged 45.
Employee 3 is Tom aged 22.
Unable to get Employee -1 because Employee index -1 is out of range 0-2.
Unable to get Employee 42 because Employee index 42 is out of range 0-2.
I'd appreciate any comments but a few things that I am uncertain about or which bother me.
- I'm not sure whether defining constructing NewPerson and NewPeople is the right thing to do. I can't have two functions called New in the same file / package and I can't make these into methods of different structs (i.e. different object types) since the caller doesn't yet have an instance to use.
- I'm wondering if there is a simple way to allow iterating using
range
rather than thefor
loop inmain.go
?
range
have a look here \$\endgroup\$