From: Robert Griesemer
-[The definition of specific types is not quite correct yet.]
-
-An interface specification that contains type elements
-defines a (possibly empty) set of specific types.
-Loosely speaking, these are the types
-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 no specific types.
-
-For a given interface, type element or type term, the set ð
of representative types is defined as follows:
-
-An interface may have specific types even if its type set
-is empty.
-
-Examples of interfaces with their specific types:
-
@@ -2002,25 +1938,24 @@ by a value of type
-Additionally, if
-If
The predeclared
interface type new
call or composite literal, or the type of
an element of a structured variable.
Variables of interface type also have a distinct dynamic type,
-which is the concrete type of the value assigned to the variable at run time
+which is the (non-interface) type of the value assigned to the variable at run time
(unless the value is the predeclared identifier nil
,
which has no type).
The dynamic type may vary during execution but values stored in interface
@@ -1799,70 +1799,6 @@ interface{ chan int | chan<- string } // channels have different element
interface{ <-chan int | chan<- int } // directional channels have different directions
-Specific types
-
-T
that appear in the
-interface definition in terms of the form T
, ~T
,
-or in unions of such terms.
-
-
-
-T
or a term of the form ~T
,
- ð
is the set consisting of the type T
.
- t1|t2|â¦|tn
,
- ð
is the union of the representative types of the terms.
-
-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)
-
-
Type identity
T
.
x
's type V
or T
are type parameters
-with specific types, x
+Additionally, if x
's type V
or T
are type parameters, x
is assignable to a variable of type T
if one of the following conditions applies:
@@ -2055,9 +1990,9 @@ are representable by values of x
is the predeclared identifier nil
, T
is
-a type parameter, and x
is assignable to each specific type of
-T
.
+a type parameter, and x
is assignable to each type in
+T
's type set.
V
is not a named type, T
is
-a type parameter, and x
is assignable to each specific type of
-T
.
+a type parameter, and x
is assignable to each type in
+T
's type set.
V
is a type parameter and T
is not a named type,
-and values of each specific type of V
are assignable
+and values of each type in V
's type set are assignable
to T
.
T
's component type (float32
T
is a type parameter with specific types,
+If T
is a type parameter,
x
is representable by a value of type T
if x
is representable
-by a value of each specific type of T
.
+by a value of each type in T
's type set.
@@ -2705,7 +2640,7 @@ other interfaces based on their type sets. But this should get us going for now.
comparable
-denotes the set of all concrete (non-interface) types that are
+denotes the set of all non-interface types that are
comparable. Specifically,
a type T
implements comparable
if:
+Implementation restriction: A compiler need not report an error if an operand's +type is a type parameter with an empty +type set. Functions with such type parameters +cannot be instantiated; any attempt will lead +to an error at the instantiation site. +
+
@@ -3819,20 +3762,19 @@ For a
of map type M
:
For a
of type parameter type P
:
P
must have specific types.a[x]
must be valid for values
- of all specific types of P
.P
must be identical.
+ of all types in P
's type set.P
's type set must be identical.
In this context, the element type of a string type is byte
.P
,
- all specific types must be map types, and the respective key types
+ P
,
+ all types in that type set must be map types, and the respective key types
must be all identical.a[x]
is the array, slice, or string element at index x
,
or the map element with key x
of the type argument
that P
is instantiated with, and the type of a[x]
is
the type of the (identical) element types.a[x]
may not be assigned to if the specific types of P
- include string types.
+ a[x]
may not be assigned to if P
's type set
+ includes string types.
@@ -4728,6 +4670,10 @@ and the other operand is not, the constant is implicitly to the type of the other operand.
++[The rules for shifts need adjustments for type parameters. Issue #51182.] +
+The right operand in a shift expression must have integer type or be an untyped constant representable by a @@ -4832,9 +4778,8 @@ The bitwise logical and shift operators apply to integers only.
-Excluding shifts, if the operand type is a type parameter,
-it must have specific types, and the operator must
-apply to each specific type.
+If the operand type is a type parameter,
+the operator must apply to each type in that type set.
The operands are represented as values of the type argument that the type parameter
is instantiated with, and the operation is computed
with the precision of that type argument. For example, given the function:
@@ -4857,11 +4802,6 @@ are computed with float32
or float64
precision,
respectively, depending on the type argument for F
.
-For shifts, the core type of both operands must be -an integer. -
-@@ -5374,23 +5314,23 @@ in any of these cases:
Additionally, if T
or x
's type V
are type
-parameters with specific types, x
+parameters, x
can also be converted to type T
if one of the following conditions applies:
V
and T
are type parameters and a value of each
-specific type of V
can be converted to each specific type
-of T
.
+type in V
's type set can be converted to each type in T
's
+type set.
V
is a type parameter and a value of each
-specific type of V
can be converted to T
.
+type in V
's type set can be converted to T
.
T
is a type parameter and x
can be converted to each
-specific type of T
.
+type in T
's type set.
If the argument type is a type parameter P
,
-P
must have specific types, and
the call len(e)
(or cap(e)
respectively) must be valid for
-each specific type of P
.
+each type in P
's type set.
The result is the length (or capacity, respectively) of the argument whose type
corresponds to the type argument with which P
was
instantiated.
@@ -7309,8 +7248,7 @@ delete(m, k) // remove element m[k] from map m
If the type of m
is a type parameter,
-it must have specific types, all specific types
-must be maps, and they must all have identical key types.
+all types in that type set must be maps, and they must all have identical key types.