diff --git a/doc/go_spec.html b/doc/go_spec.html index 0b374e7bfb..63bc6a546e 100644 --- a/doc/go_spec.html +++ b/doc/go_spec.html @@ -1,9 +1,18 @@ +

Draft Go 1.18 Specification - Work in Progress

+ +

+ +For the pre-Go1.18 spec see +The Go Programming Language Specification. + +

+

Introduction

@@ -266,7 +275,7 @@ The following character sequences represent operators * ^ *= ^= <- > >= { } / << /= <<= ++ = := , ; % >> %= >>= -- ! ... . : - &^ &^= + &^ &^= ~

Integer literals

@@ -829,27 +838,41 @@ The underlying type of []B1, B3, and B4 i

Method sets

+

-A type has a (possibly empty) method set associated with it. -The method set of an interface type is its interface. -The method set of any other type T consists of all +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: +

+ + + +

+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.

-The method set of a type determines the interfaces that the -type implements -and the methods that can be called -using a receiver of that type. +In a method set, each method must have a +unique +non-blank method name.

Boolean types

@@ -1236,23 +1259,33 @@ func(n int) func(p *T)

Interface types

-An interface type specifies a method set called its interface. -A variable of interface type can store a value of any type with a method set -that is any superset of the interface. Such a type is said to -implement the interface. +An interface type defines a type set. +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 implement the interface. The value of an uninitialized variable of interface type is nil.

-InterfaceType      = "interface" "{" { ( MethodSpec | InterfaceTypeName ) ";" } "}" .
-MethodSpec         = MethodName Signature .
-MethodName         = identifier .
-InterfaceTypeName  = TypeName .
+InterfaceType  = "interface" "{" { InterfaceElem ";" } "}" .
+InterfaceElem  = MethodElem | TypeElem .
+MethodElem     = MethodName Signature .
+MethodName     = identifier .
+TypeElem       = TypeTerm { "|" TypeTerm } .
+TypeTerm       = [ "~" ] Type .
 

-An interface type may specify methods explicitly through method specifications, -or it may embed methods of other interfaces through interface type names. +An interface type is specified by a list of interface elements. +An interface element is either a method or a type element, +where a type element is a union of one or more type terms. +A type term is either a single type or a single underlying type. +

+ +

+In its most basic form an interface specifies a (possibly empty) list of methods. +The type set defined by such an interface is the set of types which implement all of +those methods, and the corresponding method set consists +exactly of the methods specified by the interface.

@@ -1297,15 +1330,19 @@ then the File interface is implemented by both S1 and
 

-A type implements any interface comprising any subset of its methods -and may therefore implement several distinct interfaces. For -instance, all types implement the empty interface: +Every type that is a member of the type set of an interface implements that interface. +Any given type may implement several distinct interfaces. +For instance, all types implement the empty interface which stands for the set of all types:

 interface{}
 
+

+For convenience, the predeclared type any is an alias for the empty interface. +

+

Similarly, consider this interface specification, which appears within a type declaration @@ -1334,12 +1371,16 @@ as the File interface.

-An interface T may use a (possibly qualified) interface type -name E in place of a method specification. This is called +In a slightly more general form +an interface T may use a (possibly qualified) interface type +name E as an interface element. This is called embedding interface E in T. -The method set of T is the union -of the method sets of T’s explicitly declared methods and of -T’s embedded interfaces. +The type set of T is the intersection of the type sets +defined by T's explicitly declared methods and the type sets +of T’s embedded interfaces. +In other words, the type set of T is the set of all types that implement all the +explicitly declared methods of T and also all the methods of +E.

@@ -1361,8 +1402,7 @@ type ReadWriter interface {
 

-A union of method sets contains the (exported and non-exported) -methods of each method set exactly once, and methods with the +When embedding interfaces, methods with the same names must have identical signatures.

@@ -1374,6 +1414,134 @@ type ReadCloser interface { }
+

+Finally, in their most general form, an interface element may be an arbitrary type +T, a type term of the form ~T, or a union of type terms +T1 | T2 | … Tn. +Together with method specifications, these elements enable the precise +definition of an interface's type set as follows: +

+ + + +
+// An interface representing only the type int.
+interface {
+	int
+}
+
+// An interface representing all types with underlying type int.
+interface {
+	~int
+}
+
+// An interface representing all types with underlying type int which implement the String method.
+interface {
+	~int
+	String() string
+}
+
+// An interface representing an empty type set: there is no type that is both an int and a string.
+interface {
+	int
+	string
+}
+
+ +

+In a term of the form ~T, the underlying type of T +must be itself, and T cannot be an interface. +

+ +
+type MyInt int
+
+interface {
+	~[]byte  // the underlying type of []byte is itself
+	~MyInt   // illegal: the underlying type of MyInt is not MyInt
+	~error   // illegal: error is an interface
+}
+
+ +

+Union expressions denote unions of type sets: +

+ +
+// The Floats interface represents all floating-point types
+// (including any named types whose underlying types are
+// either float32 or float64).
+type Floats interface {
+	~float32 | ~float64
+}
+
+ +

+In a union expression, 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 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
+}
+
+ +

+Implementation restriction: +A union expression with more than one term cannot contain interface types +with non-empty method sets. +

+ +

+Interfaces that contain union or tilde terms (not just methods) may only be used +as type constraints, or as elements of other interfaces used as constraints. They +cannot be the types of values or variables, or components of other, non-interface types. +

+ +
+var x Floats                     // illegal: Floats is restricted by float32 and float64
+
+var x interface{} = Floats(nil)  // illegal
+
+type Floatish struct {
+	f Floats                 // illegal
+}
+
+ + +

An interface type T may not embed itself or any interface type that embeds T, recursively. @@ -1872,7 +2040,8 @@ The following identifiers are implicitly declared in the

 Types:
-	bool byte complex64 complex128 error float32 float64
+	any bool byte comparable
+	complex64 complex128 error float32 float64
 	int int8 int16 int32 int64 rune string
 	uint uint8 uint16 uint32 uint64 uintptr