From 428533fab48d71a38efd9a7c53e49365f094561c Mon Sep 17 00:00:00 2001
From: Dmitri Shuralyov
-For the pre-Go1.18 specification without generics support see
-The Go Programming Language Specification.
-
-[For reviewers: Sections where we know of missing prose are marked like this. The markers will be removed before the release.]
-
-This is a reference manual for the Go programming language. For
-more information and other documents, see golang.org.
+This is the reference manual for the Go programming language.
+The pre-Go1.18 version, without generics, can be found
+here.
+For more information and other documents, see golang.org.
@@ -766,7 +756,7 @@ type given in its declaration, the type provided in the
The language predeclares certain type names.
Others are introduced with type declarations
-or type parameter lists.
+or type parameter lists.
Composite types—array, struct, pointer, function,
interface, slice, map, and channel types—may be constructed using
type literals.
@@ -987,7 +977,7 @@ built-in function
-A new, initialized slice value for a given element type
-In a union, a term cannot be a type parameter, and the type sets of all
+In a union, a term cannot be a type parameter, and the type sets of all
non-interface terms must be pairwise disjoint (the pairwise intersection of the type sets must be empty).
Given a type parameter
Implementation restriction:
-A union with more than one term cannot contain the
+A union (with more than one term) cannot contain the
predeclared identifier
-A value Earlier version
-
-Introduction
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
@@ -812,7 +802,7 @@ TypeLit = ArrayType | StructType | PointerType | FunctionType | InterfaceType
cap(a)
.
T
is
+A new, initialized slice value for a given element type T
may be
made using the built-in function
make
,
which takes a slice type
@@ -1422,7 +1412,7 @@ interface {
~int
}
-// An interface representing all types with underlying type int which implement the String method.
+// An interface representing all types with underlying type int that implement the String method.
interface {
~int
String() string
@@ -1455,32 +1445,32 @@ Union elements denote unions of type sets:
-// The Floats interface represents all floating-point types
+// The Float interface represents all floating-point types
// (including any named types whose underlying types are
// either float32 or float64).
-type Floats interface {
+type Float interface {
~float32 | ~float64
}
P
:
interface {
- P // illegal: the term P is a type parameter
- int | P // illegal: the term P is a type parameter
- ~int | MyInt // illegal: the type sets for ~int and MyInt are not disjoint (~int includes MyInt)
- float32 | Floats // overlapping type sets but Floats is an interface
+ P // illegal: P is a type parameter
+ int | P // illegal: P is a type parameter
+ ~int | MyInt // illegal: the type sets for ~int and MyInt are not disjoint (~int includes MyInt)
+ float32 | Float // overlapping type sets but Float is an interface
}
comparable
or interfaces that specify methods, or embed comparable
or interfaces
that specify methods.
@@ -1494,12 +1484,12 @@ non-interface types.
-var x Floats // illegal: Floats is not a basic interface
+var x Float // illegal: Float is not a basic interface
-var x interface{} = Floats(nil) // illegal
+var x interface{} = Float(nil) // illegal
type Floatish struct {
- f Floats // illegal
+ f Float // illegal
}
@@ -1545,7 +1535,7 @@ A type T
implements an interface I
if
x
of type T
implements an interface if T
+A value of type T
implements an interface if T
implements the interface.
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 to which T
refers in its declaration.
+For a type parameter that is the underlying type of its
+type constraint, which is always an interface.
@@ -1755,7 +1744,7 @@ direction.-All other interfaces don't have a core type. +No other interfaces have a core type.
@@ -1775,7 +1764,7 @@ depending on the direction of the directional channels present.
By definition, a core type is never a defined type, -type parameter, or +type parameter, or interface type.
@@ -1795,7 +1784,7 @@ interface{ ~[]*data; String() string } // []*data
-Examples of interfaces whithout core types: +Examples of interfaces without core types:
@@ -1805,70 +1794,6 @@ interface{ chan int | chan<- string } // channels have different element interface{ <-chan int | chan<- int } // directional channels have different directions-
-[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 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) --
@@ -1973,21 +1898,21 @@ defined type while the latter is a type literal
-A value x
is assignable to a variable of type T
+A value x
of type V
is assignable to a variable of type T
("x
is assignable to T
") if one of the following conditions applies:
x
's type is identical to T
.
+V
and T
are identical.
x
's type V
and T
have identical
+V
and T
have identical
underlying types and at least one of V
or T
is not a named type.
x
's type V
and T
are channel types with
+V
and T
are channel types with
identical element types, V
is a bidirectional channel,
and at least one of V
or T
is not a named type.
T
.
-Additionally, if 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:
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
.
A constant x
is representable
by a value of type T
,
-where T
is not a type parameter,
+where T
is not a type parameter,
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,
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.
@@ -2176,6 +2100,7 @@ Blocks nest and influence scoping.
A declaration binds a non-blank identifier to a
constant,
type,
+type parameter,
variable,
function,
label, or
@@ -2220,13 +2145,13 @@ Go is lexically scoped using blocks:
The scope of an identifier denoting a method receiver, function parameter,
or result variable is the function body.
- The scope of an identifier denoting a type parameter of a generic function
+ The scope of an identifier denoting a type parameter of a function
or declared by a method receiver is the function body and all parameter lists of the
function.
- The scope of an identifier denoting a type parameter of a generic type
- begins after the name of the generic type and ends at the end
+ The scope of an identifier denoting a type parameter of a type
+ begins after the name of the type and ends at the end
of the TypeSpec.
The scope of a constant or variable identifier declared
@@ -2512,7 +2437,7 @@ type (
type TreeNode struct {
left, right *TreeNode
- value *Comparable
+ value any
}
type Block interface {
@@ -2573,7 +2498,7 @@ func (tz TimeZone) String() string {
-If the type definition specifies type parameters,
+If the type definition specifies type parameters,
the type name denotes a generic type.
Generic types must be instantiated when they
are used.
@@ -2584,15 +2509,10 @@ type List[T any] struct {
next *List[T]
value T
}
-
-type Tree[T constraints.Ordered] struct {
- left, right *Tree[T]
- value T
-}
-The given type cannot be a type parameter in a type definition.
+In a type definition the given type cannot be a type parameter.
@@ -2604,8 +2524,8 @@ func f[T any]() {
-A generic type may also have methods associated with it. In this case,
-the method receivers must declare the same number of type parameters as
+A generic type may also have methods associated with it.
+In this case, the method receivers must declare the same number of type parameters as
present in the generic type definition.
@@ -2614,7 +2534,7 @@ present in the generic type definition.
func (l *List[T]) Len() int { … }
-Type parameter lists
+Type parameter declarations
A type parameter list declares the type parameters of a generic function or type declaration.
@@ -2653,22 +2573,22 @@ has a corresponding (meta-)type which is called its
A parsing ambiguity arises when the type parameter list for a generic type
-declares a single type parameter with a type constraint of the form *C
-or (C)
where C
is not a (possibly parenthesized)
-type literal:
+declares a single type parameter P
with a constraint C
+such that the text P C
forms a valid expression:
type T[P *C] …
type T[P (C)] …
+type T[P *C|Q] …
+…
-In these rare cases, the type parameter declaration is indistinguishable from
-the expressions P*C
or P(C)
and the type declaration
-is parsed as an array type declaration.
-To resolve the ambiguity, embed the constraint in an interface or use a trailing
-comma:
+In these rare cases, the type parameter list is indistinguishable from an
+expression and the type declaration is parsed as an array type declaration.
+To resolve the ambiguity, embed the constraint in an
+interface or use a trailing comma:
@@ -2682,6 +2602,11 @@ of a method declaration associated
with a generic type.
+
+
Type constraints
@@ -2701,10 +2626,10 @@ the enclosing interface{ … }
may be omitted for convenience:
-[T *P] // = [T interface{*P}]
-[T ~int] // = [T interface{~int}]
-[T int|string] // = [T interface{int|string}]
-type Constraint ~int // illegal: ~int is not inside a type parameter list
+[T []P] // = [T interface{[]P}]
+[T ~int] // = [T interface{~int}]
+[T int|string] // = [T interface{int|string}]
+type Constraint ~int // illegal: ~int is not inside a type parameter list
+
A Pointer
is a pointer type but a Pointer
value may not be dereferenced.
-Any pointer or value of underlying type uintptr
can be converted to
-a type of underlying type Pointer
and vice versa.
+Any pointer or value of underlying type uintptr
can be
+converted to a type of underlying type Pointer
and vice versa.
The effect of converting between Pointer
and uintptr
is implementation-defined.
@@ -8055,7 +7980,8 @@ uintptr(unsafe.Pointer(&x)) % unsafe.Alignof(x) == 0
A (variable of) type T
has variable size if T
-is a type parameter, or if it is an array or struct type containing elements
+is a type parameter, or if it is an
+array or struct type containing elements
or fields of variable size. Otherwise the size is constant.
Calls to Alignof
, Offsetof
, and Sizeof
are compile-time constant expressions of