Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to access shared field in structs in generics in Go 1.18? I get error "type t has no field or method DATE_START"

I have two structs that have the some of the same field names and types:

type JOURNAL_TAG struct {
    DATE_START            time.Time
    DATE_END              time.Time
    ENTRY_NUMBER          uint
    VALUE                 float64
}

type INVENTORY_TAG struct {
    DATE_START   time.Time
    DATE_END     time.Time
    PRICE        float64
    QUANTITY     float64
    ACCOUNT_NAME string
}

and I have a func that accesses the common field DATE_START that should sort the slices of these types:

func sort_by_time[t JOURNAL_TAG|INVENTORY_TAG](slice []t, is_ascending bool) {
    sort.Slice(slice, func(i, j int) bool {
        return slice[i].DATE_START.After(slice[j].DATE_START) == is_ascending
    })
}

Running go build reports a compiler error:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

slice[i].DATE_START undefined (type t has no field or method DATE_START)

I want to sort the slices of these two types using generics, is it possible?

I am using go 1.18.

>Solution :

From the Go 1.18 release notes:

The Go compiler does not support accessing a struct field x.f where x is of type parameter type even if all types in the type parameter’s type set have a field f. We may remove this restriction in Go 1.19.

You could for example add a method to each of the structs that returns the DATA_START field, and then use that method as part of your type constraint.

One other comment is that you don’t need generics for this specific problem. Even without generics, you could define an interface:

type SomeInterface interface {
    DateStart() time.Time
}

and then sort:

    items := []SomeInterface{
        INVENTORY_TAG{...},
        INVENTORY_TAG{...},
    }
    sort.Slice(items, func(i, j int) bool { return items[i].DateStart().Before(timeSlice[j].DateStart()) })
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading