mirror of
https://github.com/golang/go
synced 2024-11-21 22:34:48 -07:00
go spec: Base comparison compatibility on assignment compatibility.
Specifically: - Simplified definition of comparison compatibility and folded into section on comparison operators since it's only used there. This is a small language change/cleanup. As a consequence: - An interface value may now be compared against a non-interface value. - Channels with opposite directions cannot be compared directly anymore (per discussion with rsc). R=rsc, r, iant, ken2 CC=golang-dev https://golang.org/cl/1462041
This commit is contained in:
parent
28852c1531
commit
1d282a8eb2
141
doc/go_spec.html
141
doc/go_spec.html
@ -1,9 +1,8 @@
|
|||||||
<!-- title The Go Programming Language Specification -->
|
<!-- title The Go Programming Language Specification -->
|
||||||
<!-- subtitle Version of May 26, 2010 -->
|
<!-- subtitle Version of June 1, 2010 -->
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Todo
|
TODO
|
||||||
[ ] clarify: two equal lower-case identifiers from different packages denote different objects
|
|
||||||
[ ] need language about function/method calls and parameter passing rules
|
[ ] need language about function/method calls and parameter passing rules
|
||||||
[ ] last paragraph of #Assignments (constant promotion) should be elsewhere
|
[ ] last paragraph of #Assignments (constant promotion) should be elsewhere
|
||||||
and mention assignment to empty interface.
|
and mention assignment to empty interface.
|
||||||
@ -17,6 +16,7 @@ Todo
|
|||||||
though obvious
|
though obvious
|
||||||
[ ] specify iteration direction for range clause
|
[ ] specify iteration direction for range clause
|
||||||
[ ] review language on implicit dereferencing
|
[ ] review language on implicit dereferencing
|
||||||
|
[ ] clarify what it means for two functions to be "the same" when comparing them
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
|
||||||
@ -1121,9 +1121,9 @@ KeyType = Type .
|
|||||||
|
|
||||||
<p>
|
<p>
|
||||||
The comparison operators <code>==</code> and <code>!=</code>
|
The comparison operators <code>==</code> and <code>!=</code>
|
||||||
(§<a href="#Comparison_operators">Comparison operators</a>) must be fully defined for operands of the
|
(§<a href="#Comparison_operators">Comparison operators</a>) must be fully defined
|
||||||
key type; thus the key type must be a boolean, numeric, string, pointer, function, interface,
|
for operands of the key type; thus the key type must not be a struct, array or slice.
|
||||||
map, or channel type. If the key type is an interface type, these
|
If the key type is an interface type, these
|
||||||
comparison operators must be defined for the dynamic key values;
|
comparison operators must be defined for the dynamic key values;
|
||||||
failure will cause a <a href="#Run_time_panics">run-time panic</a>.
|
failure will cause a <a href="#Run_time_panics">run-time panic</a>.
|
||||||
|
|
||||||
@ -1374,58 +1374,6 @@ represents the <a href="#The_zero_value">zero value</a> for that type.
|
|||||||
Any value may be assigned to the <a href="#Blank_identifier">blank identifier</a>.
|
Any value may be assigned to the <a href="#Blank_identifier">blank identifier</a>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h3 id="Comparison_compatibility">Comparison compatibility</h3>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Except as noted, values of any type may be compared to other values of
|
|
||||||
<a href="#Type_compatibility">compatible static type</a>.
|
|
||||||
Values of integer, floating-point, and string type may be compared using the
|
|
||||||
full range of <a href="#Comparison_operators;">comparison operators</a>;
|
|
||||||
booleans and complex values may be compared only for equality or inequality.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Values of composite type may be
|
|
||||||
compared for equality or inequality using the <code>==</code> and
|
|
||||||
<code>!=</code> operators, with the following provisos:
|
|
||||||
</p>
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
Arrays and structs may not be compared to anything.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
A slice value may only be compared explicitly against <code>nil</code>.
|
|
||||||
A slice value is equal to <code>nil</code> if it has been assigned the explicit
|
|
||||||
value <code>nil</code>, if it is uninitialized, or if it has
|
|
||||||
been assigned another slice value equal to <code>nil</code>·
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
An interface value is equal to <code>nil</code> if it has
|
|
||||||
been assigned the explicit value <code>nil</code>, if it is uninitialized,
|
|
||||||
or if it has been assigned another interface value equal to <code>nil</code>.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
For types that can be compared to <code>nil</code>,
|
|
||||||
two values of the same type are equal if they both equal <code>nil</code>,
|
|
||||||
unequal if one equals <code>nil</code> and one does not.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
Pointer values are equal if they point to the same location.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
Function values are equal if they refer to the same function.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
Channel and map values are equal if they were created by the same call to <code>make</code>
|
|
||||||
(§<a href="#Making_slices">Making slices</a>, maps, and channels).
|
|
||||||
When comparing two values of channel type, the channel value types
|
|
||||||
must be identical but the channel direction is ignored.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
Interface values may be compared if they have compatible static types.
|
|
||||||
They will be equal only if they have the same dynamic type and the underlying values are equal.
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h2 id="Blocks">Blocks</h2>
|
<h2 id="Blocks">Blocks</h2>
|
||||||
|
|
||||||
@ -2960,11 +2908,7 @@ not occur. For instance, it may not assume that <code>x < x + 1</code> is alw
|
|||||||
<h3 id="Comparison_operators">Comparison operators</h3>
|
<h3 id="Comparison_operators">Comparison operators</h3>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Comparison operators yield a value of type <code>bool</code>.
|
Comparison operators compare two operands and yield a value of type <code>bool</code>.
|
||||||
The operators <code>==</code> and <code>!=</code> apply
|
|
||||||
to operands of all types except arrays and structs.
|
|
||||||
All other comparison operators apply only to integer, floating-point
|
|
||||||
and string values.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre class="grammar">
|
<pre class="grammar">
|
||||||
@ -2977,20 +2921,71 @@ and string values.
|
|||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Operands of numeric type are compared in the usual way.
|
The operands must be <i>comparable</i>; that is, the first operand
|
||||||
</p>
|
must be <a href="#Assignment_compatibility">assignment compatible</a>
|
||||||
|
with the type of the second operand, or vice versa.
|
||||||
<p>
|
<p>
|
||||||
Operands of string type are compared byte-wise (lexically).
|
|
||||||
</p>
|
</p>
|
||||||
<p>
|
The operators <code>==</code> and <code>!=</code> apply
|
||||||
Operands of boolean type are equal if they are either both <code>true</code>
|
to operands of all types except arrays and structs.
|
||||||
or both <code>false</code>.
|
All other comparison operators apply only to integer, floating-point
|
||||||
</p>
|
and string values. The result of a comparison is defined as follows:
|
||||||
<p>
|
|
||||||
The rules for comparison of composite types are described in the
|
|
||||||
section on §<a href="#Comparison_compatibility">Comparison compatibility</a>.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
Integer values are compared in the usual way.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Floating point values are compared as defined by the IEEE-754
|
||||||
|
standard.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Two complex values <code>u</code>, <code>v</code> are
|
||||||
|
equal if both <code>real(u) == real(v)</code> and
|
||||||
|
<code>imag(u) == imag(v)</code>.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
String values are compared byte-wise (lexically).
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Boolean values are are equal if they are either both
|
||||||
|
<code>true</code> or both <code>false</code>.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Pointer values are equal if they point to the same location
|
||||||
|
or if both are <code>nil</code>.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Function values are equal if they refer to the same function
|
||||||
|
or if both are <code>nil</code>.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
A slice value may only be compared to <code>nil</code>.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Channel and map values are equal if they were created by the same call to <code>make</code>
|
||||||
|
(§<a href="#Making_slices_maps_and_channels">Making slices, maps, and channels</a>)
|
||||||
|
or if both are <code>nil</code>.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Interface values are equal if they have identical dynamic types and
|
||||||
|
equal dynamic values or if both are <code>nil</code>.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
An interface value <code>x</code> is equal to a non-interface value
|
||||||
|
<code>y</code> if the dynamic type of <code>x</code> is identical to
|
||||||
|
the static type of <code>y</code> and the dynamic value of <code>x</code>
|
||||||
|
is equal to <code>y</code>.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
A pointer, function, slice, channel, map, or interface value is equal
|
||||||
|
to <code>nil</code> if it has been assigned the explicit value
|
||||||
|
<code>nil</code>, if it is uninitialized, or if it has been assigned
|
||||||
|
another value equal to <code>nil</code>.
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
<h3 id="Logical_operators">Logical operators</h3>
|
<h3 id="Logical_operators">Logical operators</h3>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user