1
0
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:
Robert Griesemer 2010-06-03 16:55:50 -07:00
parent 28852c1531
commit 1d282a8eb2

View File

@ -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 &lt; 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>