mirror of
https://github.com/golang/go
synced 2024-11-22 03:14:41 -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:
parent
66113ac818
commit
83f648c962
@ -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
|
||||||
< less
|
< less
|
||||||
<= less or equal
|
<= less or equal
|
||||||
> greater
|
> greater
|
||||||
>= greater or equal
|
>= 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><</code>, <code><=</code>, <code>></code>, and <code>>=</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>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user