Updated: Method on slice

0

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.

go
methods
slice
asked on Stack Overflow May 11, 2019 by alexfwulf • edited May 11, 2019 by alexfwulf

1 Answer

3

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

Run it on the playground.

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
}
answered on Stack Overflow May 11, 2019 by Cerise Limón • edited May 12, 2019 by Cerise Limón

User contributions licensed under CC BY-SA 3.0