Mixed type array in Go

1,348 views
Skip to first unread message

Tong Sun

unread,
Jan 4, 2018, 10:24:16 AM1/4/18
to golang-nuts

I need a data struct / solution that I can store mixed data-types into an array. How to architect that?


Details -- Consider the checkout point at the cashier, the checkout process receives the following string of instructions

  1. purchase
  2. coupon
  3. purchase
  4. purchase

I want to store all the above request data into an array, so I don't lost the sequence how they arrive, which in turn requests the array element to be either purchase or coupon.


How to make it happen? Thanks


Josh Humphries

unread,
Jan 4, 2018, 10:43:56 AM1/4/18
to Tong Sun, golang-nuts
You would typically define the array type as an array of some interface that is implemented by both purchase and coupon. You can then use a type-switch or type-assertion to determine/assert the actual type at runtime, on a per element basis.

If the two types do not share some interface (e.g. common methods), you could define the array as []interface{}. But this also allows code to accidentally add any kind of value to the array (not just a purchase or a coupon). So it may be better to create a marker interface -- an unexported interface with a no-op unexported marker method -- and make purchase and coupon both implement that interface.


For example:

type checkoutObject interface {
  checkoutObject()
}

type Purchase struct {
    // yadda yadda
}

func (p *Purchase) checkoutObject() {
    // no-op marker method
}


type Coupon struct {
    // yadda yadda
}

func (c *Coupon) checkoutObject() {
    // no-op marker method
}

// assert that Purchase and Coupon implement checkoutObject
var _ checkObject = (*Purchase)(nil)
var _ checkObject = (*Coupon)(nil)


// Now you can define your array like so:
var checkoutItems []checkoutObject
// The compiler will only let you add *Purchase and *Coupon
// values to the array.

// You can use the values at runtime like so:
for e := range checkoutItems {
    switch e := e.(type) {
    case *Purchase:
        // handle purchase
    case *Coupon:
        // handle coupon
    default:
        panic(fmt.Sprintf("unsupported type: %T", e))
    }
}


----
Josh Humphries
jh...@bluegosling.com

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Tong Sun

unread,
Jan 4, 2018, 10:59:35 AM1/4/18
to Josh Humphries, golang-nuts
That's really comprehensive. Thanks a million Josh!

Tong Sun

unread,
Jan 4, 2018, 12:03:12 PM1/4/18
to golang-nuts


On Thursday, January 4, 2018 at 10:59:35 AM UTC-5, Tong Sun wrote:
That's really comprehensive. Thanks a million Josh!


Hi Josh, FTA, 

I've archived your masterpiece as 
and

so that people can enjoy it right away.

Thanks again

Reply all
Reply to author
Forward
0 new messages