mirror of
https://github.com/golang/go
synced 2024-11-22 00:14:42 -07:00
First cut at incorporating anonymous fields of pointer types into the
spec. I have deliberately removed the wording about receivers where it was before because I think it needs to be more precise. There is a TODO. DELTA=90 (54 added, 0 deleted, 36 changed) OCL=17597 CL=17716
This commit is contained in:
parent
8d3a3dd904
commit
071c91bf48
112
doc/go_spec.txt
112
doc/go_spec.txt
@ -4,7 +4,7 @@ The Go Programming Language Specification (DRAFT)
|
|||||||
Robert Griesemer, Rob Pike, Ken Thompson
|
Robert Griesemer, Rob Pike, Ken Thompson
|
||||||
|
|
||||||
----
|
----
|
||||||
(October 20, 2008)
|
(October 23, 2008)
|
||||||
|
|
||||||
|
|
||||||
This document is a semi-formal specification of the Go systems
|
This document is a semi-formal specification of the Go systems
|
||||||
@ -843,8 +843,8 @@ Types may be ``complete'' or ''incomplete''. Basic, pointer, function and
|
|||||||
interface types are always complete (although their components, such
|
interface types are always complete (although their components, such
|
||||||
as the base type of a pointer type, may be incomplete). All other types are
|
as the base type of a pointer type, may be incomplete). All other types are
|
||||||
complete when they are fully declared. Incomplete types are subject to
|
complete when they are fully declared. Incomplete types are subject to
|
||||||
usage restrictions; for instance a variable type cannot be an incomplete
|
usage restrictions; for instance the type of a variable must be complete
|
||||||
type.
|
where the variable is declared.
|
||||||
|
|
||||||
CompleteType = Type .
|
CompleteType = Type .
|
||||||
|
|
||||||
@ -1118,20 +1118,29 @@ types (§Types).
|
|||||||
f *();
|
f *();
|
||||||
}
|
}
|
||||||
|
|
||||||
A struct may contain ``anonymous fields'', which are declared with
|
A struct may contain ``anonymous fields'', which are declared with a type
|
||||||
a type name but no explicit field identifier. Instead, the unqualified type
|
but no explicit field identifier. An anonymous field type must be specified as
|
||||||
name acts as the field identifier. Anonymous fields must not be interface types.
|
a type name "T", or as a pointer to a type name ``*T'', and T itself may not be
|
||||||
|
a pointer or interface type. The unqualified type acts as the field identifier.
|
||||||
|
|
||||||
// A struct with two anonymous fields of type T1 and P.T2
|
// A struct with four anonymous fields of type T1, *T2, P.T3 and *P.T4
|
||||||
struct {
|
struct {
|
||||||
T1; // the field name is T1
|
T1; // the field name is T1
|
||||||
P.T2; // the field name is the unqualified type name T2
|
*T2; // the field name is T2
|
||||||
|
P.T3; // the field name is the unqualified type name T3
|
||||||
|
*P.T4; // the field name is the unqualified type name T4
|
||||||
x, y int;
|
x, y int;
|
||||||
}
|
}
|
||||||
|
|
||||||
The unqualified type name of an anonymous field must not conflict with the
|
The unqualified type name of an anonymous field must not conflict with the
|
||||||
field identifier (or unqualified type name for an anonymous field) of any
|
field identifier (or unqualified type name for an anonymous field) of any
|
||||||
other field within the struct.
|
other field within the struct. The following declaration is illegal:
|
||||||
|
|
||||||
|
struct {
|
||||||
|
T; // conflicts with anonymous field *T and *P.T
|
||||||
|
*T; // conflicts with anonymous field T and *P.T
|
||||||
|
*P.T; // conflicts with anonymous field T and *T
|
||||||
|
}
|
||||||
|
|
||||||
Fields and methods (§Method declarations) of an anonymous field become directly
|
Fields and methods (§Method declarations) of an anonymous field become directly
|
||||||
accessible as fields and methods of the struct without the need to provide the
|
accessible as fields and methods of the struct without the need to provide the
|
||||||
@ -1570,32 +1579,77 @@ A primary expression of the form
|
|||||||
x.f
|
x.f
|
||||||
|
|
||||||
denotes the field or method f of the value denoted by x (or of *x if
|
denotes the field or method f of the value denoted by x (or of *x if
|
||||||
x is of pointer type). The identifier f is called the ``selector''.
|
x is of pointer type). The identifier f is called the (field or method)
|
||||||
The following rules apply:
|
``selector''.
|
||||||
|
|
||||||
For x of type S or *S where S is a struct type (§Struct types):
|
A selector f may denote a field f declared in a type T, or it may refer
|
||||||
|
to a field f declared in a nested anonymous field of T. Analogously,
|
||||||
|
f may denote a method f of T, or it may refer to a method f of the type
|
||||||
|
of a nested anonymous field of T. The number of anonymous fields traversed
|
||||||
|
to get to the field or method is called its ``depth'' in T.
|
||||||
|
|
||||||
1) If f is declared as a (named or anonymous) field of S then x.f denotes
|
More precisely, the depth of a field or method f declared in T is zero.
|
||||||
that field.
|
The depth of a field or method f declared anywhere inside
|
||||||
|
an anonymous field A declared in T is the depth of f in A plus one.
|
||||||
|
|
||||||
2) If f is declared (or forward-declared) as a method of S textually
|
The following rules apply to selectors:
|
||||||
before x.f then x.f denotes that method and x becomes the receiver
|
|
||||||
of f.
|
|
||||||
|
|
||||||
3) Otherwise, if there is single anononymous field A of S such that
|
1) For a value x of type T or *T where T is not an interface type,
|
||||||
x.A.f denotes a valid field according to 1) or 2), then x.f is
|
x.f denotes the field or method at the shallowest depth in T where there
|
||||||
a shortcut for x.A.f, and x.A becomes the receiver of f.
|
is such an f. The type of x.f is the type of the field or method f.
|
||||||
If there is none or more then one anonymous field of S satisfying
|
If there is not exactly one f with shallowest depth, the selector
|
||||||
this criterion, x.f is illegal.
|
expression is illegal.
|
||||||
|
|
||||||
|
2) For a variable x of type I or *I where I is an interface type,
|
||||||
|
x.f denotes the actual method with name f of the value assigned
|
||||||
|
to x if there is such a method. The type of x.f is the type
|
||||||
|
of the method f. If no value or nil was assigned to x, x.f is illegal.
|
||||||
|
|
||||||
|
3) In all other cases, x.f is illegal.
|
||||||
|
|
||||||
|
Thus, selectors automatically dereference pointers as necessary. For instance,
|
||||||
|
for an x of type *T where T declares an f, x.f is a shortcut for (*x).f.
|
||||||
|
Furthermore, for an x of type T containing an anonymous field A declared as *A
|
||||||
|
inside T, and where A contains a field f, x.f is a shortcut for (*x.A).f
|
||||||
|
(assuming that the selector is legal in the first place).
|
||||||
|
|
||||||
|
The following examples illustrate selector use in more detail. Given the
|
||||||
|
declarations:
|
||||||
|
|
||||||
|
type T0 struct {
|
||||||
|
x int;
|
||||||
|
}
|
||||||
|
|
||||||
|
func (recv *T0) M0()
|
||||||
|
|
||||||
|
type T1 struct {
|
||||||
|
y int;
|
||||||
|
}
|
||||||
|
|
||||||
|
func (recv T1) M1()
|
||||||
|
|
||||||
|
type T2 struct {
|
||||||
|
z int;
|
||||||
|
T1;
|
||||||
|
*T0;
|
||||||
|
}
|
||||||
|
|
||||||
|
func (recv *T2) M2()
|
||||||
|
|
||||||
|
var p *T2; // with p != nil and p.T1 != nil
|
||||||
|
|
||||||
|
we can write:
|
||||||
|
|
||||||
|
p.z // (*p).z
|
||||||
|
p.y // ((*p).T1).y
|
||||||
|
p.x // (*(*p).T0).x
|
||||||
|
|
||||||
|
p.M2 // (*p).M2
|
||||||
|
p.M1 // ((*p).T1).M1
|
||||||
|
p.M0 // ((*p).T0).M0
|
||||||
|
|
||||||
|
|
||||||
For x of type I or *I where I is an interface type (§Interface types):
|
TODO: Specify what happens to receivers.
|
||||||
|
|
||||||
- If f is a method declared in I then x.f denotes the actual method with
|
|
||||||
name f of the value assigned to the variable x and x becomes the receiver
|
|
||||||
of f. If no value or nil was assigned to x, x.f is illegal.
|
|
||||||
|
|
||||||
Otherwise, x.f is illegal.
|
|
||||||
|
|
||||||
|
|
||||||
Indexes
|
Indexes
|
||||||
|
Loading…
Reference in New Issue
Block a user