golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
120.1k stars 17.24k forks source link

x/spec: the selector rules list states that certain legal expressions are illegal #67099

Closed leabit closed 2 weeks ago

leabit commented 2 weeks ago

What is the URL of the page with the issue?

https://go.dev/ref/spec#Selectors

What is your user agent?

Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36

Screenshot

image

What did you do?

The official golang specification (selectors section) states the following two rules:

....

  1. As an exception, if the type of x is a defined pointer type and (x).f is a valid selector expression denoting a field (but not a method), x.f is shorthand for (x).f.
  2. In all other cases, x.f is illegal. ....

So, based on that, only the following should work:

package main

import "fmt"

type Human *struct {
    name string
}

func main() {
    var a Human = &struct{ name string }{"leabit1"}

    fmt.Println(a.name)

    a.name = "leabit2"

    fmt.Println(a.name)
}

What did you see happen?

However, the following two cases also work (even though, based on documentation, they are illegal):

1) Pointer to defined non-pointer type

package main

import "fmt"

type Human struct {
    name string
}

func main() {
    var a *Human = &Human{"leabit1"}

    fmt.Println(a.name)

    a.name = "leabit2"

    fmt.Println(a.name)
}
  1. Pointer to non-defined (unnamed) type
package main

import "fmt"

func main() {
    var a *struct{ name string } = &struct{ name string }{"leabit1"}

    fmt.Println(a.name)

    a.name = "leabit2"

    fmt.Println(a.name)
}

What did you expect to see?

I expect the documentation to include these two cases and not to consider them illegal.

seankhliao commented 2 weeks ago

Those are just the first case, where x = a T = Human or struct{ name string } f = name