-1

I understand that Go does not support enums of the kind shown in the Rust example below. What would be the idiomatic way of achieving the same effect, i.e., perform matching on types, in Go? For example, would I use an empty struct or an interface?

enum WebEvent {
    PageLoad,
    KeyPress(char),
}

fn inspect(event: WebEvent) {
    match event {
        WebEvent::PageLoad => println!("page loaded"),
        WebEvent::KeyPress(c) => println!("pressed '{}'.", c),
    }
}

Example taken from Rust By Example.

EternalObserver
  • 517
  • 7
  • 19
savx2
  • 1,011
  • 2
  • 10
  • 28
  • 3
    Possible duplicate of [How do I do enums in golang?](https://stackoverflow.com/questions/29083806/how-do-i-do-enums-in-golang) – Jonathan Hall Jul 24 '18 at 21:25
  • 2
    If this question is targeted towards Go users, you will have to explain what that code does and preferably show an attempt of your own first. – E_net4 Jul 24 '18 at 21:26
  • 3
    Also, probably a useful note: Rust enums are actually sum types rather than C-style enums. The suggested duplicate target does not seem to address this. – E_net4 Jul 24 '18 at 21:30
  • 1
    I know how to use Go enums, and I don't think that's the way to go. I am interested in matching different types and since I am new to Go I am not sure whether I would use an empty struct as parent or an interface or something else entirely – savx2 Jul 24 '18 at 21:32
  • 5
    @SavvasSavvides if they all have a common subset of methods, use an explicit interface. Otherwise, use an empty interface. Either way: type switch is your friend. – Adam Smith Jul 24 '18 at 21:33
  • 1
    something like this: https://play.golang.org/p/DPfbOKVyPk9 – dave Jul 24 '18 at 21:35
  • you can even make @dave's example more explicit by embedding his `WebEventInterface` (which I would call just `WebEvent` but that's neither here nor there) in each struct. – Adam Smith Jul 24 '18 at 21:38
  • 1
    Knowing the term "sum type" leads to blog posts [like this one](https://medium.com/@haya14busa/sum-union-variant-type-in-go-and-static-check-tool-of-switch-case-handling-3bfc61618b1e). – Shepmaster Jul 24 '18 at 21:38
  • Your question should be rewrote like: *How can I have a sum type equivalent in Go?* – Boiethios Jul 25 '18 at 07:17
  • @Boiethios yea well, I did not choose the question, it was edited by "moderators" who also added the recommended duplicate answer which is in fact completely irrelevant. – savx2 Jul 25 '18 at 08:11
  • @SavvasSavvides You put the Rust tag in your question... – Boiethios Jul 25 '18 at 08:13
  • @Boiethios Which was correctly removed. Were you talking about the tag or the title? – savx2 Jul 25 '18 at 08:23

1 Answers1

1

If your WebEvents share a common functionality, define an explicit interface.

type WebEvent interface {
    Foo()
    Bar()
}

type PageLoad struct{}

func (*pl PageLoad) Foo() {
    // do something
}

func (*pl PageLoad) Bar() {
    // do something else
}

func Inspect(event WebEvent) {
    switch event.(type) {
    case PageLoad:
        // inside this block you're operating on event.(PageLoad), not just event.(WebEvent)!
    }
}

Otherwise you can use an empty interface

type PageLoad struct{}  // optionally with methods as above

func Inspect(event interface{}) {
    switch event.(type) {
    case PageLoad:
        // similarly, in here event is a PageLoad, not an interface{}
    }
}
Adam Smith
  • 52,157
  • 12
  • 73
  • 112
  • 1
    I tried this and inside the case I still need to cast the event var or otherwise assign the result of `event.(type)` to a new variable in the switch, the `event` variable can't be used as the matched type directly inside the `case` branch – Asiel Diaz Benitez Apr 10 '23 at 18:14