]> Cypherpunks repositories - gostls13.git/commitdiff
spec: move all sections describing type properties into one place
authorRobert Griesemer <gri@golang.org>
Thu, 10 Feb 2022 01:36:51 +0000 (17:36 -0800)
committerRobert Griesemer <gri@golang.org>
Thu, 10 Feb 2022 21:40:49 +0000 (21:40 +0000)
This change only shuffles sections for better organization; there
are no other changes except title and link adjustments.

Until now, the sections on underlying types and method sets were
immediately following the introduction of types. As it becomes
necessary to introduce the notion of a core type more centrally,
the natural place is immediately following the section on underlying
types. All together, these sections, immediately after the introduction
of types, would distract from purpose of the section on types, which
is to introduce the various types that Go offers.

The more natural place for the definition of underlying, core, and
specific types is the section on properties of types and values.

To accomplish this, the section on the structure of interfaces is
split into a section on core types and one on specific types, and
the various sections are reorganized appropriately.

The new organization of the section on types now simply introduces
all Go types as follows:

- boolean types
- numeric types
- string types
- array types
- slice types
- struct types
- pointer types
- function types
- interface types
- map types
- channel types
- type parameters

The new organization of the section on properties of types and values
is as follows:

- underlying types
- core types
- specific types
- type identity
- assignability
- representability
- method sets

Change-Id: I59e4d47571da9d4c89d47d777f5353fb1c5843e6
Reviewed-on: https://go-review.googlesource.com/c/go/+/384623
Trust: Robert Griesemer <gri@golang.org>
Run-TryBot: Robert Griesemer <gri@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>

doc/go_spec.html

index 751d7fea01931e800afd9063cd3d8f48d5c9b867..99bedf2671701ffe4500e38432bc78460d670f6c 100644 (file)
@@ -818,79 +818,6 @@ Predeclared types, defined types, and type parameters are called <i>named types<
 An alias denotes a named type if the type given in the alias declaration is a named type.
 </p>
 
-<h3 id="Underlying_types">Underlying types</h3>
-
-<p>
-Each type <code>T</code> has an <i>underlying type</i>: If <code>T</code>
-is one of the predeclared boolean, numeric, or string types, or a type literal,
-the corresponding underlying type is <code>T</code> itself.
-Otherwise, <code>T</code>'s underlying type is the underlying type of the
-type to which <code>T</code> refers in its <a href="#Type_declarations">type
-declaration</a>. Accordingly, the underlying type of a type parameter is the
-underlying type of its <a href="#Type_constraints">type constraint</a>, which
-is always an interface.
-</p>
-
-<pre>
-type (
-       A1 = string
-       A2 = A1
-)
-
-type (
-       B1 string
-       B2 B1
-       B3 []B1
-       B4 B3
-)
-
-func f[P any](x P) { … }
-</pre>
-
-<p>
-The underlying type of <code>string</code>, <code>A1</code>, <code>A2</code>, <code>B1</code>,
-and <code>B2</code> is <code>string</code>.
-The underlying type of <code>[]B1</code>, <code>B3</code>, and <code>B4</code> is <code>[]B1</code>.
-The underlying type of <code>P</code> is <code>interface{}</code>.
-</p>
-
-<h3 id="Method_sets">Method sets</h3>
-
-<p>
-The <i>method set</i> of a type determines the methods that can be
-<a href="#Calls">called</a> on an <a href="#Operands">operand</a> of that type.
-Every type has a (possibly empty) method set associated with it:
-</p>
-
-<ul>
-<li>The method set of a <a href="#Type_definitions">defined type</a> <code>T</code> consists of all
-<a href="#Method_declarations">methods</a> declared with receiver type <code>T</code>.
-</li>
-
-<li>
-The method set of a pointer to a defined type <code>T</code>
-(where <code>T</code> is neither a pointer nor an interface)
-is the set of all methods declared with receiver <code>*T</code> or <code>T</code>.
-</li>
-
-<li>The method set of an <a href="#Interface_types">interface type</a> is the intersection
-of the method sets of each type in the interface's <a href="#Interface_types">type set</a>
-(the resulting method set is usually just the set of declared methods in the interface).
-</li>
-</ul>
-
-<p>
-Further rules apply to structs (and pointer to structs) containing embedded fields,
-as described in the section on <a href="#Struct_types">struct types</a>.
-Any other type has an empty method set.
-</p>
-
-<p>
-In a method set, each method must have a
-<a href="#Uniqueness_of_identifiers">unique</a>
-non-<a href="#Blank_identifier">blank</a> <a href="#MethodName">method name</a>.
-</p>
-
 <h3 id="Boolean_types">Boolean types</h3>
 
 <p>
@@ -1748,6 +1675,171 @@ The properties of a type parameter are determined by its
 
 <h2 id="Properties_of_types_and_values">Properties of types and values</h2>
 
+<h3 id="Underlying_types">Underlying types</h3>
+
+<p>
+Each type <code>T</code> has an <i>underlying type</i>: If <code>T</code>
+is one of the predeclared boolean, numeric, or string types, or a type literal,
+the corresponding underlying type is <code>T</code> itself.
+Otherwise, <code>T</code>'s underlying type is the underlying type of the
+type to which <code>T</code> refers in its <a href="#Type_declarations">type
+declaration</a>. The underlying type of a type parameter is the
+underlying type of its <a href="#Type_constraints">type constraint</a>, which
+is always an interface.
+</p>
+
+<pre>
+type (
+       A1 = string
+       A2 = A1
+)
+
+type (
+       B1 string
+       B2 B1
+       B3 []B1
+       B4 B3
+)
+
+func f[P any](x P) { … }
+</pre>
+
+<p>
+The underlying type of <code>string</code>, <code>A1</code>, <code>A2</code>, <code>B1</code>,
+and <code>B2</code> is <code>string</code>.
+The underlying type of <code>[]B1</code>, <code>B3</code>, and <code>B4</code> is <code>[]B1</code>.
+The underlying type of <code>P</code> is <code>interface{}</code>.
+</p>
+
+<h3 id="Core_types">Core types</h3>
+
+<p>
+Each non-interface type <code>T</code> has a <i>core</i> type, which is the
+<a href="#Underlying_types">underlying type</a> of <code>T</code>.
+</p>
+
+<p>
+An interface <code>T</code> has a core type if one of the following
+conditions is satisfied:
+</p>
+
+<ol>
+<li>
+There is a single type <code>U</code> which is the <a href="#Underlying_types">underlying type</a>
+of all types in the <a href="#Interface_types">type set</a> of <code>T</code>; or
+</li>
+<li>
+the type set of <code>T</code> contains only <a href="#Channel_types">channel types</a>
+with identical element type <code>E</code>, and all directional channels have the same
+direction.
+</li>
+</ol>
+
+<p>
+All other interfaces don't have a core type.
+</p>
+
+<p>
+The core type of an interface is, depending on the condition that is satisfied, either:
+</p>
+
+<ol>
+<li>
+the type <code>U</code>; or
+</li>
+<li>
+the type <code>chan E</code> if <code>T</code> contains only bidirectional
+channels, or the type <code>chan&lt;- E</code> or <code>&lt;-chan E</code>
+depending on the direction of the directional channels present.
+</li>
+</ol>
+
+<p>
+Examples of interfaces with core types:
+</p>
+
+<pre>
+type Celsius float32
+type Kelvin  float32
+
+interface{ int }                          // int
+interface{ Celsius|Kelvin }               // float32
+interface{ ~chan int }                    // chan int
+interface{ ~chan int|~chan&lt;- int }        // chan&lt;- int
+interface{ ~[]*data; String() string }    // []*data
+</pre>
+
+<p>
+Examples of interfaces whithout core types:
+</p>
+
+<pre>
+interface{}                               // no single underlying type
+interface{ Celsius|float64 }              // no single underlying type
+interface{ chan int | chan&lt;- string }     // channels have different element types
+interface{ &lt;-chan int | chan&lt;- int }      // directional channels have different directions
+</pre>
+
+<h3 id="Specific_types">Specific types</h3>
+
+<p>
+An interface specification that contains <a href="#Interface_types">type elements</a>
+defines a (possibly empty) set of <i>specific types</i>.
+Loosely speaking, these are the types <code>T</code> that appear in the
+interface definition in terms of the form <code>T</code>, <code>~T</code>,
+or in unions of such terms.
+</p>
+
+<p>
+More precisely, for a given interface, the set of specific types corresponds to
+the set 𝑅 of representative types of the interface, if 𝑅 is non-empty and finite.
+Otherwise, if 𝑅 is empty or infinite, the interface has <i>no specific types</i>.
+</p>
+
+<p>
+For a given interface, type element or type term, the set 𝑅 of representative types is defined as follows:
+</p>
+
+<ul>
+       <li>For an interface with no type elements, 𝑅 is the (infinite) set of all types.
+       </li>
+
+       <li>For an interface with type elements,
+               𝑅 is the intersection of the representative types of its type elements.
+       </li>
+
+       <li>For a non-interface type term <code>T</code> or a term of the form <code>~T</code>,
+               𝑅 is the set consisting of the type <code>T</code>.
+       </li>
+
+       <li>For a <i>union</i> of terms
+               <code>t<sub>1</sub>|t<sub>2</sub>|…|t<sub>n</sub></code>,
+               𝑅 is the union of the representative types of the terms.
+       </li>
+</ul>
+
+<p>
+An interface may have specific types even if its <a href="#Interface_types">type set</a>
+is empty.
+</p>
+
+<p>
+Examples of interfaces with their specific types:
+</p>
+
+<pre>
+interface{}                    // no specific types
+interface{ int }               // int
+interface{ ~string }           // string
+interface{ int|~string }       // int, string
+interface{ Celsius|Kelvin }    // Celsius, Kelvin
+interface{ float64|any }       // no specific types (union is all types)
+interface{ int; m() }          // int (but type set is empty because int has no method m)
+interface{ ~int; m() }         // int (but type set is infinite because many integer types have a method m)
+interface{ int; any }          // int
+interface{ int; string }       // no specific types (intersection is empty)
+</pre>
+
 <h3 id="Type_identity">Type identity</h3>
 
 <p>
@@ -1888,7 +1980,7 @@ by a value of type <code>T</code>.
 
 <p>
 Additionally, if <code>x's</code> type <code>V</code> or <code>T</code> are type parameters
-with <a href="#Structure_of_interfaces">specific types</a>, <code>x</code>
+with <a href="#Specific_types">specific types</a>, <code>x</code>
 is assignable to a variable of type <code>T</code> if one of the following conditions applies:
 </p>
 
@@ -1940,7 +2032,7 @@ are representable by values of <code>T</code>'s component type (<code>float32</c
 </ul>
 
 <p>
-If <code>T</code> is a type parameter with <a href="#Structure_of_interfaces">specific types</a>,
+If <code>T</code> is a type parameter with <a href="#Specific_types">specific types</a>,
 <code>x</code> is representable by a value of type <code>T</code> if <code>x</code> is representable
 by a value of each specific type of <code>T</code>.
 </p>
@@ -1972,128 +2064,43 @@ x                   T           x is not representable by a value of T because
 1e1000              float64     1e1000 overflows to IEEE +Inf after rounding
 </pre>
 
-<h3 id="Structure_of_interfaces">Structure of interfaces</h3>
-
-<p>
-An interface specification which contains <a href="#Interface_types">type elements</a>
-defines a (possibly empty) set of <i>specific types</i>.
-Loosely speaking, these are the types <code>T</code> that appear in the
-interface definition in terms of the form <code>T</code>, <code>~T</code>,
-or in unions of such terms.
-</p>
-
-<p>
-More precisely, for a given interface, the set of specific types corresponds to
-the set 𝑅 of representative types of the interface, if 𝑅 is non-empty and finite.
-Otherwise, if 𝑅 is empty or infinite, the interface has <i>no specific types</i>.
-</p>
+<h3 id="Method_sets">Method sets</h3>
 
 <p>
-For a given interface, type element or type term, the set 𝑅 of representative types is defined as follows:
+The <i>method set</i> of a type determines the methods that can be
+<a href="#Calls">called</a> on an <a href="#Operands">operand</a> of that type.
+Every type has a (possibly empty) method set associated with it:
 </p>
 
 <ul>
-       <li>For an interface with no type elements, 𝑅 is the (infinite) set of all types.
-       </li>
-
-       <li>For an interface with type elements,
-               𝑅 is the intersection of the representative types of its type elements.
-       </li>
-
-       <li>For a non-interface type term <code>T</code> or a term of the form <code>~T</code>,
-               𝑅 is the set consisting of the type <code>T</code>.
-       </li>
-
-       <li>For a <i>union</i> of terms
-               <code>t<sub>1</sub>|t<sub>2</sub>|…|t<sub>n</sub></code>,
-               𝑅 is the union of the representative types of the terms.
-       </li>
-</ul>
-
-<p>
-An interface may have specific types even if its <a href="#Interface_types">type set</a>
-is empty.
-</p>
-
-<p>
-Examples of interfaces with their specific types:
-</p>
-
-<pre>
-type Celsius float32
-type Kelvin  float32
-
-interface{}                    // no specific types
-interface{ int }               // int
-interface{ ~string }           // string
-interface{ int|~string }       // int, string
-interface{ Celsius|Kelvin }    // Celsius, Kelvin
-interface{ float64|any }       // no specific types (union is all types)
-interface{ int; m() }          // int (but type set is empty because int has no method m)
-interface{ ~int; m() }         // int (but type set is infinite because many integer types have a method m)
-interface{ int; any }          // int
-interface{ int; string }       // no specific types (intersection is empty)
-</pre>
-
-<p>
-An interface <code>T</code> has a <i>core type</i> if one of the following
-conditions is satisfied:
-</p>
-
-<ol>
-<li>
-There is a single type <code>U</code> which is the <a href="#Underlying_types">underlying type</a>
-of all types in the <a href="#Interface_types">type set</a> of <code>T</code>; or
-</li>
-<li>
-the type set of <code>T</code> contains only <a href="#Channel_types">channel types</a>
-with identical element type <code>E</code>, and all directional channels have the same
-direction.
+<li>The method set of a <a href="#Type_definitions">defined type</a> <code>T</code> consists of all
+<a href="#Method_declarations">methods</a> declared with receiver type <code>T</code>.
 </li>
-</ol>
 
-<p>
-All other interfaces don't have a core type.
-</p>
-
-<p>
-The core type is, depending on the condition that is satisfied, either:
-</p>
-
-<ol>
 <li>
-the type <code>U</code>; or
+The method set of a pointer to a defined type <code>T</code>
+(where <code>T</code> is neither a pointer nor an interface)
+is the set of all methods declared with receiver <code>*T</code> or <code>T</code>.
 </li>
-<li>
-the type <code>chan E</code> if <code>T</code> contains only bidirectional
-channels, or the type <code>chan&lt;- E</code> or <code>&lt;-chan E</code>
-depending on the direction of the directional channels present.
+
+<li>The method set of an <a href="#Interface_types">interface type</a> is the intersection
+of the method sets of each type in the interface's <a href="#Interface_types">type set</a>
+(the resulting method set is usually just the set of declared methods in the interface).
 </li>
-</ol>
+</ul>
 
 <p>
-Examples of interfaces with core types:
+Further rules apply to structs (and pointer to structs) containing embedded fields,
+as described in the section on <a href="#Struct_types">struct types</a>.
+Any other type has an empty method set.
 </p>
 
-<pre>
-interface{ int }                          // int
-interface{ Celsius|Kelvin }               // float32
-interface{ ~chan int }                    // chan int
-interface{ ~chan int|~chan&lt;- int }        // chan&lt;- int
-interface{ ~[]*data; String() string }    // []*data
-</pre>
-
 <p>
-Examples of interfaces whithout core types:
+In a method set, each method must have a
+<a href="#Uniqueness_of_identifiers">unique</a>
+non-<a href="#Blank_identifier">blank</a> <a href="#MethodName">method name</a>.
 </p>
 
-<pre>
-interface{}                               // no single underlying type
-interface{ Celsius|float64 }              // no single underlying type
-interface{ chan int | chan&lt;- string }     // channels have different element types
-interface{ &lt;-chan int | chan&lt;- int }      // directional channels have different directions
-</pre>
-
 <h2 id="Blocks">Blocks</h2>
 
 <p>
@@ -3783,7 +3790,7 @@ For <code>a</code> of <a href="#Map_types">map type</a> <code>M</code>:
 For <code>a</code> of <a href="#Type_parameters">type parameter type</a> <code>P</code>:
 </p>
 <ul>
-       <li><code>P</code> must have <a href="#Structure_of_interfaces">specific types</a>.</li>
+       <li><code>P</code> must have <a href="#Specific_types">specific types</a>.</li>
        <li>The index expression <code>a[x]</code> must be valid for values
            of all specific types of <code>P</code>.</li>
        <li>The element types of all specific types of <code>P</code> must be identical.
@@ -4513,7 +4520,7 @@ min(1.0, 2)    // illegal: default type float64 (for 1.0) doesn't match default
 <p>
 Constraint type inference infers type arguments by considering type constraints.
 If a type parameter <code>P</code> has a constraint with a
-<a href="#Structure_of_interfaces">core type</a> <code>C</code>,
+<a href="#Core_types">core type</a> <code>C</code>,
 <a href="#Type_unification">unifying</a> <code>P</code> with <code>C</code>
 may infer additional type arguments, either the type argument for <code>P</code>,
 or if that is already known, possibly the type arguments for type parameters
@@ -4774,7 +4781,7 @@ The bitwise logical and shift operators apply to integers only.
 
 <p>
 Excluding shifts, if the operand type is a <a href="#Type_parameters">type parameter</a>,
-it must have <a href="#Structure_of_interfaces">specific types</a>, and the operator must
+it must have <a href="#Specific_types">specific types</a>, and the operator must
 apply to each specific type.
 The operands are represented as values of the type argument that the type parameter
 is <a href="#Instantiations">instantiated</a> with, and the operation is computed
@@ -5314,7 +5321,7 @@ in any of these cases:
 
 <p>
 Additionally, if <code>T</code> or </code><code>x's</code> type <code>V</code> are type
-parameters with <a href="#Structure_of_interfaces">specific types</a>, <code>x</code>
+parameters with <a href="#Specific_types">specific types</a>, <code>x</code>
 can also be converted to type <code>T</code> if one of the following conditions applies:
 </p>
 
@@ -7023,7 +7030,7 @@ cap(s)    [n]T, *[n]T      array length (== n)
 
 <p>
 If the argument type is a <a href="#Type_parameters">type parameter</a> <code>P</code>,
-<code>P</code> must have <a href="#Structure of interfaces">specific types</a>, and
+<code>P</code> must have <a href="#Specific_types">specific types</a>, and
 the call <code>len(e)</code> (or <code>cap(e)</code> respectively) must be valid for
 each specific type of <code>P</code>.
 The result is the length (or capacity, respectively) of the argument whose type