Although I think the problem I have is not correctly described in the heading it is the only way I am able to describe it now.
I have a struct Mini
which is defined in another file. A set of Minis should be described as a slice. As I want to change some fields of the Mini
struct when it is appended to the slice custom functions for append are needed.
Until now I got the following code:
import (
"fmt"
"reflect"
)
//Minis is a slice of all Minis
type Minis struct {
AllMinis []*Mini
}
//Append adds a new Mini to the Minis slice
func (m *Minis) Append(n *Mini) {
m.AllMinis = append(m.AllMinis, n)
}
This code works totally fine. But in my opinion a struct with just one field is kind of witless.
Is there any way to make a method on a struct or a more elegant solution in general?
Thanks!
Edit: I solved it based on an answer like this:
//Append adds a new Mini to the Minis slice, recommended because of the usage of ID, returns a pointer to the created Mini
func (m *Minis) Append(n *Mini) *Mini {
highestID := 0
//get highest number for id
for _, l := range *m {
if highestID < l.ID {
highestID = l.ID
}
}
n.ID = highestID + 1
*m = append(*m, n)
return n
}
func (m *Minis) concat(n *Mini) *Minis {
*m = append(*m, n)
return m
}
So basically Append
appends an object with a new ID, concat
appends without a new ID.
It should run fine, but it doesn't. There's no difference between the append functions and I'm getting the following output in the console:
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x0 pc=0x4908f9]
goroutine 1 [running]:
ign/ign.(*Minis).Concat(...)
D:/Code/GOPATH/src/ign/ign/minicontainer.go:21
ign/ign.(*Minis).QForename(0xc000081f60, 0x4c1d5e, 0x6, 0x40b1ff)
D:/Code/GOPATH/src/ign/ign/minicontainer.go:58 +0x99
main.appendTest()
D:/code/gopath/src/ign/main.go:60 +0x169
main.main()
D:/code/gopath/src/ign/main.go:25 +0x27
exit status 2
The mentioned QForename
is this:
//QForename queries by Surname
func (m *Minis) QForename(q string) *Minis {
var matches *Minis
fmt.Println(matches)
for _, n := range *m {
if n.Forename == q {
matches.concat(n)
}
}
return matches
}
As far as I can see there shouldn't be any problem. See here for a more complete example.
Declare the type as a slice:
//Minis is a slice of all Minis
type Minis []*Mini
//Append adds a new Mini to the Minis slice
func (m *Minis) Append(n *Mini) {
*m = append(*m, n)
}
concat
panics because QForename
passes a nil slice pointer as the receiver to concat
. Fix by using a non-nil pointer:
func (m *Minis) QForename(q string) *Minis {
var matches Minis
for _, n := range *m {
if n.Forename == q {
matches.concat(n)
}
}
return &matches
}
User contributions licensed under CC BY-SA 3.0