1
0
mirror of https://github.com/golang/go synced 2024-11-21 21:14:47 -07:00

spec: allow comparison of structs, arrays containing comparable values

Also, clarify when interface comparison panics and
that comparison to nil is a special syntax rather than
a general comparison rule.

R=r, gri, r, iant, cw, bradfitz
CC=golang-dev
https://golang.org/cl/5440117
This commit is contained in:
Russ Cox 2011-12-12 22:21:46 -05:00
parent 66113ac818
commit 83f648c962

View File

@ -1,5 +1,5 @@
<!-- title The Go Programming Language Specification --> <!-- title The Go Programming Language Specification -->
<!-- subtitle Version of December 10, 2011 --> <!-- subtitle Version of December 12, 2011 -->
<!-- <!--
TODO TODO
@ -2909,72 +2909,103 @@ Comparison operators compare two operands and yield a value of type <code>bool</
!= not equal != not equal
&lt; less &lt; less
&lt;= less or equal &lt;= less or equal
> greater &gt; greater
>= greater or equal &gt;= greater or equal
</pre> </pre>
<p> <p>
The operands must be <i>comparable</i>; that is, the first operand In any comparison, the first operand
must be <a href="#Assignability">assignable</a> must be <a href="#Assignability">assignable</a>
to the type of the second operand, or vice versa. to the type of the second operand, or vice versa.
</p> </p>
<p> <p>
The operators <code>==</code> and <code>!=</code> apply The equality operators <code>==</code> and <code>!=</code> apply
to operands of all types except arrays and structs. to operands that are <i>comparable</i>.
All other comparison operators apply only to integer, floating-point The ordering operators <code>&lt;</code>, <code>&lt;=</code>, <code>&gt;</code>, and <code>&gt;=</code>
and string values. The result of a comparison is defined as follows: apply to operands that are <i>ordered</i>.
These terms and the result of the comparisons are defined as follows:
</p> </p>
<ul> <ul>
<li> <li>
Integer values are compared in the usual way. Boolean values are comparable.
Two boolean values are equal if they are either both
<code>true</code> or both <code>false</code>.
</li> </li>
<li> <li>
Floating point values are compared as defined by the IEEE-754 Integer values are comparable and ordered, in the usual way.
standard.
</li> </li>
<li> <li>
Two complex values <code>u</code>, <code>v</code> are Floating point values are comparable and ordered,
as defined by the IEEE-754 standard.
</li>
<li>
Complex values are comparable.
Two complex values <code>u</code> and <code>v</code> are
equal if both <code>real(u) == real(v)</code> and equal if both <code>real(u) == real(v)</code> and
<code>imag(u) == imag(v)</code>. <code>imag(u) == imag(v)</code>.
</li> </li>
<li> <li>
String values are compared byte-wise (lexically). String values are comparable and ordered, lexically byte-wise.
</li> </li>
<li> <li>
Boolean values are equal if they are either both Pointer values are comparable.
<code>true</code> or both <code>false</code>. Two pointer values are equal if they point to the same location or if both have value <code>nil</code>.
</li> </li>
<li> <li>
Pointer values are equal if they point to the same location Channel values are comparable.
or if both are <code>nil</code>. Two channel values are equal if they were created by the same call to <code>make</code>
</li>
<li>
A slice, map, or function value may be compared only to <code>nil</code>.
</li>
<li>
Channel 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>) <a href="#Making_slices_maps_and_channels">Making slices, maps, and channels</a>)
or if both are <code>nil</code>. or if both have value <code>nil</code>.
</li> </li>
<li> <li>
Interface values are equal if they have <a href="#Type_identity">identical</a> dynamic types and Interface values are comparable.
equal dynamic values or if both are <code>nil</code>. Two interface values are equal if they have <a href="#Type_identity">identical</a> dynamic types
and equal dynamic values or if both have value <code>nil</code>.
</li> </li>
<li> <li>
An interface value <code>x</code> is equal to a non-interface value A value <code>x</code> of non-interface type <code>X</code> and
<code>y</code> if the dynamic type of <code>x</code> is identical to a value <code>t</code> of interface type <code>T</code> are comparable when values
the static type of <code>y</code> and the dynamic value of <code>x</code> of type <code>X</code> are comparable and
is equal to <code>y</code>. <code>X</code> implements <code>T</code>.
They are equal if <code>t</code>'s dynamic type is identical to <code>X</code>
and <code>t</code>'s dynamic value is equal to <code>x</code>.
</li> </li>
<li> <li>
A pointer, function, slice, channel, map, or interface value is equal Struct values are comparable if all the fields are comparable.
to <code>nil</code> if it has been assigned the explicit value Two struct values are equal if their corresponding fields are equal.
<code>nil</code>, if it is uninitialized, or if it has been assigned </li>
another value equal to <code>nil</code>.
<li>
Array values are comparable if values of the array element type are comparable.
Two array values are equal if their corresponding elements are equal.
</li> </li>
</ul> </ul>
<p>
A comparison of two interface values with identical dynamic types
causes a <a href="#Run_time_panics">run-time panic</a> if values
of that type are not comparable. This behavior applies not only to direct interface
value comparisons but also when comparing arrays of interface values
or structs with interface-valued fields.
</p>
<p>
Slice, map, and function values are not comparable.
However, as a special case, a slice, map, or function value may
be compared to the predeclared identifier <code>nil</code>.
Comparison of pointer, channel, and interface values to <code>nil</code>
is also allowed and follows from the general rules above.
</p>
<h3 id="Logical_operators">Logical operators</h3> <h3 id="Logical_operators">Logical operators</h3>