<!--{
"Title": "The Go Programming Language Specification",
- "Subtitle": "Version of Oct 15, 2021",
+ "Subtitle": "Version of Nov 17, 2021",
"Path": "/ref/spec"
}-->
+<h2>Draft Go 1.18 Specification - Work in Progress </h2>
+
+<p>
+<strong>
+For the pre-Go1.18 spec see
+<a href="/doc/go1.17_spec.html">The Go Programming Language Specification</a>.
+</strong>
+</p>
+
<h2 id="Introduction">Introduction</h2>
<p>
* ^ *= ^= <- > >= { }
/ << /= <<= ++ = := , ;
% >> %= >>= -- ! ... . :
- &^ &^=
+ &^ &^= ~
</pre>
<h3 id="Integer_literals">Integer literals</h3>
</p>
<h3 id="Method_sets">Method sets</h3>
+
<p>
-A type has a (possibly empty) <i>method set</i> associated with it.
-The method set of an <a href="#Interface_types">interface type</a> is its interface.
-The method set of any other type <code>T</code> consists of all
+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>.
-The method set of the corresponding <a href="#Pointer_types">pointer type</a> <code>*T</code>
-is the set of all methods declared with receiver <code>*T</code> or <code>T</code>
-(that is, it also contains the method set of <code>T</code>).
-Further rules apply to structs containing embedded fields, as described
-in the section on <a href="#Struct_types">struct types</a>.
+</li>
+
+<li>
+The method set of a <a href="#Pointer_types">pointer</a> <code>*T</code>
+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.
-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>
<p>
-The method set of a type determines the interfaces that the
-type <a href="#Interface_types">implements</a>
-and the methods that can be <a href="#Calls">called</a>
-using a receiver of that type.
+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>
<h3 id="Interface_types">Interface types</h3>
<p>
-An interface type specifies a <a href="#Method_sets">method set</a> called its <i>interface</i>.
-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
-<i>implement the interface</i>.
+An interface type defines a <i>type set</i>.
+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 <i>implement the interface</i>.
The value of an uninitialized variable of interface type is <code>nil</code>.
</p>
<pre class="ebnf">
-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 .
</pre>
<p>
-An interface type may specify methods <i>explicitly</i> through method specifications,
-or it may <i>embed</i> methods of other interfaces through interface type names.
+An interface type is specified by a list of <i>interface elements</i>.
+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.
+</p>
+
+<p>
+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 <a href="#Method_sets">method set</a> consists
+exactly of the methods specified by the interface.
</p>
<pre>
</p>
<p>
-A type implements any interface comprising any subset of its methods
-and may therefore implement several distinct interfaces. For
-instance, all types implement the <i>empty interface</i>:
+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 <i>empty interface</i> which stands for the set of all types:
</p>
<pre>
interface{}
</pre>
+<p>
+For convenience, the predeclared type <code>any</code> is an alias for the empty interface.
+</p>
+
<p>
Similarly, consider this interface specification,
which appears within a <a href="#Type_declarations">type declaration</a>
</p>
<p>
-An interface <code>T</code> may use a (possibly qualified) interface type
-name <code>E</code> in place of a method specification. This is called
+In a slightly more general form
+an interface <code>T</code> may use a (possibly qualified) interface type
+name <code>E</code> as an interface element. This is called
<i>embedding</i> interface <code>E</code> in <code>T</code>.
-The <a href="#Method_sets">method set</a> of <code>T</code> is the <i>union</i>
-of the method sets of <code>T</code>’s explicitly declared methods and of
-<code>T</code>’s embedded interfaces.
+The type set of <code>T</code> is the <i>intersection</i> of the type sets
+defined by <code>T</code>'s explicitly declared methods and the type sets
+of <code>T</code>’s embedded interfaces.
+In other words, the type set of <code>T</code> is the set of all types that implement all the
+explicitly declared methods of <code>T</code> and also all the methods of
+<code>E</code>.
</p>
<pre>
</pre>
<p>
-A <i>union</i> 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
<a href="#Uniqueness_of_identifiers">same</a> names must
have <a href="#Type_identity">identical</a> signatures.
</p>
}
</pre>
+<p>
+Finally, in their most general form, an interface element may be an arbitrary type
+<code>T</code>, a type term of the form <code>~T</code>, or a union of type terms
+<code>T1 | T2 | … Tn</code>.
+Together with method specifications, these elements enable the precise
+definition of an interface's type set as follows:
+</p>
+
+<ul>
+ <li>The type set of the empty interface is the set of all types.
+ </li>
+
+ <li>The type set of a non-empty interface is the intersection of the type sets
+ of its interface elements.
+ </li>
+
+ <li>The type set of a method specification is the set of types
+ whose method sets include that method.
+ </li>
+
+ <li>The type set of a non-interface type is the set consisting
+ of just that type.
+ </li>
+
+ <li>The type set of a term of the form <code>~T</code>
+ is the set of types whose underlying type is <code>T</code>.
+ </li>
+
+ <li>The type set of a <i>union</i> of terms <code>T1 | T2 | … Tn</code>
+ is the union of the type sets of the terms.
+ </li>
+</ul>
+
+<pre>
+// 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
+}
+</pre>
+
+<p>
+In a term of the form <code>~T</code>, the underlying type of <code>T</code>
+must be itself, and <code>T</code> cannot be an interface.
+</p>
+
+<pre>
+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
+}
+</pre>
+
+<p>
+Union expressions denote unions of type sets:
+</p>
+
+<pre>
+// 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
+}
+</pre>
+
+<p>
+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 <code>P</code>:
+</p>
+
+<pre>
+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
+}
+</pre>
+
+<p>
+Implementation restriction:
+A union expression with more than one term cannot contain interface types
+with non-empty <a href="#Method_sets">method sets</a>.
+</p>
+
+<p>
+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.
+</p>
+
+<pre>
+var x Floats // illegal: Floats is restricted by float32 and float64
+
+var x interface{} = Floats(nil) // illegal
+
+type Floatish struct {
+ f Floats // illegal
+}
+</pre>
+
+<!-- TODO The rule below needs to be generalized to interface elements.
+ It should be factored out and generalized to other types
+ such as arrays and structs which are currently missing such a
+ rule. See also #5069.
+-->
+
<p>
An interface type <code>T</code> may not embed itself
or any interface type that embeds <code>T</code>, recursively.
</p>
<pre class="grammar">
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