Would it be possible to make this work in the future?

224 views
Skip to first unread message

محمد بومنذر

unread,
Aug 25, 2023, 10:44:02 AM8/25/23
to golang-nuts
Greetings everyone,

I'm writing a parser based on Go's `encoding/xml`, I tried to use the following pattern but it was deemed invalid:

```
switch tok := p.tok.(type) {
case xml.StartElement, xml.EndElement:
tok.Name.Local == "types"
}


```
To me, it'd make sense if it was allowed since both types are structs and both of them share the field `Name` with the subsequent field `Local`.

TheDiveO

unread,
Aug 25, 2023, 1:17:40 PM8/25/23
to golang-nuts
==?

Ian Lance Taylor

unread,
Aug 25, 2023, 4:43:05 PM8/25/23
to محمد بومنذر, golang-nuts
‪On Fri, Aug 25, 2023 at 7:43 AM ‫محمد بومنذر‬‎
<mohamme...@gmail.com> wrote:‬
>
> I'm writing a parser based on Go's `encoding/xml`, I tried to use the following pattern but it was deemed invalid:
>
> ```
> To me, it'd make sense if it was allowed since both types are structs and both of them share the field `Name` with the subsequent field `Local`.


Please post code as plain text or as a link to the Go playground, not
as an image. Images are much harder to read, and there is no reason
to use them for plain code. Thanks.

We are unlikely to implement such a language feature. We would have
to have careful definitions of what kinds of code are permitted in a
case with multiple types. And since in general there is no reason to
expect that the fields are at the same location, we would have to
compile the case differently for each type anyhow. And the code might
actually behave quite differently; should we permit code like

switch x := v.(type) {
case []int, map[int]int:
return x[1]
}

Ian

محمد بومنذر

unread,
Aug 25, 2023, 4:55:41 PM8/25/23
to golang-nuts
It's actually plain text but copied right from my editor with the theme styles, I'll use the playground for future examples.

Thank you for clarifying. I do see how the compiled version will need to be repetitive, although as you mentioned this piece of code is not a common case.

Ian Lance Taylor

unread,
Aug 25, 2023, 5:03:02 PM8/25/23
to محمد بومنذر, golang-nuts
‪On Fri, Aug 25, 2023 at 1:55 PM ‫محمد بومنذر‬‎
<mohamme...@gmail.com> wrote:‬
>
> It's actually plain text but copied right from my editor with the theme styles, I'll use the playground for future examples.

Thanks. Then I guess my request is to paste as plain text without styles.

Ian
> --
> 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...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/312da70b-11c3-43b1-b53e-6d1a8e622becn%40googlegroups.com.

Jan

unread,
Aug 26, 2023, 8:42:04 AM8/26/23
to golang-nuts
Notice that if you don't assign to `tok`, multiple alternatives in `case` works.

But the issue is that in Go there are no "duck typing" for data, only for methods (interfaces).  `xml.StartElement` and `xmlEndElement` not being the same type, the assignment ('tok.name.Local = "types"`) won't work.

Would converting to a method,  something like this, work for you  ? It could be changed by making the interface "Named" the type to match in the `switch` clause. There are many alternatives, the key point is when you are trying to share functionality (or data) across different types, it is usually done using common interfaces.


On Friday, August 25, 2023 at 4:44:02 PM UTC+2 محمد بومنذر wrote:

roger peppe

unread,
Aug 29, 2023, 9:48:49 AM8/29/23
to Ian Lance Taylor, محمد بومنذر, golang-nuts
> We would have to have careful definitions of what kinds of code are permitted in a case with multiple types.

ISTM that we already have such a careful definition with generics: given a case in a `switch x.(type)` statement of the form `T1, T2, ..., Tn`, where `x` is of type `S`, we could define the allowed operations of `x` as if it was a parameter to a a generic function with type constraint `interface {S; T1 | T2 | ... | Tn}`.

So your specific `[]int, map[int]int` example wouldn't be allowed, but this would:

    switch x := v.(type) {
    case int32, int64:
        fmt.Println(x + 1)
    }

Perhaps this could be considered a natural extension of the way that the type of `x` becomes `S` inside the default branch of the type switch statement.


Reply all
Reply to author
Forward
0 new messages