mirror of
https://github.com/golang/go
synced 2024-11-11 23:20:24 -07:00
new method set rules
DELTA=63 (27 added, 6 deleted, 30 changed) OCL=29065 CL=29091
This commit is contained in:
parent
1b3b51f7db
commit
56809d0ade
@ -8,7 +8,6 @@ Open issues:
|
|||||||
- no mechanism to declare a local type name: type T P.T
|
- no mechanism to declare a local type name: type T P.T
|
||||||
|
|
||||||
Todo's:
|
Todo's:
|
||||||
[ ] new interface rules per rsc (use "method set" terminology)
|
|
||||||
[ ] document illegality of package-external tuple assignments to structs
|
[ ] document illegality of package-external tuple assignments to structs
|
||||||
w/ private fields: P.T(1, 2) illegal since same as P.T(a: 1, b: 2) for
|
w/ private fields: P.T(1, 2) illegal since same as P.T(a: 1, b: 2) for
|
||||||
a T struct { a b int }.
|
a T struct { a b int }.
|
||||||
@ -418,10 +417,10 @@ literal.
|
|||||||
<h2>Types</h2>
|
<h2>Types</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
A type determines the set of values and operations specific to values of that type.
|
A type determines the set of values and operations specific to values of that
|
||||||
A type may be specified by a (possibly qualified (§Qualified identifiers))
|
type. A type may be specified by a (possibly qualified) <i>type name</i>
|
||||||
type name (§Type declarations) or a <i>type literal</i>,
|
(§Qualified identifier, §Type declarations) or a <i>type literal</i>,
|
||||||
which composes a new type in terms of previously declared types.
|
which composes a new type from previously declared types.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre class="grammar">
|
<pre class="grammar">
|
||||||
@ -450,10 +449,16 @@ because the size of the pointer itself is always known.
|
|||||||
interface fit in here.)
|
interface fit in here.)
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
The <i>interface</i> of a type is the set of methods bound to it
|
A type may have a method set associated with it
|
||||||
(§Method declarations); for pointer types, it is the interface
|
(§Interface types, §Method declarations).
|
||||||
of the pointer base type (§Pointer types). All types have an interface;
|
The method set of an interface type (§Interface types) is its interface.
|
||||||
if they have no methods, it is the <i>empty interface</i>.
|
The method set of any other named type <code>T</code>
|
||||||
|
consists of all methods with receiver
|
||||||
|
type <code>T</code>.
|
||||||
|
The method set of the corresponding pointer type <code>*T</code>
|
||||||
|
is the set of all methods with receiver <code>*T</code> or <code>T</code>
|
||||||
|
(that is, it also contains the method set of <code>T</code>).
|
||||||
|
Any other type has an empty method set.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
The <i>static type</i> (or just <i>type</i>) of a variable is the
|
The <i>static type</i> (or just <i>type</i>) of a variable is the
|
||||||
@ -461,7 +466,7 @@ type defined by its declaration. Variables of interface type
|
|||||||
(§Interface types) also have a distinct <i>dynamic type</i>, which
|
(§Interface types) also have a distinct <i>dynamic type</i>, which
|
||||||
is the actual type of the value stored in the variable at run-time.
|
is the actual type of the value stored in the variable at run-time.
|
||||||
The dynamic type may vary during execution but is always compatible
|
The dynamic type may vary during execution but is always compatible
|
||||||
with the static type of the interface variable. For non-interfaces
|
with the static type of the interface variable. For non-interface
|
||||||
types, the dynamic type is always the static type.
|
types, the dynamic type is always the static type.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@ -736,10 +741,28 @@ struct {
|
|||||||
<p>
|
<p>
|
||||||
Fields and methods (§Method declarations) of an anonymous field are
|
Fields and methods (§Method declarations) of an anonymous field are
|
||||||
promoted to be ordinary fields and methods of the struct (§Selectors).
|
promoted to be ordinary fields and methods of the struct (§Selectors).
|
||||||
|
The following rules apply for a struct type named <code>S</code> and
|
||||||
|
a type named <code>T</code>:
|
||||||
</p>
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>If <code>S</code> contains an anonymous field <code>T</code>, the
|
||||||
|
method set of <code>S</code> includes the method set of <code>T</code>.
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>If <code>S</code> contains an anonymous field <code>*T</code>, the
|
||||||
|
method set of <code>S</code> includes the method set of <code>*T</code>
|
||||||
|
(which itself includes the method set of <code>T</code>).
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>If <code>S</code> contains an anonymous field <code>T</code> or
|
||||||
|
<code>*T</code>, the method set of <code>*S</code> includes the
|
||||||
|
method set of <code>*T</code> (which itself includes the method
|
||||||
|
set of <code>T</code>).
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
<p>
|
<p>
|
||||||
A field declaration may be followed by an optional string literal <i>tag</i>, which
|
A field declaration may be followed by an optional string literal <i>tag</i>,
|
||||||
becomes an attribute for all the identifiers in the corresponding
|
which becomes an attribute for all the identifiers in the corresponding
|
||||||
field declaration. The tags are made
|
field declaration. The tags are made
|
||||||
visible through a reflection library (TODO: reference?)
|
visible through a reflection library (TODO: reference?)
|
||||||
but are otherwise ignored.
|
but are otherwise ignored.
|
||||||
@ -824,10 +847,10 @@ func (n int) (func (p* T))
|
|||||||
<h3>Interface types</h3>
|
<h3>Interface types</h3>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
An interface type specifies an unordered set of methods. A variable
|
An interface type specifies a method set called its <i>interface</i>.
|
||||||
of interface type can store, dynamically, any value that implements
|
A variable of interface type can store a value of any type with a method set
|
||||||
at least that set of methods.
|
that is any superset of the interface. Such a type is said to
|
||||||
An interface value may be <code>nil</code>.
|
<i>implement the interface</i>. An interface value may be <code>nil</code>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre class="grammar">
|
<pre class="grammar">
|
||||||
@ -846,11 +869,9 @@ interface {
|
|||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Any type (including interface types) whose interface includes,
|
More than one type may implement an interface.
|
||||||
possibly as a subset, the complete set of methods of an interface <code>I</code>
|
|
||||||
is said to implement interface <code>I</code>.
|
|
||||||
For instance, if two types <code>S1</code> and <code>S2</code>
|
For instance, if two types <code>S1</code> and <code>S2</code>
|
||||||
have the methods
|
have the method set
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
@ -1066,7 +1087,7 @@ identical types. In detail:
|
|||||||
|
|
||||||
<li>Two struct types are identical if they have the same sequence of fields,
|
<li>Two struct types are identical if they have the same sequence of fields,
|
||||||
and if corresponding fields have the same names and identical types.
|
and if corresponding fields have the same names and identical types.
|
||||||
Two anonymous fields are considered to have the same name.</li>
|
Two anonymous fields are considered to have the same name.</li>
|
||||||
|
|
||||||
<li>Two pointer types are identical if they have identical base types.</li>
|
<li>Two pointer types are identical if they have identical base types.</li>
|
||||||
|
|
||||||
@ -1620,9 +1641,10 @@ Receiver = "(" [ identifier ] [ "*" ] TypeName ")" .
|
|||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The receiver type must be a type name or a pointer to a type name,
|
The receiver type must be of the form <code>T</code> or <code>*T</code> where
|
||||||
and that name is called the <i>receiver base type</i> or just <i>base type</i>.
|
<code>T</code> is a type name. <code>T</code> is called the
|
||||||
The base type must not be a pointer type and must be
|
<i>receiver base type</i> or just <i>base type</i>.
|
||||||
|
The base type must not be a pointer or interface type and must be
|
||||||
declared in the same source file as the method.
|
declared in the same source file as the method.
|
||||||
The method is said to be <i>bound</i> to the base type
|
The method is said to be <i>bound</i> to the base type
|
||||||
and is visible only within selectors for that type
|
and is visible only within selectors for that type
|
||||||
@ -1630,8 +1652,6 @@ and is visible only within selectors for that type
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
All methods bound to a base type must have the same receiver type,
|
|
||||||
either all pointers to the base type or all the base type itself.
|
|
||||||
Given type <code>Point</code>, the declarations
|
Given type <code>Point</code>, the declarations
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@ -1652,8 +1672,7 @@ to the base type <code>Point</code>.
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
If the
|
If the receiver's value is not referenced inside the the body of the method,
|
||||||
receiver's value is not referenced inside the the body of the method,
|
|
||||||
its identifier may be omitted in the declaration. The same applies in
|
its identifier may be omitted in the declaration. The same applies in
|
||||||
general to parameters of functions and methods.
|
general to parameters of functions and methods.
|
||||||
</p>
|
</p>
|
||||||
@ -1723,8 +1742,8 @@ func F(a int) int {
|
|||||||
|
|
||||||
<p>
|
<p>
|
||||||
An expression specifies the computation of a value by applying
|
An expression specifies the computation of a value by applying
|
||||||
operators and functions to operands. An expression has a value and
|
operators and functions to operands. An expression has a value
|
||||||
a type.
|
and a type.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h3>Operands</h3>
|
<h3>Operands</h3>
|
||||||
@ -2262,10 +2281,12 @@ pt.Scale(3.5) // method call with receiver pt
|
|||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
If the receiver type of the method is declared as a pointer of type <code>*T</code>,
|
A method call <code>x.m()</code> is valid if the method set of
|
||||||
the actual receiver may be a value of type <code>T</code>;
|
(the type of) <code>x</code> contains <code>m</code> (and the
|
||||||
in such cases method invocation implicitly takes the
|
argument list is compatible with the parameter list of <code>m</code>).
|
||||||
receiver's address:
|
If <code>x</code> is addressable and <code>&x</code>'s method
|
||||||
|
set contains <code>m</code>, <code>x.m()</code> is shorthand
|
||||||
|
for <code>(&x).m()</code>:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
|
Loading…
Reference in New Issue
Block a user