summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2010-06-07 15:49:39 -0700
committerRobert Griesemer <gri@golang.org>2010-06-07 15:49:39 -0700
commitbbbbbf8523f3e81ca82873254abdbb75d3a22e4f (patch)
tree87c059a878206ea84b59abdb67c5705871ba09fe /doc
parentded9ca954cd9b7380c814624137c02aaaf3516e6 (diff)
downloadgolang-bbbbbf8523f3e81ca82873254abdbb75d3a22e4f.tar.gz
go spec: clean-up and consolidation of spec with implementation
Specifically: - introduced notion of "underlying type" - removed notion of type compatibility - consolidated rules about assignment compatibility in assignment compatibility section - be consistent with specyfing that nil is the value for uninitialized variables that can be nil (this was not specified clearly for pointers, functions, interfaces) - added/fixed various related links throughout - clarify language on conversions R=rsc, r, iant, ken2 CC=golang-dev http://codereview.appspot.com/1536041
Diffstat (limited to 'doc')
-rw-r--r--doc/go_spec.html243
1 files changed, 125 insertions, 118 deletions
diff --git a/doc/go_spec.html b/doc/go_spec.html
index 5cd890ab9..dc9bd6497 100644
--- a/doc/go_spec.html
+++ b/doc/go_spec.html
@@ -1,5 +1,5 @@
<!-- title The Go Programming Language Specification -->
-<!-- subtitle Version of June 1, 2010 -->
+<!-- subtitle Version of June 7, 2010 -->
<!--
TODO
@@ -610,6 +610,27 @@ type literals.
</p>
<p>
+Each type <code>T</code> has an <i>underlying type</i>: If <code>T</code>
+is a predeclared type or a type literal, the corresponding underlying
+type is <code>T</code> itself. Otherwise, <code>T</code>'s underlying type
+is the underlying type of the type to which <code>T</code> refers in its
+<a href="#Type_declarations">type declaration</a>.
+</p>
+
+<pre>
+ type T1 string
+ type T2 T1
+ type T3 []T1
+ type T4 T3
+</pre>
+
+<p>
+The underlying type of <code>string</code>, <code>T1</code>, and <code>T2</code>
+is <code>string</code>. The underlying type of <code>[]T1</code>, <code>T3</code>,
+and <code>T4</code> is <code>[]T1</code>.
+</p>
+
+<p>
A type may have a <i>method set</i> associated with it
(§<a href="#Interface_types">Interface types</a>, §<a href="#Method_declarations">Method declarations</a>).
The method set of an <a href="#Interface_types">interface type</a> is its interface.
@@ -626,7 +647,8 @@ The <i>static type</i> (or just <i>type</i>) of a variable is the
type defined by its declaration. Variables of interface type
also have a distinct <i>dynamic type</i>, which
is the actual type of the value stored in the variable at run-time.
-The dynamic type may vary during execution but is always assignment compatible
+The dynamic type may vary during execution but is always
+<a href="#Assignment_compatibility">assignment compatible</a>
to the static type of the interface variable. For non-interface
types, the dynamic type is always the static type.
</p>
@@ -687,7 +709,7 @@ uintptr an unsigned integer large enough to store the uninterpreted bits of a p
To avoid portability issues all numeric types are distinct except
<code>byte</code>, which is an alias for <code>uint8</code>.
Conversions
-are required when incompatible numeric types are mixed in an expression
+are required when different numeric types are mixed in an expression
or assignment. For instance, <code>int32</code> and <code>int</code>
are not the same type even though they may have the same size on a
particular architecture.
@@ -753,7 +775,7 @@ multi-dimensional types.
A slice is a reference to a contiguous segment of an array and
contains a numbered sequence of elements from that array. A slice
type denotes the set of all slices of arrays of its element type.
-A slice value may be <code>nil</code>.
+The value of an uninitialized slice is <code>nil</code>.
</p>
<pre class="ebnf">
@@ -791,7 +813,6 @@ built-in function <code>cap(a)</code> and the relationship between
</pre>
<p>
-The value of an uninitialized slice is <code>nil</code>.
The length and capacity of a <code>nil</code> slice
are 0. A new, initialized slice value for a given element type <code>T</code> is
made using the built-in function <code>make</code>, which takes a slice type
@@ -938,7 +959,7 @@ struct {
<p>
A pointer type denotes the set of all pointers to variables of a given
type, called the <i>base type</i> of the pointer.
-A pointer value may be <code>nil</code>.
+The value of an unitialized pointer is <code>nil</code>.
</p>
<pre class="ebnf">
@@ -955,8 +976,8 @@ BaseType = Type .
<p>
A function type denotes the set of all functions with the same parameter
-and result types.
-A function value may be <code>nil</code>.
+and result types. The value of an unitialized variable of function type
+is <code>nil</code>.
</p>
<pre class="ebnf">
@@ -1006,7 +1027,8 @@ func(n int) func(p *T)
An interface type specifies a <a href="#Types">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 value may be <code>nil</code>.
+<i>implement the interface</i>.
+The value of an unitialized variable of interface type is <code>nil</code>.
</p>
<pre class="ebnf">
@@ -1110,8 +1132,7 @@ type File interface {
A map is an unordered group of elements of one type, called the
element type, indexed by a set of unique <i>keys</i> of another type,
called the key type.
-A map value may be <code>nil</code>.
-
+The value of an uninitialized map is <code>nil</code>.
</p>
<pre class="ebnf">
@@ -1143,7 +1164,6 @@ Values may be added and removed
during execution using special forms of <a href="#Assignments">assignment</a>.
</p>
<p>
-The value of an uninitialized map is <code>nil</code>.
A new, empty map value is made using the built-in
function <code>make</code>, which takes the map type and an optional
capacity hint as arguments:
@@ -1166,7 +1186,7 @@ stored in them.
A channel provides a mechanism for two concurrently executing functions
to synchronize execution and communicate by passing a value of a
specified element type.
-A value of channel type may be <code>nil</code>.
+The value of an uninitialized channel is <code>nil</code>.
</p>
<pre class="ebnf">
@@ -1200,7 +1220,7 @@ chan (&lt;-chan int)
</pre>
<p>
-The value of an uninitialized channel is <code>nil</code>. A new, initialized channel
+A new, initialized channel
value can be made using the built-in function
<a href="#Making_slices_maps_and_channels"><code>make</code></a>,
which takes the channel type and an optional capacity as arguments:
@@ -1224,21 +1244,17 @@ A channel may be closed and tested for closure with the built-in functions
<h2 id="Properties_of_types_and_values">Properties of types and values</h2>
+<h3 id="Type_identity">Type identity</h3>
+
<p>
-Two types are either <i>identical</i> or <i>different</i>, and they are
-either <i>compatible</i> or <i>incompatible</i>.
-Identical types are always compatible, but compatible types need not be identical.
+Two types are either <i>identical</i> or <i>different</i>.
</p>
-<h3 id="Type_identity_and_compatibility">Type identity and compatibility</h3>
-
-<h4 id="Type_identity">Type identity</h4>
-
<p>
Two named types are identical if their type names originate in the same
-type declaration (§<a href="#Declarations_and_scope">Declarations and scope</a>).
+type <a href="#Declarations_and_scope">declaration</a>.
A named and an unnamed type are always different. Two unnamed types are identical
-if the corresponding type literals are identical; that is if they have the same
+if the corresponding type literals are identical, that is, if they have the same
literal structure and corresponding components have identical types. In detail:
</p>
@@ -1272,14 +1288,6 @@ literal structure and corresponding components have identical types. In detail:
the same direction.</li>
</ul>
-<h4 id="Type_compatibility">Type compatibility</h4>
-
-<p>
-Type compatibility is less stringent than type identity: All identical types are
-compatible, but additionally a named and an unnamed type are compatible if the
-respective type literals are identical.
-</p>
-
<p>
Given the declarations
</p>
@@ -1307,46 +1315,45 @@ func(x int, y float) *[]string and func(int, float) (result *[]string)
</pre>
<p>
-<code>T0</code> and <code>T1</code> are neither identical nor compatible
-because they are named types with distinct declarations.
-</p>
-
-<p>
-These types are compatible:
+<code>T0</code> and <code>T1</code> are different because they are named types
+with distinct declarations; <code>func(int, float) *T0</code> and
+<code>func(x int, y float) *[]string</code> are different because <code>T0</code>
+is different from <code>[]string</code>.
</p>
-<pre>
-T0 and T0
-T0 and []string
-T3 and struct { a int; c int }
-T4 and func(x int, y float) (result *T0)
-</pre>
-
-<p>
-<code>T2</code> and <code>struct { a, c int }</code> are incompatible because
-they have different field names; <code>T4</code> and
-<code>func(x int, y float) *[]string</code> are incompatible because the
-respective type literals are different.
-</p>
<h3 id="Assignment_compatibility">Assignment compatibility</h3>
<p>
-A value <code>v</code> of static type <code>V</code> is <i>assignment compatible</i>
-with a type <code>T</code> if one or more of the following conditions applies:
+A value <code>x</code> is <i>assignment compatible</i> with type <code>T</code>
+(<code>x</code> <i>can be assigned to</i> <code>T</code>) in any of these cases:
</p>
<ul>
<li>
-<code>V</code> is compatible with <code>T</code>.
+<code>x</code>'s type is identical to <code>T</code>.
+</li>
+<li>
+<code>x</code>'s type <code>V</code> or <code>T</code> have identical
+<a href="#Types">underlying types</a> and <code>V</code> or <code>T</code>
+is not a named type.
</li>
<li>
<code>T</code> is an interface type and
-<code>V</code> <a href="#Interface_types">implements</a> <code>T</code>.
+<code>x</code> <a href="#Interface_types">implements</a> <code>T</code>.
+</li>
+<li>
+<code>x</code> is a bidirectional channel value, <code>T</code> is a channel type,
+<code>x</code>'s type <code>V</code> and <code>T</code> have identical element types,
+and <code>V</code> or <code>T</code> is not a named type.
</li>
<li>
-<code>V</code> is a bidirectional channel and <code>T</code> is a channel type
-with identical element type and at least one of <code>V</code> or <code>T</code> is unnamed.
+<code>x</code> is the predeclared identifier <code>nil</code> and <code>T</code>
+is a pointer, function, slice, map, channel, or interface type.
+</li>
+<li>
+<code>x</code> is an untyped <a href="#Constants">constant</a> representable
+by a value of type <code>T</code>.
</li>
</ul>
@@ -1359,18 +1366,6 @@ every field of the struct may be legally assigned individually by the program.
</p>
<p>
-An untyped <a href="#Constants">constant</a> <code>v</code>
-is assignment compatible with type <code>T</code> if <code>v</code>
-can be represented accurately as a value of type <code>T</code>.
-</p>
-
-<p>
-The predeclared identifier <code>nil</code> is assignment compatible with any
-pointer, function, slice, map, channel, or interface type and
-represents the <a href="#The_zero_value">zero value</a> for that type.
-</p>
-
-<p>
Any value may be assigned to the <a href="#Blank_identifier">blank identifier</a>.
</p>
@@ -1491,11 +1486,11 @@ The following identifiers are implicitly declared in the universe block:
</p>
<pre class="grammar">
Basic types:
- bool byte float32 float64 int8 int16 int32 int64
- string uint8 uint16 uint32 uint64
+ bool byte complex64 complex128 float32 float64
+ int8 int16 int32 int64 string uint8 uint16 uint32 uint64
Architecture-specific convenience types:
- float int uint uintptr
+ complex float int uint uintptr
Constants:
true false iota
@@ -1659,10 +1654,9 @@ last non-empty expression list.
<p>
A type declaration binds an identifier, the <i>type name</i>, to a new type
-that has the same definition (element, fields, channel direction, etc.) as
-an existing type. The new type is
-<a href="#Properties_of_types_and_values">compatible</a> with, but
-<a href="#Properties_of_types_and_values">different</a> from, the existing type.
+that has the same <a href="#Types">underlying type</a> as
+an existing type. The new type is <a href="#Type_identity">different</a> from
+the existing type.
</p>
<pre class="ebnf">
@@ -2498,8 +2492,8 @@ The notation <code>x.(T)</code> is called a <i>type assertion</i>.
</p>
<p>
More precisely, if <code>T</code> is not an interface type, <code>x.(T)</code> asserts
-that the dynamic type of <code>x</code> is identical to the type <code>T</code>
-(§<a href="#Type_identity">Type identity and compatibility</a>).
+that the dynamic type of <code>x</code> is <a href="#Type_identity">identical</a>
+to the type <code>T</code>.
If <code>T</code> is an interface type, <code>x.(T)</code> asserts that the dynamic type
of <code>x</code> implements the interface <code>T</code> (§<a href="#Interface_types">Interface types</a>).
</p>
@@ -2672,7 +2666,7 @@ Within <code>Greeting</code>, <code>who</code> will have value
As a special case, if a function passes its own <code>...</code> parameter,
with or without specified type, as the argument
for a <code>...</code> in a call to another function with a <code>...</code> parameter
-of identical type,
+of <a href="#Type_identity">identical type</a>,
the parameter is not wrapped again but passed directly. In short, a formal <code>...</code>
parameter is passed unchanged as an actual <code>...</code> parameter provided the
types match.
@@ -2700,8 +2694,7 @@ unary_op = "+" | "-" | "!" | "^" | "*" | "&amp;" | "&lt;-" .
<p>
Comparisons are discussed <a href="#Comparison_operators">elsewhere</a>.
-For other binary operators, the operand types must be identical
-(§<a href="#Properties_of_types_and_values">Properties of types and values</a>)
+For other binary operators, the operand types must be <a href="#Type_identity">identical</a>
unless the operation involves channels, shifts, or untyped <a href="#Constants">constants</a>.
For operations involving constants only, see the section on
<a href="#Constant_expressions">constant expressions</a>.
@@ -2924,8 +2917,8 @@ Comparison operators compare two operands and yield a value of type <code>bool</
The operands must be <i>comparable</i>; that is, the first operand
must be <a href="#Assignment_compatibility">assignment compatible</a>
with the type of the second operand, or vice versa.
-<p>
</p>
+<p>
The operators <code>==</code> and <code>!=</code> apply
to operands of all types except arrays and structs.
All other comparison operators apply only to integer, floating-point
@@ -2969,7 +2962,7 @@ and string values. The result of a comparison is defined as follows:
or if both are <code>nil</code>.
</li>
<li>
- Interface values are equal if they have identical dynamic types and
+ Interface values are equal if they have <a href="#Type_identity">identical</a> dynamic types and
equal dynamic values or if both are <code>nil</code>.
</li>
<li>
@@ -3259,51 +3252,65 @@ If the type starts with an operator it must be parenthesized:
</pre>
<p>
-In general, a conversion is permitted if
-</p>
-<ol>
-<li>
-the value of <code>x</code> would be
-<a href="#Assignment_compatibility">assignment compatible</a> with type
-<code>T</code> if <code>T</code> were unnamed
-</li>
-<li>
-<code>x</code> is of an unnamed pointer type and type <code>T</code> is another
-unnamed pointer type and the previous rule applies to the pointer base types.
-</li>
-</ol>
-<p>
-Such a conversion changes the type but not the representation of <code>x</code>.
+A value <code>x</code> can be converted to type <code>T</code> in any
+of these cases:
</p>
-<p>
-Specific rules apply to conversions where <code>T</code> is a
-numeric or string type, or where <code>x</code> is of string type.
-These conversions may change the representation of a value and incur a run-time cost.
-</p>
+<ul>
+ <li>
+ <code>x</code> can be <a href="#Assignment_compatibility">assigned</a>
+ to <code>T</code>.
+ </li>
+ <li>
+ <code>x</code>'s type and <code>T</code> have identical
+ <a href="#Types">underlying types</a>.
+ </li>
+ <li>
+ <code>x</code>'s type and <code>T</code> are unnamed pointer types
+ and their pointer base types have identical underlying types.
+ </li>
+ <li>
+ <code>x</code>'s type and <code>T</code> are both integer or floating
+ point types.
+ </li>
+ <li>
+ <code>x</code>'s type and <code>T</code> are both complex types.
+ </li>
+ <li>
+ <code>x</code> is an integer or has type <code>[]byte</code> or
+ <code>[]int</code> and <code>T</code> is a string type.
+ </li>
+ <li>
+ <code>x</code> is a string and <code>T</code> is <code>[]byte</code> or
+ <code>[]int</code>.
+ </li>
+</ul>
-<h4>Conversions between integer types</h4>
<p>
-If the value is a signed quantity, it is
-sign extended to implicit infinite precision; otherwise it is zero
-extended. It is then truncated to fit in the result type's size.
-For example, if <code>x := uint16(0x10F0)</code>, then <code>uint32(int8(x)) == 0xFFFFFFF0</code>.
-The conversion always yields a valid value; there is no indication of overflow.
+Specific rules apply to conversions between numeric types or to and from
+a string type.
+These conversions may change the representation of <code>x</code>
+and incur a run-time cost.
+All other conversions only change the type but not the representation
+of <code>x</code>.
</p>
-<h4>Conversions involving floating point and complex types</h4>
+<h4>Conversions between numeric types</h4>
<ol>
<li>
-When converting a floating-point number to an integer, the fraction is discarded
-(truncation towards zero).
+When converting between integer types, if the value is a signed integer, it is
+sign extended to implicit infinite precision; otherwise it is zero extended.
+It is then truncated to fit in the result type's size.
+For example, if <code>v := uint16(0x10F0)</code>, then <code>uint32(int8(v)) == 0xFFFFFFF0</code>.
+The conversion always yields a valid value; there is no indication of overflow.
</li>
<li>
-A value of complex type may be converted to a different complex type,
-but there is no conversion between complex and any other type.
+When converting a floating-point number to an integer, the fraction is discarded
+(truncation towards zero).
</li>
<li>
-When converting a number to a floating-point or complex type,
-the result value is rounded
+When converting an integer or floating-point number to a floating-point type,
+or a complex number to another complex type, the result value is rounded
to the precision specified by the destination type.
For instance, the value of a variable <code>x</code> of type <code>float32</code>
may be stored using additional precision beyond that of an IEEE-754 32-bit number,
@@ -3325,8 +3332,8 @@ implementation-dependent.
<ol>
<li>
Converting a signed or unsigned integer value to a string type yields a
-string containing the UTF-8 representation of the integer.
-Negative values are converted to <code>"\uFFFD"</code>.
+string containing the UTF-8 representation of the integer. Values outside
+the range of valid Unicode code points are converted to <code>"\uFFFD"</code>.
<pre>
string('a') // "a"
@@ -4486,7 +4493,7 @@ m := make(map[string] int, 100) // map with initial space for 100 elements
The built-in function <code>copy</code> copies slice elements from
a source <code>src</code> to a destination <code>dst</code> and returns the
number of elements copied. Source and destination may overlap.
-Both arguments must have identical element type <code>T</code> and must be
+Both arguments must have <a href="#Type_identity">identical</a> element type <code>T</code> and must be
<a href="#Assignment_compatibility">assignment compatible</a> to a slice
of type <code>[]T</code>. The number of arguments copied is the minimum of
<code>len(src)</code> and <code>len(dst)</code>.