Hi there,

I played around a bit with the go2go playground today; I was wondering
how useful it would be to implement enums.

Whether using generics like this is a good idea or not is a different
discussion, it's just an interesting thing to experiment with and see
how far I could get.

I thought it might be useful to share my experience; I ran in to several
errors I couldn't really make sense of. This is probably a failure of
understanding on my part 😅 But I did spend quite some time in front of
the draft specification trying to figure this out.

All code was run on the "go2go" playground today.

Note I am not usually subscribed to the golang-nuts mailing list, and
have not read all of the discussions (using Google groups to browse
archives is a but of a pain), so apologies if this duplicates any
previous feedback.

Hope it helps.

Cheerio,
Martin

---

First, let's define my types:

        type (
                Banana  struct{ banana struct{} }
                Coconut struct{ coconut struct{} }

                Fruit interface {
                        type Banana, Coconut
                }
        )

And then adds a function which only accepts a "Fruit" enum value:

        func show(type enum Fruit)(fruit enum) {
                switch (interface{})(fruit).(type) {
                case Banana:
                        fmt.Println("That's just bananas!")
                case Coconut:
                        fmt.Println("I've got a lovely bunch of coconuts!")
                default:
                        fmt.Println("Yeah nah")
                }
        }

        func main() {
                show(Banana{})
                show(Coconut{})
        }

The type switch is somewhat ugly and has limitations, as mentioned in
the design document, but it works for this case.

Moving on, I wanted to add a function which accepts multiple fruits,
which gives an error:

        // type Coconut of (Coconut literal) does not match inferred type 
Banana for enum
        func showAll(type enum Fruit)(fruits ...enum) {
                for _, f := range fruits {
                        show(f)
                }
        }

In the spec it actually mentioned that:

> No variadic type parameters. There is no support for variadic type
> parameters, which would permit writing a single generic function that
> takes different numbers of both type parameters and regular
> parameters.

So looks like that's not supported, fait enough, but the error message
is a bit confusing. Second try:

        func showAll(type enum Fruit)(fruits []enum) {
                for _, f := range fruits {
                        show(f)
                }
        }

        func main() {
                // Fruit does not satisfy Fruit (interface{type Banana, 
Coconut} not found in Banana, Coconut)
                showAll([]Fruit{Banana{}})
        }

I'm not entirely sure what to make of that error 🤔

Adding a function which returns a Fruit also proved difficult:

        // cannot use (Banana literal) (value of type Banana) as enum value in 
return statement
        func getBanana(type enum Fruit)() enum {
                return Banana{}
        }

        // cannot convert (Banana literal) (value of type Banana) to enum
        func getBanana(type enum Fruit)() enum {
                return enum(Banana{})
        }

I'm not entirely sure why this doesn't work 🤔 It does work when you're
doing something like:

        // getBanana(Banana{})
        func getBanana(type enum Fruit)(v enum) enum {
                return v
        }

But this is a fairly useless function :-)

I also wasn't able to create a list of all Fruit types:

        // undefined: Fruit
        var FruitList = []Fruit{Banana{}, Coconut{}}

        func FruitList(type enum Fruit)() enum {
                // cannot use (Banana literal) (value of type Banana) as enum 
value in array or slice literal
                return []enum{Banana{}, Coconut{}}
        }

        // function type must have no type parameters
        var FruitList = func(type enum Fruit)() []enum {
                return []enum{}
        }

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/f7c19f07-809c-4cb2-9815-6d9a1b88d5f9%40www.fastmail.com.

Reply via email to