mirror of
https://github.com/golang/go
synced 2024-11-02 13:42:29 +00:00
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:
parent
f2ec001845
commit
ea9b1f1573
1 changed files with 40 additions and 14 deletions
|
@ -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>
|
||||||
|
|
Loading…
Reference in a new issue