spec: add a section on implementing an interface

Also, fixed several closing header tags and removed a duplicate "the".
(Thanks to @hopehook and Hossein Zolfi for pointing these out.)

Change-Id: I85a40ba44b8570a578bce8d211dcc5ea3901fb1e
Reviewed-on: https://go-review.googlesource.com/c/go/+/385036
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
Robert Griesemer 2022-02-10 21:10:34 -08:00
parent f2ec001845
commit ea9b1f1573

View file

@ -1,6 +1,6 @@
<!--{ <!--{
"Title": "The Go Programming Language Specification - Go 1.18 Draft (incomplete)", "Title": "The Go Programming Language Specification - Go 1.18 Draft (incomplete)",
"Subtitle": "Version of Feb 10, 2022", "Subtitle": "Version of Feb 11, 2022",
"Path": "/ref/spec" "Path": "/ref/spec"
}--> }-->
@ -1205,7 +1205,8 @@ func(n int) func(p *T)
<p> <p>
An interface type defines a <i>type set</i>. An interface type defines a <i>type set</i>.
A variable of interface type can store a value of any type that is in the type A variable of interface type can store a value of any type that is in the type
set of the interface. Such a type is said to <i>implement the interface</i>. set of the interface. Such a type is said to
<a href="#Implementing_an_interface">implement the interface</a>.
The value of an uninitialized variable of interface type is <code>nil</code>. The value of an uninitialized variable of interface type is <code>nil</code>.
</p> </p>
@ -1376,7 +1377,7 @@ definition of an interface's type set as follows:
</p> </p>
<ul> <ul>
<li>The type set of the empty interface is the set of all types. <li>The type set of the empty interface is the set of all non-interface types.
</li> </li>
<li>The type set of a non-empty interface is the intersection of the type sets <li>The type set of a non-empty interface is the intersection of the type sets
@ -1401,6 +1402,10 @@ definition of an interface's type set as follows:
</li> </li>
</ul> </ul>
<p>
By construction, an interface's type set never contains an interface type.
</p>
<pre> <pre>
// An interface representing only the type int. // An interface representing only the type int.
interface { interface {
@ -1519,6 +1524,27 @@ type Bad2 interface {
} }
</pre> </pre>
<h4 id="Implementing_an_interface">Implementing an interface</h4>
<p>
A type <code>T</code> implements an interface <code>I</code> if
</p>
<ul>
<li>
<code>T</code> is not an interface and is an element of the type set of <code>I</code>; or
</li>
<li>
<code>T</code> is an interface and the type set of <code>T</code> is a subset of the
type set of <code>I</code>.
</li>
</ul>
<p>
A value <code>x</code> of type <code>T</code> implements an interface if <code>T</code>
implements the interface.
</p>
<h3 id="Map_types">Map types</h3> <h3 id="Map_types">Map types</h3>
<p> <p>
@ -1978,7 +2004,7 @@ and at least one of <code>V</code> or <code>T</code> is not a <a href="#Types">n
</li> </li>
<li> <li>
<code>T</code> is an interface type, but not a type parameter, and <code>T</code> is an interface type, but not a type parameter, and
<code>x</code> <a href="#Interface_types">implements</a> <code>T</code>. <code>x</code> <a href="#Implementing_an_interface">implements</a> <code>T</code>.
</li> </li>
<li> <li>
<code>x</code> is the predeclared identifier <code>nil</code> and <code>T</code> <code>x</code> is the predeclared identifier <code>nil</code> and <code>T</code>
@ -2687,7 +2713,7 @@ type Constraint ~int // illegal: ~int is not inside a type paramet
<!-- <!--
We should be able to simplify the rules for comparable or delegate some of them We should be able to simplify the rules for comparable or delegate some of them
elsewhere once we have a section that clearly defines how interfaces implement elsewhere since we have a section that clearly defines how interfaces implement
other interfaces based on their type sets. But this should get us going for now. other interfaces based on their type sets. But this should get us going for now.
--> -->
@ -4018,7 +4044,7 @@ In this case, <code>T</code> must <a href="#Method_sets">implement</a> the (inte
otherwise the type assertion is invalid since it is not possible for <code>x</code> otherwise the type assertion is invalid since it is not possible for <code>x</code>
to store a value of type <code>T</code>. to store a value of type <code>T</code>.
If <code>T</code> is an interface type, <code>x.(T)</code> asserts that the dynamic type If <code>T</code> is an interface type, <code>x.(T)</code> asserts that the dynamic type
of <code>x</code> implements the interface <code>T</code>. of <code>x</code> <a href="#Implementing_an_interface">implements</a> the interface <code>T</code>.
</p> </p>
<p> <p>
If the type assertion holds, the value of the expression is the value If the type assertion holds, the value of the expression is the value
@ -4290,7 +4316,8 @@ Missing type arguments may be <i>inferred</i> by a series of steps, described be
Each step attempts to use known information to infer additional type arguments. Each step attempts to use known information to infer additional type arguments.
Type inference stops as soon as all type arguments are known. Type inference stops as soon as all type arguments are known.
After type inference is complete, it is still necessary to substitute all type arguments After type inference is complete, it is still necessary to substitute all type arguments
for type parameters and verify that each type argument implements the relevant constraint; for type parameters and verify that each type argument
<a href="#Implementing_an_interface">implements</a> the relevant constraint;
it is possible for an inferred type argument to fail to implement a constraint, in which it is possible for an inferred type argument to fail to implement a constraint, in which
case instantiation fails. case instantiation fails.
</p> </p>
@ -4344,7 +4371,7 @@ The process stops as soon as <i>M</i> has a type argument for each type paramete
If an inference step fails, or if <i>M</i> is still missing type arguments after the last step, type inference fails. If an inference step fails, or if <i>M</i> is still missing type arguments after the last step, type inference fails.
</p> </p>
<h4 id="Type_unification">Type unification</h3> <h4 id="Type_unification">Type unification</h4>
<p> <p>
Type inference is based on <i>type unification</i>. A single unification step Type inference is based on <i>type unification</i>. A single unification step
@ -4421,7 +4448,7 @@ and the type literal <code>[]E</code>, unification compares <code>[]float64</cod
the substitution map. the substitution map.
</p> </p>
<h4 id="Function_argument_type_inference">Function argument type inference</h3> <h4 id="Function_argument_type_inference">Function argument type inference</h4>
<!-- In this section and the section on constraint type inference we start with examples <!-- In this section and the section on constraint type inference we start with examples
rather than have the examples follow the rules as is customary elsewhere in spec. rather than have the examples follow the rules as is customary elsewhere in spec.
@ -4540,7 +4567,7 @@ processing continues until all untyped arguments are considered, an error is rep
ensures that type inference does not depend on the order of the untyped arguments. ensures that type inference does not depend on the order of the untyped arguments.
</p> </p>
<h4 id="Constraint_type_inference">Constraint type inference</h3> <h4 id="Constraint_type_inference">Constraint type inference</h4>
<!-- <!--
The next paragraph needs to be updated for the new definition of core type: The next paragraph needs to be updated for the new definition of core type:
@ -4833,7 +4860,7 @@ func dotProduct[F ~float32|~float64](v1, v2 []F) F {
</pre> </pre>
<p> <p>
the the product <code>x * y</code> and the addition <code>s += x * y</code> the product <code>x * y</code> and the addition <code>s += x * y</code>
are computed with <code>float32</code> or <code>float64</code> precision, are computed with <code>float32</code> or <code>float64</code> precision,
respectively, depending on the type argument for <code>F</code>. respectively, depending on the type argument for <code>F</code>.
</p> </p>
@ -5079,7 +5106,7 @@ These terms and the result of the comparisons are defined as follows:
A value <code>x</code> of non-interface type <code>X</code> and 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 a value <code>t</code> of interface type <code>T</code> are comparable when values
of type <code>X</code> are comparable and of type <code>X</code> are comparable and
<code>X</code> implements <code>T</code>. <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> 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>. and <code>t</code>'s dynamic value is equal to <code>x</code>.
</li> </li>
@ -5412,8 +5439,7 @@ of <code>x</code>.
<p> <p>
There is no linguistic mechanism to convert between pointers and integers. There is no linguistic mechanism to convert between pointers and integers.
The package <a href="#Package_unsafe"><code>unsafe</code></a> The package <a href="#Package_unsafe"><code>unsafe</code></a>
implements this functionality under implements this functionality under restricted circumstances.
restricted circumstances.
</p> </p>
<h4>Conversions between numeric types</h4> <h4>Conversions between numeric types</h4>