From 99b61be9f573ca46f4a4160e536abcb62180638a Mon Sep 17 00:00:00 2001
From: Robert Griesemer
-Each type T
has an underlying type: If T
-is one of the predeclared boolean, numeric, or string types, or a type literal,
-the corresponding underlying type is T
itself.
-Otherwise, T
's underlying type is the underlying type of the
-type to which T
refers in its type
-declaration. Accordingly, the underlying type of a type parameter is the
-underlying type of its type constraint, which
-is always an interface.
-
-type ( - A1 = string - A2 = A1 -) - -type ( - B1 string - B2 B1 - B3 []B1 - B4 B3 -) - -func f[P any](x P) { ⦠} -- -
-The underlying type of string
, A1
, A2
, B1
,
-and B2
is string
.
-The underlying type of []B1
, B3
, and B4
is []B1
.
-The underlying type of P
is interface{}
.
-
-The method set of a type determines the methods that can be -called on an operand of that type. -Every type has a (possibly empty) method set associated with it: -
- -T
consists of all
-methods declared with receiver type T
.
-T
-(where T
is neither a pointer nor an interface)
-is the set of all methods declared with receiver *T
or T
.
--Further rules apply to structs (and pointer to structs) containing embedded fields, -as described in the section on struct types. -Any other type has an empty method set. -
- --In a method set, each method must have a -unique -non-blank method name. -
-@@ -1748,6 +1675,171 @@ The properties of a type parameter are determined by its
+Each type T
has an underlying type: If T
+is one of the predeclared boolean, numeric, or string types, or a type literal,
+the corresponding underlying type is T
itself.
+Otherwise, T
's underlying type is the underlying type of the
+type to which T
refers in its type
+declaration. The underlying type of a type parameter is the
+underlying type of its type constraint, which
+is always an interface.
+
+type ( + A1 = string + A2 = A1 +) + +type ( + B1 string + B2 B1 + B3 []B1 + B4 B3 +) + +func f[P any](x P) { ⦠} ++ +
+The underlying type of string
, A1
, A2
, B1
,
+and B2
is string
.
+The underlying type of []B1
, B3
, and B4
is []B1
.
+The underlying type of P
is interface{}
.
+
+Each non-interface type T
has a core type, which is the
+underlying type of T
.
+
+An interface T
has a core type if one of the following
+conditions is satisfied:
+
U
which is the underlying type
+of all types in the type set of T
; or
+T
contains only channel types
+with identical element type E
, and all directional channels have the same
+direction.
++All other interfaces don't have a core type. +
+ ++The core type of an interface is, depending on the condition that is satisfied, either: +
+ +U
; or
+chan E
if T
contains only bidirectional
+channels, or the type chan<- E
or <-chan E
+depending on the direction of the directional channels present.
++Examples of interfaces with core types: +
+ ++type Celsius float32 +type Kelvin float32 + +interface{ int } // int +interface{ Celsius|Kelvin } // float32 +interface{ ~chan int } // chan int +interface{ ~chan int|~chan<- int } // chan<- int +interface{ ~[]*data; String() string } // []*data ++ +
+Examples of interfaces whithout core types: +
+ ++interface{} // no single underlying type +interface{ Celsius|float64 } // no single underlying type +interface{ chan int | chan<- string } // channels have different element types +interface{ <-chan int | chan<- int } // directional channels have different directions ++ +
+An interface specification that contains type elements
+defines a (possibly empty) set of specific types.
+Loosely speaking, these are the types T
that appear in the
+interface definition in terms of the form T
, ~T
,
+or in unions of such terms.
+
+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: +
+ +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.
+ +An interface may have specific types even if its type set +is empty. +
+ ++Examples of interfaces with their specific types: +
+ ++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) ++
@@ -1888,7 +1980,7 @@ by a value of type T
.
Additionally, if x's
type V
or T
are type parameters
-with specific types, x
+with specific types, x
is assignable to a variable of type T
if one of the following conditions applies:
T
's component type (float32
-If T
is a type parameter with specific types,
+If T
is a type parameter with specific types,
x
is representable by a value of type T
if x
is representable
by a value of each specific type of T
.
@@ -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
-Structure of interfaces
-
-
-An interface specification which contains type elements
-defines a (possibly empty) set of specific types.
-Loosely speaking, these are the types T
that appear in the
-interface definition in terms of the form T
, ~T
,
-or in unions of such terms.
-
-
-
-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.
-
+Method sets
-For a given interface, type element or type term, the set ð
of representative types is defined as follows:
+The method set of a type determines the methods that can be
+called on an operand of that type.
+Every type has a (possibly empty) method set associated with it:
- - For an interface with no type elements, ð
is the (infinite) set of all types.
-
-
- - For an interface with type elements,
- ð
is the intersection of the representative types of its type elements.
-
-
- - For a non-interface type term
T
or a term of the form ~T
,
- ð
is the set consisting of the type T
.
-
-
- - For a union of terms
-
t1|t2|â¦|tn
,
- ð
is the union of the representative types of the terms.
-
-
-
-
-An interface may have specific types even if its type set
-is empty.
-
-
-
-Examples of interfaces with their specific types:
-
-
-
-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)
-
-
-
-An interface T
has a core type if one of the following
-conditions is satisfied:
-
-
-
--
-There is a single type
U
which is the underlying type
-of all types in the type set of T
; or
-
--
-the type set of
T
contains only channel types
-with identical element type E
, and all directional channels have the same
-direction.
+ - The method set of a defined type
T
consists of all
+methods declared with receiver type T
.
-
-
-All other interfaces don't have a core type.
-
-
-
-The core type is, depending on the condition that is satisfied, either:
-
-
-
-
-the type
U
; or
+The method set of a pointer to a defined type T
+(where T
is neither a pointer nor an interface)
+is the set of all methods declared with receiver *T
or T
.
--
-the type
chan E
if T
contains only bidirectional
-channels, or the type chan<- E
or <-chan E
-depending on the direction of the directional channels present.
+
+ - The method set of an interface type is the intersection
+of the method sets of each type in the interface's type set
+(the resulting method set is usually just the set of declared methods in the interface).
-
+
-Examples of interfaces with core types:
+Further rules apply to structs (and pointer to structs) containing embedded fields,
+as described in the section on struct types.
+Any other type has an empty method set.
-
-interface{ int } // int
-interface{ Celsius|Kelvin } // float32
-interface{ ~chan int } // chan int
-interface{ ~chan int|~chan<- int } // chan<- int
-interface{ ~[]*data; String() string } // []*data
-
-
-Examples of interfaces whithout core types:
+In a method set, each method must have a
+unique
+non-blank method name.
-
-interface{} // no single underlying type
-interface{ Celsius|float64 } // no single underlying type
-interface{ chan int | chan<- string } // channels have different element types
-interface{ <-chan int | chan<- int } // directional channels have different directions
-
-
Blocks
@@ -3783,7 +3790,7 @@ For a
of map type M
:
For a
of type parameter type P
:
- P
must have specific types.
+ P
must have specific types.
- The index expression
a[x]
must be valid for values
of all specific types of P
.
- The element types of all specific types of
P
must be identical.
@@ -4513,7 +4520,7 @@ min(1.0, 2) // illegal: default type float64 (for 1.0) doesn't match default
Constraint type inference infers type arguments by considering type constraints.
If a type parameter P
has a constraint with a
-core type C
,
+core type C
,
unifying P
with C
may infer additional type arguments, either the type argument for P
,
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.
Excluding shifts, if the operand type is a type parameter,
-it must have specific types, and the operator must
+it must have specific types, and the operator must
apply to each specific type.
The operands are represented as values of the type argument that the type parameter
is instantiated with, and the operation is computed
@@ -5314,7 +5321,7 @@ in any of these cases:
Additionally, if T
or
x's
type V
are type
-parameters with specific types, x
+parameters with specific types, x
can also be converted to type T
if one of the following conditions applies:
@@ -7023,7 +7030,7 @@ cap(s) [n]T, *[n]T array length (== n)
If the argument type is a type parameter P
,
-P
must have specific types, and
+P
must have specific types, and
the call len(e)
(or cap(e)
respectively) must be valid for
each specific type of P
.
The result is the length (or capacity, respectively) of the argument whose type
--
2.48.1