mirror of
https://github.com/golang/go
synced 2024-11-23 15:10:12 -07:00
go/types: clarify semantics of Selection
This is one of the more complex areas of the (pre-generics) spec, and I'm probably not the only person who can never remember all the details each time I need them. Change-Id: I25b3c46311df4db33357af5601c5e3586327dac2 Reviewed-on: https://go-review.googlesource.com/c/go/+/533736 Reviewed-by: Robert Griesemer <gri@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Alan Donovan <adonovan@google.com>
This commit is contained in:
parent
e6990b7629
commit
ede27fb4ac
@ -13,6 +13,39 @@ import (
|
||||
|
||||
// SelectionKind describes the kind of a selector expression x.f
|
||||
// (excluding qualified identifiers).
|
||||
//
|
||||
// If x is a struct or *struct, a selector expression x.f may denote a
|
||||
// sequence of selection operations x.a.b.c.f. The SelectionKind
|
||||
// describes the kind of the final (explicit) operation; all the
|
||||
// previous (implicit) operations are always field selections.
|
||||
// Each element of Indices specifies an implicit field (a, b, c)
|
||||
// by its index in the struct type of the field selection operand.
|
||||
//
|
||||
// For a FieldVal operation, the final selection refers to the field
|
||||
// specified by Selection.Obj.
|
||||
//
|
||||
// For a MethodVal operation, the final selection refers to a method.
|
||||
// If the "pointerness" of the method's declared receiver does not
|
||||
// match that of the effective receiver after implicit field
|
||||
// selection, then an & or * operation is implicitly applied to the
|
||||
// receiver variable or value.
|
||||
// So, x.f denotes (&x.a.b.c).f when f requires a pointer receiver but
|
||||
// x.a.b.c is a non-pointer variable; and it denotes (*x.a.b.c).f when
|
||||
// f requires a non-pointer receiver but x.a.b.c is a pointer value.
|
||||
//
|
||||
// All pointer indirections, whether due to implicit or explicit field
|
||||
// selections or * operations inserted for "pointerness", panic if
|
||||
// applied to a nil pointer, so a method call x.f() may panic even
|
||||
// before the function call.
|
||||
//
|
||||
// By contrast, a MethodExpr operation T.f is essentially equivalent
|
||||
// to a function literal of the form:
|
||||
//
|
||||
// func(x T, args) (results) { return x.f(args) }
|
||||
//
|
||||
// Consequently, any implicit field selections and * operations
|
||||
// inserted for "pointerness" are not evaluated until the function is
|
||||
// called, so a T.f or (*T).f expression never panics.
|
||||
type SelectionKind int
|
||||
|
||||
const (
|
||||
|
@ -15,6 +15,39 @@ import (
|
||||
|
||||
// SelectionKind describes the kind of a selector expression x.f
|
||||
// (excluding qualified identifiers).
|
||||
//
|
||||
// If x is a struct or *struct, a selector expression x.f may denote a
|
||||
// sequence of selection operations x.a.b.c.f. The SelectionKind
|
||||
// describes the kind of the final (explicit) operation; all the
|
||||
// previous (implicit) operations are always field selections.
|
||||
// Each element of Indices specifies an implicit field (a, b, c)
|
||||
// by its index in the struct type of the field selection operand.
|
||||
//
|
||||
// For a FieldVal operation, the final selection refers to the field
|
||||
// specified by Selection.Obj.
|
||||
//
|
||||
// For a MethodVal operation, the final selection refers to a method.
|
||||
// If the "pointerness" of the method's declared receiver does not
|
||||
// match that of the effective receiver after implicit field
|
||||
// selection, then an & or * operation is implicitly applied to the
|
||||
// receiver variable or value.
|
||||
// So, x.f denotes (&x.a.b.c).f when f requires a pointer receiver but
|
||||
// x.a.b.c is a non-pointer variable; and it denotes (*x.a.b.c).f when
|
||||
// f requires a non-pointer receiver but x.a.b.c is a pointer value.
|
||||
//
|
||||
// All pointer indirections, whether due to implicit or explicit field
|
||||
// selections or * operations inserted for "pointerness", panic if
|
||||
// applied to a nil pointer, so a method call x.f() may panic even
|
||||
// before the function call.
|
||||
//
|
||||
// By contrast, a MethodExpr operation T.f is essentially equivalent
|
||||
// to a function literal of the form:
|
||||
//
|
||||
// func(x T, args) (results) { return x.f(args) }
|
||||
//
|
||||
// Consequently, any implicit field selections and * operations
|
||||
// inserted for "pointerness" are not evaluated until the function is
|
||||
// called, so a T.f or (*T).f expression never panics.
|
||||
type SelectionKind int
|
||||
|
||||
const (
|
||||
|
Loading…
Reference in New Issue
Block a user