summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2022-12-12 16:30:42 -0800
committerRobert Griesemer <gri@golang.org>2022-12-14 19:12:15 +0000
commitffefcd360b64e197131d6dc37a7ed015a2643c1b (patch)
tree1cc079e47a8a969c081f84d8619e7f606e3041d7 /doc
parentcb07765045aed5104a3df31507564ac99e6ddce8 (diff)
downloadgo-git-ffefcd360b64e197131d6dc37a7ed015a2643c1b.tar.gz
spec: introduce notion of strict comparability
- Rephrase the notion of "comparability" from a property of values (operands) to a property of types and adjust dependent prose. - Introduce the notion of "strict comparability". - Fix the definitions of comparability for type interfaces and type parameters. - Define the predeclared identifier "comparable" as stricly comparable. These changes address existing problems in the spec as outlined in the section on "Related spec issues" in issue #56548. For #56548. Change-Id: Ibc8c2f36d92857a5134eadc18358624803d3dd21 Reviewed-on: https://go-review.googlesource.com/c/go/+/457095 Reviewed-by: Ian Lance Taylor <iant@google.com> Reviewed-by: Matthew Dempsky <mdempsky@google.com> TryBot-Bypass: Robert Griesemer <gri@google.com> Reviewed-by: Robert Findley <rfindley@google.com> Reviewed-by: Robert Griesemer <gri@google.com>
Diffstat (limited to 'doc')
-rw-r--r--doc/go_spec.html84
1 files changed, 57 insertions, 27 deletions
diff --git a/doc/go_spec.html b/doc/go_spec.html
index 6d7f90e98d..7b4bde0fe0 100644
--- a/doc/go_spec.html
+++ b/doc/go_spec.html
@@ -1,6 +1,6 @@
<!--{
"Title": "The Go Programming Language Specification",
- "Subtitle": "Version of November 21, 2022",
+ "Subtitle": "Version of December 14, 2022",
"Path": "/ref/spec"
}-->
@@ -2684,18 +2684,17 @@ other interfaces based on their type sets. But this should get us going for now.
The <a href="#Predeclared_identifiers">predeclared</a>
<a href="#Interface_types">interface type</a> <code>comparable</code>
denotes the set of all non-interface types that are
-<a href="#Comparison_operators">comparable</a>. Specifically,
+<a href="#Comparison_operators">strictly comparable</a>. Specifically,
a type <code>T</code> implements <code>comparable</code> if:
</p>
<ul>
<li>
- <code>T</code> is not an interface type and <code>T</code> supports the operations
- <code>==</code> and <code>!=</code>; or
+ <code>T</code> is not an interface type and <code>T</code> is strictly comparable; or
</li>
<li>
<code>T</code> is an interface type and each type in <code>T</code>'s
- <a href="#Interface_types">type set</a> implements <code>comparable</code>.
+ <a href="#Interface_types">type set</a> is strictly comparable.
</li>
</ul>
@@ -2707,12 +2706,13 @@ Even though interfaces that are not type parameters can be
</p>
<pre>
-int // implements comparable
+int // implements comparable (int is strictly comparable)
[]byte // does not implement comparable (slices cannot be compared)
interface{} // does not implement comparable (see above)
-interface{ ~int | ~string } // type parameter only: implements comparable
-interface{ comparable } // type parameter only: implements comparable
-interface{ ~int | ~[]byte } // type parameter only: does not implement comparable (not all types in the type set are comparable)
+interface{ ~int | ~string } // type parameter only: implements comparable (int, string types are stricly comparable)
+interface{ comparable } // type parameter only: implements comparable (comparable implements itself)
+interface{ ~int | ~[]byte } // type parameter only: does not implement comparable (slices are not comparable)
+interface{ ~struct{ any } } // type parameter only: does not implement comparable (field any is not strictly comparable)
</pre>
<p>
@@ -5019,69 +5019,71 @@ to the type of the second operand, or vice versa.
</p>
<p>
The equality operators <code>==</code> and <code>!=</code> apply
-to operands that are <i>comparable</i>.
+to operands of <i>comparable</i> types.
The ordering operators <code>&lt;</code>, <code>&lt;=</code>, <code>&gt;</code>, and <code>&gt;=</code>
-apply to operands that are <i>ordered</i>.
+apply to operands of <i>ordered</i> types.
These terms and the result of the comparisons are defined as follows:
</p>
<ul>
<li>
- Boolean values are comparable.
+ Boolean types are comparable.
Two boolean values are equal if they are either both
<code>true</code> or both <code>false</code>.
</li>
<li>
- Integer values are comparable and ordered, in the usual way.
+ Integer types are comparable and ordered.
+ Two integer values are compared in the usual way.
</li>
<li>
- Floating-point values are comparable and ordered,
- as defined by the IEEE-754 standard.
+ Floating-point types are comparable and ordered.
+ Two floating-point values are compared as defined by the IEEE-754 standard.
</li>
<li>
- Complex values are comparable.
+ Complex types are comparable.
Two complex values <code>u</code> and <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 comparable and ordered, lexically byte-wise.
+ String types are comparable and ordered.
+ Two string values are compared lexically byte-wise.
</li>
<li>
- Pointer values are comparable.
+ Pointer types are comparable.
Two pointer values are equal if they point to the same variable or if both have value <code>nil</code>.
Pointers to distinct <a href="#Size_and_alignment_guarantees">zero-size</a> variables may or may not be equal.
</li>
<li>
- Channel values are comparable.
+ Channel types are comparable.
Two channel values are equal if they were created by the same call to
<a href="#Making_slices_maps_and_channels"><code>make</code></a>
or if both have value <code>nil</code>.
</li>
<li>
- Interface values are comparable.
+ Interface types that are not type parameters are comparable.
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>
A value <code>x</code> of non-interface type <code>X</code> and
- a value <code>t</code> of interface type <code>T</code> are comparable when values
- of type <code>X</code> are comparable and
+ a value <code>t</code> of interface type <code>T</code> can be compared
+ if type <code>X</code> is comparable and
<code>X</code> <a href="#Implementing_an_interface">implements</a> <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>
- Struct values are comparable if all their fields are comparable.
+ Struct types are comparable if all their field types are comparable.
Two struct values are equal if their corresponding
non-<a href="#Blank_identifier">blank</a> field values are equal.
The fields are compared in source order, and comparison stops as
@@ -5089,23 +5091,27 @@ These terms and the result of the comparisons are defined as follows:
</li>
<li>
- Array values are comparable if values of the array element type are comparable.
+ Array types are comparable if their array element types are comparable.
Two array values are equal if their corresponding element values are equal.
The elements are compared in ascending index order, and comparison stops
as soon as two element values differ (or all elements have been compared).
</li>
+
+ <li>
+ Type parameters are comparable if they are strictly comparable (see below).
+ </li>
</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
+causes a <a href="#Run_time_panics">run-time panic</a> if that type
+is 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.
+Slice, map, and function types 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>
@@ -5126,6 +5132,30 @@ var (
)
</pre>
+<p>
+A type is <i>strictly comparable</i> if it is comparable and not an interface
+type nor composed of interface types.
+Specifically:
+</p>
+
+<ul>
+ <li>
+ Boolean, numeric, string, pointer, and channel types are strictly comparable.
+ </li>
+
+ <li>
+ Struct types are strictly comparable if all their field types are strictly comparable.
+ </li>
+
+ <li>
+ Array types are strictly comparable if their array element types are strictly comparable.
+ </li>
+
+ <li>
+ Type parameters are strictly comparable if all types in their type set are strictly comparable.
+ </li>
+</ul>
+
<h3 id="Logical_operators">Logical operators</h3>
<p>