user1467267
user1467267

Reputation:

Golang Slice of custom Type in another Type as reference

I get this error with my Go test code:

$ go run test.go 
# command-line-arguments
./test.go:43: cannot use &ol1 (type *Orderline) as type Orderline in array element
./test.go:43: cannot use &ol2 (type *Orderline) as type Orderline in array element

Code

package main

import (
    "fmt"
)

type Customer struct {
    Id int64
    Name string
}

type Order struct {
    Id int64
    Customer *Customer
    Orderlines *[]Orderline
}

type Orderline struct {
    Id int64
    Product *Product
    Amount int64
}

type Product struct {
    Id int64
    Modelnr string
    Price float64
}

func (o *Order) total_amount() float64 {
    return 0.0 // Total amount collector for each Orderline goes here
}

func main() {
    c := Customer{1, "Customername"}

    p1 := Product{30, "Z97", 9.95}
    p2 := Product{31, "Z98", 25.00}

    ol1 := Orderline{10, &p1, 2}
    ol2 := Orderline{11, &p2, 6}

    ols := []Orderline{&ol1, &ol2}

    o := Order{1, &c, &ols}

    fmt.Println(o)
}

I also tried to append to the Slice in the Order directly, but it also failed:

o := new(Order)
o.Id = 1
o.Customer = &c
append(o.Orderlines, &ol1, &ol2)

throws:

$ go run test.go 
# command-line-arguments
./test.go:48: append(o.Orderlines, &ol1, &ol2) evaluated but not used

Upvotes: 1

Views: 6267

Answers (1)

mortdeus
mortdeus

Reputation: 197

The problem is that you are trying to put Orderline pointers into a slice that wants Orderline values.

type Order struct {
    Id int64
    Customer *Customer
    Orderlines *[]Orderline
}

Change this field's type from

Orderlines *[]Orderline

to...

Orderlines []*Orderline

You also need to change...

ols := []Orderline{&ol1, &ol2}

to

ols := []*Orderline{&ol1, &ol2}

In most cases defining a *[]slicetype is redundant because slices, maps, and channels are already reference types. In otherwords if you pass the value of a slice defined in main into a function, changes made to the copied slice's indices will mutate the original slice defined in main as well.

However, it's important to note that slices become decoupled from each other when an individual copy's underlying array is forced to grow it's capacity as a result of appending data to your slice. Therefore in certain scenarios you may find a pointer to a slice ideal or even necessary.

Upvotes: 4

Related Questions