From: Rob Pike Date: Tue, 24 Feb 2009 03:26:07 +0000 (-0800) Subject: Move Types before Declarations and Scopes. X-Git-Tag: weekly.2009-11-06~2142 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=a9ed30ff377976b9e2fd7fb4a897ffda71649474;p=gostls13.git Move Types before Declarations and Scopes. This is the only change in this CL: only rearrangement, no content change, so subsequent edits will be easier to understand. R=gri OCL=25353 CL=25353 --- diff --git a/doc/go_spec.html b/doc/go_spec.html index f3a52b970a..32ac34e3db 100644 --- a/doc/go_spec.html +++ b/doc/go_spec.html @@ -538,1269 +538,1270 @@ literal.


-

Declarations and Scope

+

Types

+A type specifies the set of values that variables of that type may assume +and the operators that are applicable.

-A declaration binds an identifier to a language entity such as -a variable or function and specifies properties such as its type. -Every identifier in a program must be declared. -

+A type may be specified by a type name (§Type declarations) or a type literal. +A type literal is a syntactic construct that explicitly specifies the +composition of a new type in terms of other (already declared) types.
-Declaration = ConstDecl | TypeDecl | VarDecl | FunctionDecl | MethodDecl .
+Type = TypeName | TypeLit | "(" Type ")" .
+TypeName = QualifiedIdent.
+TypeLit =
+	ArrayType | StructType | PointerType | FunctionType | InterfaceType |
+	SliceType | MapType | ChannelType .
 
- + +Some types are predeclared and denoted by their type names; these are called +``basic types''. Generally (except for strings) they are not composed of more +elementary types; instead they model elementary machine data types.

-The scope of an identifier is the extent of source text within which the -identifier denotes the bound entity. No identifier may be declared twice in a -single scope, but inner blocks can declare a new entity with the same -identifier, in which case the scope created by the outer declaration excludes -that created by the inner. -

+All other types are called ``composite types'; they are composed from other +(basic or composite) types and denoted by their type names or by type literals. +There are arrays, structs, pointers, functions, interfaces, slices, maps, and +channels.

-There are levels of scoping in effect before each source file is compiled. -In order from outermost to innermost: -

-
    -
  1. The universe scope contains all predeclared identifiers.
  2. -
  3. An implicit scope contains only the package name.
  4. -
  5. The package-level scope surrounds all declarations at the - top level of the file, that is, outside the body of any - function or method. That scope is shared across all - source files within the package (§Packages), allowing - package-level identifiers to be shared between source - files.
  6. -
+At a given point in the source code, a type may be ``complete'' or +''incomplete''. Array and struct types are complete when they are fully declared. +All other types are always complete (although their components, such as the base +type of a pointer type, may be incomplete). Incomplete types are subject to usage +restrictions; for instance the type of a variable must be complete where the +variable is declared. +The ``interface'' of a type is the set of methods bound to it +(§Method declarations). The interface of a pointer type is the interface +of the pointer base type (§Pointer types). All types have an interface; +if they have no methods associated with them, their interface is +called the ``empty'' interface.

-The scope of an identifier depends on the entity declared: -

- -
    -
  1. The scope of predeclared identifiers is the universe scope.
  2. - -
  3. The scope of an (identifier denoting a) type, function or package - extends from the point of the identifier in the declaration - to the end of the innermost surrounding block.
  4. +The ``static type'' (or simply ``type'') of a variable is the type defined by +the variable's declaration. The ``dynamic type'' of a variable is the actual +type of the value stored in a variable at run-time. Except for variables of +interface type, the dynamic type of a variable is always its static type. +

    +Variables of interface type may hold values with different dynamic types +during execution. However, its dynamic type is always compatible with +the static type of the interface variable (§Interface types). + -

  5. The scope of a constant or variable extends textually from - the end of the declaration to the end of the innermost - surrounding block. If the variable is declared in the - init statement of an if , for, - or switch statement, the - innermost surrounding block is the block associated - with that statement.
  6. +

    Basic types

    -
  7. The scope of a parameter or result is the body of the - corresponding function.
  8. +Go defines a number of basic types, referred to by their predeclared +type names. These include traditional arithmetic types, booleans, +and strings. -
  9. The scope of a field or method is selectors for the - corresponding type containing the field or method (§Selectors).
  10. -
  11. The scope of a label is a unique scope emcompassing - the body of the innermost surrounding function, excluding - nested functions. Labels do not conflict with variables.
  12. -
+

Arithmetic types

-

Predeclared identifiers

+The following list enumerates all platform-independent numeric types: -

-The following identifiers are implicitly declared in the outermost scope: -

-Basic types:
-	bool byte float32 float64 int8 int16 int32 int64 string uint8 uint16 uint32 uint64
-
-Platform-specific convenience types:
-	float int uint uintptr
+byte     same as uint8 (for convenience)
 
-Constants:
-	true false iota nil
+uint8    the set of all unsigned  8-bit integers (0 to 255)
+uint16   the set of all unsigned 16-bit integers (0 to 65535)
+uint32   the set of all unsigned 32-bit integers (0 to 4294967295)
+uint64   the set of all unsigned 64-bit integers (0 to 18446744073709551615)
 
-Functions:
-	cap convert len make new panic panicln print println typeof (TODO: typeof??)
+int8     the set of all signed  8-bit integers (-128 to 127)
+int16    the set of all signed 16-bit integers (-32768 to 32767)
+int32    the set of all signed 32-bit integers (-2147483648 to 2147483647)
+int64    the set of all signed 64-bit integers (-9223372036854775808 to 9223372036854775807)
 
-Packages:
-	sys unsafe  (TODO: does sys endure?)
+float32  the set of all valid IEEE-754 32-bit floating point numbers
+float64  the set of all valid IEEE-754 64-bit floating point numbers
 
+Integer types are represented in the usual binary format; the value of +an n-bit integer is n bits wide. A negative signed integer is represented +as the two's complement of its absolute value. -

Exported identifiers

+ -

-By default, identifiers are visible only within the package in which they are declared. -Some identifiers are exported and can be referenced using -qualified identifiers in other packages (§Qualified identifiers). -If an identifier satisfies these two conditions: -

-
    -
  1. the first character of the identifier's name is a Unicode upper case letter; -
  2. the identifier is declared at the package level or is a field or method of a type -declared at the top level; -
-

-it will be exported automatically. -

+Additionally, Go declares a set of platform-specific numeric types for +convenience: -

Const declarations

+
+uint     at least 32 bits, at most the size of the largest uint type
+int      at least 32 bits, at most the size of the largest int type
+float    at least 32 bits, at most the size of the largest float type
+uintptr  smallest uint type large enough to store the uninterpreted
+		 bits of a pointer value
+
+For instance, int might have the same size as int32 on a 32-bit +architecture, or int64 on a 64-bit architecture.

-A constant declaration binds a list of identifiers (the names of -the constants) to the values of a list of constant expressions -(§Constant expressions). The number of identifiers must be equal -to the number of expressions, and the nth identifier on -the left is bound to value of the nth expression on the -right. -

+Except for "byte", which is an alias for "uint8", all numeric types +are different from each other to avoid portability issues. Conversions +are required when different numeric types are mixed in an expression or assignment. +For instance, "int32" and "int" are not the same type even though they may have +the same size on a particular platform. -
-ConstDecl      = "const" ( ConstSpec | "(" [ ConstSpecList ] ")" ) .
-ConstSpecList  = ConstSpec { ";" ConstSpec } [ ";" ] .
-ConstSpec      = IdentifierList [ CompleteType ] [ "=" ExpressionList ] .
 
-IdentifierList = identifier { "," identifier } .
-ExpressionList = Expression { "," Expression } .
+

Booleans

-CompleteType = Type . -
+The type "bool" comprises the truth values true and false, which are +available through the two predeclared constants, "true" and "false". -

-If the type (CompleteType) is omitted, the constants take the -individual types of the corresponding expressions, which may be -``ideal integer'' or ``ideal float'' (§Ideal number). If the type -is present, all constants take the type specified, and the types -of all the expressions must be assignment-compatible -with that type. -

-
-const Pi float64 = 3.14159265358979323846
-const E = 2.718281828
-const (
-	size int64 = 1024;
-	eof = -1;
-)
-const a, b, c = 3, 4, "foo"  // a = 3, b = 4, c = "foo"
-const u, v float = 0, 3      // u = 0.0, v = 3.0
-
+

Strings

-Within a parenthesized const declaration list the -expression list may be omitted from any but the first declaration. -Such an empty list is equivalent to the textual substitution of the -first preceding non-empty expression list. Omitting the list of -expressions is therefore equivalent to repeating the previous list. -The number of identifiers must be equal to the number of expressions -in the previous list. Together with the iota constant generator -(§Iota) this mechanism permits light-weight declaration of sequential values: +The "string" type represents the set of string values (strings). +Strings behave like arrays of bytes, with the following properties:

+ -

Iota

+

Array types

-

-Within a constant declaration, the predeclared pseudo-constant -iota represents successive integers. It is reset to 0 -whenever the reserved word const appears in the source -and increments with each semicolon. It can be used to construct a -set of related constants: -

+An array is a composite type consisting of a number of elements all of the +same type, called the element type. The element type must be a complete type +(§Types). The number of elements of an array is called its length; it is never +negative. The elements of an array are designated by indices +which are integers from 0 through the length - 1. -
-const (            // iota is reset to 0
-	c0 = iota;  // c0 == 0
-	c1 = iota;  // c1 == 1
-	c2 = iota   // c2 == 2
-)
-
-const (
-	a = 1 << iota;  // a == 1 (iota has been reset)
-	b = 1 << iota;  // b == 2
-	c = 1 << iota;  // c == 4
-)
+
+ArrayType = "[" ArrayLength "]" ElementType .
+ArrayLength = Expression .
+ElementType = CompleteType .
+
-const ( - u = iota * 42; // u == 0 (ideal integer) - v float = iota * 42; // v == 42.0 (float) - w = iota * 42; // w == 84 (ideal integer) -) +The array length and its value are part of the array type. The array length +must be a constant expression (§Constant expressions) that evaluates to an +integer value >= 0. +

+The number of elements of an array "a" can be discovered using the built-in +function -const x = iota; // x == 0 (iota has been reset) -const y = iota; // y == 0 (iota has been reset) +

+len(a)
 
-

-Within an ExpressionList, the value of each iota is the same because -it is only incremented at a semicolon: -

+The length of arrays is known at compile-time, and the result of a call to +"len(a)" is a compile-time constant.
-const (
-	bit0, mask0 = 1 << iota, 1 << iota - 1;  // bit0 == 1, mask0 == 0
-	bit1, mask1;                             // bit1 == 2, mask1 == 1
-	bit2, mask2;                             // bit2 == 4, mask2 == 3
-)
+[32]byte
+[2*N] struct { x, y int32 }
+[1000]*float64
 
-

-This last example exploits the implicit repetition of the -last non-empty expression list. -

+Assignment compatibility: Arrays can be assigned to variables of equal type +and to slice variables with equal element type. When assigning to a slice +variable, the array is not copied but a slice comprising the entire array +is created. -

Type declarations

+

Struct types

-

-A type declaration binds an identifier, the type name, -to a new type. TODO: what exactly is a "new type"? -

+A struct is a composite type consisting of a fixed number of elements, +called fields, with possibly different types. A struct type declares +an identifier and type for each field. Within a struct type no field +identifier may be declared twice and all field types must be complete +types (§Types).
-TypeDecl     = "type" ( TypeSpec | "(" [ TypeSpecList ] ")" ) .
-TypeSpecList = TypeSpec { ";" TypeSpec } [ ";" ] .
-TypeSpec     = identifier Type .
+StructType = "struct" [ "{" [ FieldDeclList ] "}" ] .
+FieldDeclList = FieldDecl { ";" FieldDecl } [ ";" ] .
+FieldDecl = (IdentifierList CompleteType | [ "*" ] TypeName) [ Tag ] .
+Tag = StringLit .
 
-type IntArray [16] int
-
-type (
-	Point struct { x, y float };
-	Polar Point
-)
-
-type TreeNode struct {
-	left, right *TreeNode;
-	value Point;
-}
+// An empty struct.
+struct {}
 
-type Comparable interface {
-	cmp(Comparable) int
+// A struct with 5 fields.
+struct {
+	x, y int;
+	u float;
+	A *[]int;
+	F func();
 }
 
-

Variable declarations

+A struct may contain ``anonymous fields'', which are declared with a type +but no explicit field identifier. An anonymous field type must be specified as +a type name "T", or as a pointer to a type name ``*T'', and T itself may not be +a pointer or interface type. The unqualified type name acts as the field identifier. -

-A variable declaration creates a variable, binds an identifier to it and -gives it a type and optionally an initial value. -The variable type must be a complete type (§Types). -

-
-VarDecl     = "var" ( VarSpec | "(" [ VarSpecList ] ")" ) .
-VarSpecList = VarSpec { ";" VarSpec } [ ";" ] .
-VarSpec     = IdentifierList ( CompleteType [ "=" ExpressionList ] | "=" ExpressionList ) .
+
+// A struct with four anonymous fields of type T1, *T2, P.T3 and *P.T4
+struct {
+	T1;        // the field name is T1
+	*T2;       // the field name is T2
+	P.T3;      // the field name is the unqualified type name T3
+	*P.T4;     // the field name is the unqualified type name T4
+	x, y int;  
+}
 
+The unqualified type name of an anonymous field must not conflict with the +field identifier (or unqualified type name for an anonymous field) of any +other field within the struct. The following declaration is illegal: +
-var i int
-var U, V, W float
-var k = 0
-var x, y float = -1.0, -2.0
-var (
-	i int;
-	u, v, s = 2.0, 3.0, "bar"
-)
+struct {
+	T;         // conflicts with anonymous field *T and *P.T
+	*T;        // conflicts with anonymous field T and *P.T
+	*P.T;      // conflicts with anonymous field T and *T
+}
 
+Fields and methods (§Method declarations) of an anonymous field become directly +accessible as fields and methods of the struct without the need to provide the +type name of the respective anonymous field (§Selectors).

-If there are expressions, their number must be equal -to the number of identifiers, and the nth variable -is initialized to the value of the nth expression. -Otherwise, each variable is initialized to the zero -of the type (§Program initialization and execution). -The expressions can be general expressions; they need not be constants. -

-

-Either the type or the expression list must be present. If the -type is present, it sets the type of each variable and the expressions -(if any) must be assignment-compatible to that type. If the type -is absent, the variables take the types of the corresponding -expressions. -

-

-If the type is absent and the corresponding expression is a constant -expression of ideal integer or ideal float type, the type of the -declared variable is int or float -respectively: -

+A field declaration may be followed by an optional string literal tag which +becomes an ``attribute'' for all the identifiers in the corresponding +field declaration. The tags are available via the reflection library but +are ignored otherwise. A tag may contain arbitrary application-specific +information.
-var i = 0       // i has type int
-var f = 3.1415  // f has type float
+// A struct corresponding to the EventIdMessage protocol buffer.
+// The tag strings contain the protocol buffer field tags.
+struct {
+	time_usec uint64 "1";
+	server_ip uint32 "2";
+	process_id uint32 "3";
+}
 
-

Short variable declarations

+Assignment compatibility: Structs are assignment compatible to variables of +equal type only. -A short variable declaration uses the syntax -
-SimpleVarDecl = IdentifierList ":=" ExpressionList .
-
+

Pointer types

-and is shorthand for the declaration syntax +A pointer type denotes the set of all pointers to variables of a given +type, called the ``base type'' of the pointer, and the value "nil".
-"var" IdentifierList = ExpressionList .
+PointerType = "*" BaseType .
+BaseType = Type .
 
-i, j := 0, 10;
-f := func() int { return 7; }
-ch := new(chan int);
+*int
+map[string] chan
 
-

-Unlike regular variable declarations, short variable declarations -can be used, by analogy with tuple assignment (§Assignments), to -receive the individual elements of a multi-valued expression such -as a call to a multi-valued function. In this form, the ExpressionLIst -must be a single such multi-valued expression, the number of -identifiers must equal the number of values, and the declared -variables will be assigned the corresponding values. -

+The pointer base type may be denoted by an identifier referring to an +incomplete type (§Types), possibly declared via a forward declaration. +This allows the construction of recursive and mutually recursive types +such as:
-count, error := os.Close(fd);  // os.Close()  returns two values
+type S struct { s *S }
+
+type S2 struct // forward declaration of S2
+type S1 struct { s2 *S2 }
+type S2 struct { s1 *S1 }
 
+Assignment compatibility: A pointer is assignment compatible to a variable +of pointer type, only if both types are equal.

-Short variable declarations may appear only inside functions. -In some contexts such as the initializers for if, -for, or switch statements, -they can be used to declare local temporary variables (§Statements). -

- -

Function declarations

- +Comparisons: A variable of pointer type can be compared against "nil" with the +operators "==" and "!=" (§Comparison operators). The variable is +"nil" only if "nil" is assigned explicitly to the variable (§Assignments), or +if the variable has not been modified since creation (§Program initialization +and execution).

-A function declaration binds an identifier to a function (§Function types). -

+Two variables of equal pointer type can be tested for equality with the +operators "==" and "!=" (§Comparison operators). The pointers are equal +if they point to the same location. -
-FunctionDecl = "func" identifier Signature [ Block ] .
-
+Pointer arithmetic of any kind is not permitted. -
-func min(x int, y int) int {
-	if x < y {
-		return x;
-	}
-	return y;
-}
-
-

-A function must be declared or forward-declared before it can be invoked (§Forward declarations). -Implementation restriction: Functions can only be declared at the package level. -

+

Function types

-

Method declarations

+A function type denotes the set of all functions with the same parameter +and result types, and the value "nil". -

-A method declaration binds an identifier to a method, -which is a function with a receiver. -

-MethodDecl = "func" Receiver identifier Signature [ Block ] .
-Receiver = "(" [ identifier ] [ "*" ] TypeName ")" .
+FunctionType = "func" Signature .
+Signature = "(" [ ParameterList ] ")" [ Result ] .
+ParameterList = ParameterDecl { "," ParameterDecl } .
+ParameterDecl = [ IdentifierList ] ( Type | "..." ) .
+Result = Type | "(" ParameterList ")" .
 
+In ParameterList, the parameter names (IdentifierList) either must all be +present, or all be absent. If the parameters are named, each name stands +for one parameter of the specified type. If the parameters are unnamed, each +type stands for one parameter of that type.

-The receiver type must be a type name or a pointer to a type name, -and that name is called the receiver base type or just base type. -The base type must not be a pointer type and must be -declared in the same source file as the method. -The method is said to be bound to the base type -and is visible only within selectors for that type -(§Type declarations, §Selectors). -

- -

-All methods bound to a base type must have the same receiver type, -either all pointers to the base type or all the base type itself. -Given type Point, the declarations -

+For the last incoming parameter only, instead of a parameter type one +may write "...". The ellipsis indicates that the last parameter stands +for an arbitrary number of additional arguments of any type (including +no additional arguments). If the parameters are named, the identifier +list immediately preceding "..." must contain only one identifier (the +name of the last parameter).
-func (p *Point) Length() float {
-	return Math.sqrt(p.x * p.x + p.y * p.y);
-}
+func ()
+func (x int)
+func () int
+func (string, float, ...)
+func (a, b int, z float) bool
+func (a, b int, z float) (bool)
+func (a, b int, z float, opt ...) (success bool)
+func (int, int, float) (float, *[]int)
+
-func (p *Point) Scale(factor float) { - p.x = p.x * factor; - p.y = p.y * factor; -} +If the result type of a function is itself a function type, the result type +must be parenthesized to resolve a parsing ambiguity: + +
+func (n int) (func (p* T))
 
+Assignment compatibility: A function can be assigned to a function +variable only if both function types are equal.

-bind the methods Length and Scale -to the base type Point. -

- +Comparisons: A variable of function type can be compared against "nil" with the +operators "==" and "!=" (§Comparison operators). The variable is +"nil" only if "nil" is assigned explicitly to the variable (§Assignments), or +if the variable has not been modified since creation (§Program initialization +and execution).

-If the -receiver's value is not referenced inside the the body of the method, -its identifier may be omitted in the declaration. The same applies in -general to parameters of functions and methods. -

+Two variables of equal function type can be tested for equality with the +operators "==" and "!=" (§Comparison operators). The variables are equal +if they refer to the same function. -

-Methods can be declared -only after their base type is declared or forward-declared, and invoked -only after their own declaration or forward-declaration (§Forward declarations). -Implementation restriction: They can only be declared at package level. -

-

Forward declarations

+

Interface types

-

-Mutually-recursive types struct or interface types require that one be -forward declared so that it may be named in the other. -A forward declaration of a type omits the block containing the fields -or methods of the type. -

+Type interfaces may be specified explicitly by interface types. +An interface type denotes the set of all types that implement at least +the set of methods specified by the interface type, and the value "nil". + +
+InterfaceType = "interface" [ "{" [ MethodSpecList ] "}" ] .
+MethodSpecList = MethodSpec { ";" MethodSpec } [ ";" ] .
+MethodSpec = IdentifierList Signature | TypeName .
+
-type List struct  // forward declaration of List
-type Item struct {
-	value int;
-	next *List;
-}
-type List struct {
-	head, tail *Item
+// An interface specifying a basic File type.
+interface {
+	Read, Write	(b Buffer) bool;
+	Close		();
 }
 
-

-A forward-declared type is incomplete (§Types) -until it is fully declared. The full declaration must follow -before the end of the block containing the forward declaration. -

-

-Functions and methods may similarly be forward-declared by omitting their body. -

+ +Any type (including interface types) whose interface has, possibly as a +subset, the complete set of methods of an interface I is said to implement +interface I. For instance, if two types S1 and S2 have the methods +
-func F(a int) int  // forward declaration of F
-func G(a, b int) int {
-	return F(a) + F(b)
-}
-func F(a int) int {
-	if a <= 0 { return 0 }
-	return G(a-1, b+1)
-}
+func (p T) Read(b Buffer) bool { return ... }
+func (p T) Write(b Buffer) bool { return ... }
+func (p T) Close() { ... }
 
-
+(where T stands for either S1 or S2) then the File interface is +implemented by both S1 and S2, regardless of what other methods +S1 and S2 may have or share. -

Types

+All types implement the empty interface: -A type specifies the set of values that variables of that type may assume -and the operators that are applicable. -

-A type may be specified by a type name (§Type declarations) or a type literal. -A type literal is a syntactic construct that explicitly specifies the -composition of a new type in terms of other (already declared) types. +

+interface {}
+
-
-Type = TypeName | TypeLit | "(" Type ")" .
-TypeName = QualifiedIdent.
-TypeLit =
-	ArrayType | StructType | PointerType | FunctionType | InterfaceType |
-	SliceType | MapType | ChannelType .
+In general, a type implements an arbitrary number of interfaces.
+For instance, consider the interface
+
+
+type Lock interface {
+	Lock, Unlock	();
+}
 
-Some types are predeclared and denoted by their type names; these are called -``basic types''. Generally (except for strings) they are not composed of more -elementary types; instead they model elementary machine data types. -

-All other types are called ``composite types'; they are composed from other -(basic or composite) types and denoted by their type names or by type literals. -There are arrays, structs, pointers, functions, interfaces, slices, maps, and -channels. -

-At a given point in the source code, a type may be ``complete'' or -''incomplete''. Array and struct types are complete when they are fully declared. -All other types are always complete (although their components, such as the base -type of a pointer type, may be incomplete). Incomplete types are subject to usage -restrictions; for instance the type of a variable must be complete where the -variable is declared. +If S1 and S2 also implement -The ``interface'' of a type is the set of methods bound to it -(§Method declarations). The interface of a pointer type is the interface -of the pointer base type (§Pointer types). All types have an interface; -if they have no methods associated with them, their interface is -called the ``empty'' interface. -

-The ``static type'' (or simply ``type'') of a variable is the type defined by -the variable's declaration. The ``dynamic type'' of a variable is the actual -type of the value stored in a variable at run-time. Except for variables of -interface type, the dynamic type of a variable is always its static type. +

+func (p T) Lock() { ... }
+func (p T) Unlock() { ... }
+
+ +they implement the Lock interface as well as the File interface.

-Variables of interface type may hold values with different dynamic types -during execution. However, its dynamic type is always compatible with -the static type of the interface variable (§Interface types). - +An interface may contain a type name T in place of a method specification. +T must denote another, complete (and not forward-declared) interface type. +Using this notation is equivalent to enumerating the methods of T explicitly +in the interface containing T. -

Basic types

+
+type ReadWrite interface {
+	Read, Write	(b Buffer) bool;
+}
 
-Go defines a number of basic types, referred to by their predeclared
-type names.  These include traditional arithmetic types, booleans,
-and strings.
+type File interface {
+	ReadWrite;  // same as enumerating the methods in ReadWrite
+	Lock;       // same as enumerating the methods in Lock
+	Close();
+}
+
+Forward declaration: +A interface type consisting of only the reserved word "interface" may be used in +a type declaration; it declares an incomplete interface type (§Type declarations). +This allows the construction of mutually recursive types such as: -

Arithmetic types

+
+type T2 interface
+type T1 interface {
+	foo(T2) int;
+}
+type T2 interface {
+	bar(T1) int;
+}
+
-The following list enumerates all platform-independent numeric types: +Assignment compatibility: A value can be assigned to an interface variable +if the static type of the value implements the interface or if the value is "nil". +

+Comparisons: A variable of interface type can be compared against "nil" with the +operators "==" and "!=" (§Comparison operators). The variable is +"nil" only if "nil" is assigned explicitly to the variable (§Assignments), or +if the variable has not been modified since creation (§Program initialization +and execution). +

+Two variables of interface type can be tested for equality with the +operators "==" and "!=" (§Comparison operators) if both variables have the +same static type. They are equal if both their dynamic types and values are +equal. If the dynamic types are equal but the values do not support comparison, +a run-time error occurs. -

-byte     same as uint8 (for convenience)
 
-uint8    the set of all unsigned  8-bit integers (0 to 255)
-uint16   the set of all unsigned 16-bit integers (0 to 65535)
-uint32   the set of all unsigned 32-bit integers (0 to 4294967295)
-uint64   the set of all unsigned 64-bit integers (0 to 18446744073709551615)
+

Slice types

-int8 the set of all signed 8-bit integers (-128 to 127) -int16 the set of all signed 16-bit integers (-32768 to 32767) -int32 the set of all signed 32-bit integers (-2147483648 to 2147483647) -int64 the set of all signed 64-bit integers (-9223372036854775808 to 9223372036854775807) +A slice type denotes the set of all slices (segments) of arrays +(§Array types) of a given element type, and the value "nil". +The number of elements of a slice is called its length; it is never negative. +The elements of a slice are designated by indices which are +integers from 0 through the length - 1. -float32 the set of all valid IEEE-754 32-bit floating point numbers -float64 the set of all valid IEEE-754 64-bit floating point numbers +
+SliceType = "[" "]" ElementType .
 
-Integer types are represented in the usual binary format; the value of -an n-bit integer is n bits wide. A negative signed integer is represented -as the two's complement of its absolute value. +Syntactically and semantically, arrays and slices look and behave very +similarly, but with one important difference: A slice is a descriptor +of an array segment; in particular, different variables of a slice type may +refer to different (and possibly overlapping) segments of the same underlying +array. Thus, with respect to the underlying array, slices behave like +references. In contrast, two different variables of array type always +denote two different arrays. +

+For slices, the actual array underlying the slice may extend past the current +slice length; the maximum length a slice may assume is called its capacity. +The capacity of any slice "a" can be discovered using the built-in function - +

+cap(a)
+
-Additionally, Go declares a set of platform-specific numeric types for -convenience: +and the following relationship between "len()" and "cap()" holds: -
-uint     at least 32 bits, at most the size of the largest uint type
-int      at least 32 bits, at most the size of the largest int type
-float    at least 32 bits, at most the size of the largest float type
-uintptr  smallest uint type large enough to store the uninterpreted
-		 bits of a pointer value
+
+0 <= len(a) <= cap(a)
 
-For instance, int might have the same size as int32 on a 32-bit -architecture, or int64 on a 64-bit architecture. -

-Except for "byte", which is an alias for "uint8", all numeric types -are different from each other to avoid portability issues. Conversions -are required when different numeric types are mixed in an expression or assignment. -For instance, "int32" and "int" are not the same type even though they may have -the same size on a particular platform. +The value of an uninitialized slice is "nil", and its length and capacity +are 0. A new, initialized slice value for a given element type T is +made using the built-in function "make", which takes a slice type +and parameters specifying the length and optionally the capacity: + +

+make([]T, length)
+make([]T, length, capacity)
+
+ +The "make()" call allocates a new underlying array to which the returned +slice value refers. More precisely, calling "make" +
+make([]T, length, capacity)
+
-

Booleans

+is effectively the same as allocating an array and slicing it -The type "bool" comprises the truth values true and false, which are -available through the two predeclared constants, "true" and "false". +
+new([capacity]T)[0 : length]
+
+Assignment compatibility: Slices are assignment compatible to variables +of the same type. +

+Indexing: Given a (pointer to) a slice variable "a", a slice element is +specified with an index operation: -

Strings

+
+a[i]
+
+This denotes the slice element at index "i". "i" must be within bounds, +that is "0 <= i < len(a)".

-The "string" type represents the set of string values (strings). -Strings behave like arrays of bytes, with the following properties: -

-
    -
  • They are immutable: after creation, it is not possible to change the -contents of a string. -
  • No internal pointers: it is illegal to create a pointer to an inner -element of a string. -
  • They can be indexed: given string "s1", "s1[i]" is a byte value. -
  • They can be concatenated: given strings "s1" and "s2", "s1 + s2" is a value -combining the elements of "s1" and "s2" in sequence. -
  • Known length: the length of a string "s1" can be obtained by calling -"len(s1)". The length of a string is the number -of bytes within. Unlike in C, there is no terminal NUL byte. -
  • Creation 1: a string can be created from an integer value by a conversion; -the result is a string containing the UTF-8 encoding of that code point -(§Conversions). -"string('x')" yields "x"; "string(0x1234)" yields the equivalent of "\u1234" +Slicing: Given a a slice variable "a", a sub-slice is created with a slice +operation: -
  • Creation 2: a string can by created from an array of integer values (maybe -just array of bytes) by a conversion (§Conversions):
    -a [3]byte; a[0] = 'a'; a[1] = 'b'; a[2] = 'c';  string(a) == "abc";
    +a[i : j]
     
    -
+ +This creates the sub-slice consisting of the elements "a[i]" through "a[j - 1]" +(that is, excluding "a[j]"). The values "i" and "j" must satisfy the condition +"0 <= i <= j <= cap(a)". The length of the new slice is "j - i". The capacity of +the slice is "cap(a) - i"; thus if "i" is 0, the slice capacity does not change +as a result of a slice operation. The type of a sub-slice is the same as the +type of the slice. Unlike the capacity, the length of a sub-slice may be larger +than the length of the original slice. +

+Comparisons: A variable of slice type can be compared against "nil" with the +operators "==" and "!=" (§Comparison operators). The variable is +"nil" only if "nil" is assigned explicitly to the variable (§Assignments), or +if the variable has not been modified since creation (§Program initialization +and execution). -

Array types

+

Map types

-An array is a composite type consisting of a number of elements all of the -same type, called the element type. The element type must be a complete type -(§Types). The number of elements of an array is called its length; it is never -negative. The elements of an array are designated by indices -which are integers from 0 through the length - 1. +A map is a composite type consisting of a variable number of entries +called (key, value) pairs. For a given map, the keys and values must +each be of a specific complete type (§Types) called the key and value type, +respectively. The number of entries in a map is called its length; it is never +negative.
-ArrayType = "[" ArrayLength "]" ElementType .
-ArrayLength = Expression .
-ElementType = CompleteType .
+MapType = "map" "[" KeyType "]" ValueType .
+KeyType = CompleteType .
+ValueType = CompleteType .
 
-The array length and its value are part of the array type. The array length -must be a constant expression (§Constant expressions) that evaluates to an -integer value >= 0. +The comparison operators "==" and "!=" (§Comparison operators) must be defined +for operands of the key type; thus the key type must be a basic, pointer, +interface, or channel type. If the key type is an interface type, +the dynamic key types must support these comparison operators. In this case, +inserting a map value with a key that does not support testing for equality +is a run-time error.

-The number of elements of an array "a" can be discovered using the built-in -function +Upon creation, a map is empty and values may be added and removed +during execution.

-len(a)
+map [string] int
+map [*T] struct { x, y float }
+map [string] interface {}
 
-The length of arrays is known at compile-time, and the result of a call to -"len(a)" is a compile-time constant. +The length of a map "m" can be discovered using the built-in function
-[32]byte
-[2*N] struct { x, y int32 }
-[1000]*float64
+len(m)
 
-Assignment compatibility: Arrays can be assigned to variables of equal type -and to slice variables with equal element type. When assigning to a slice -variable, the array is not copied but a slice comprising the entire array -is created. +The value of an uninitialized map is "nil". A new, empty map value for given +map type M is made using the built-in function "make" which takes the map type +and an optional capacity as arguments: +
+my_map := make(M, 100);
+
-

Struct types

+The map capacity is an allocation hint for more efficient incremental growth +of the map. +

+Assignment compatibility: A map type is assignment compatible to a variable of +map type only if both types are equal. +

+Comparisons: A variable of map type can be compared against "nil" with the +operators "==" and "!=" (§Comparison operators). The variable is +"nil" only if "nil" is assigned explicitly to the variable (§Assignments), or +if the variable has not been modified since creation (§Program initialization +and execution). -A struct is a composite type consisting of a fixed number of elements, -called fields, with possibly different types. A struct type declares -an identifier and type for each field. Within a struct type no field -identifier may be declared twice and all field types must be complete -types (§Types). -

-StructType = "struct" [ "{" [ FieldDeclList ] "}" ] .
-FieldDeclList = FieldDecl { ";" FieldDecl } [ ";" ] .
-FieldDecl = (IdentifierList CompleteType | [ "*" ] TypeName) [ Tag ] .
-Tag = StringLit .
-
+

Channel types

-
-// An empty struct.
-struct {}
+A channel provides a mechanism for two concurrently executing functions
+to synchronize execution and exchange values of a specified type. This
+type must be a complete type (§Types). (TODO could it be incomplete?)
 
-// A struct with 5 fields.
-struct {
-	x, y int;
-	u float;
-	A *[]int;
-	F func();
-}
+
+ChannelType = Channel | SendChannel | RecvChannel .
+Channel = "chan" ValueType .
+SendChannel = "chan" "<-" ValueType .
+RecvChannel = "<-" "chan" ValueType .
 
-A struct may contain ``anonymous fields'', which are declared with a type -but no explicit field identifier. An anonymous field type must be specified as -a type name "T", or as a pointer to a type name ``*T'', and T itself may not be -a pointer or interface type. The unqualified type name acts as the field identifier. +Upon creation, a channel can be used both to send and to receive. +By conversion or assignment, a channel may be constrained only to send or +to receive. This constraint is called a channel's ``direction''; either +bi-directional (unconstrained), send, or receive.
-// A struct with four anonymous fields of type T1, *T2, P.T3 and *P.T4
-struct {
-	T1;        // the field name is T1
-	*T2;       // the field name is T2
-	P.T3;      // the field name is the unqualified type name T3
-	*P.T4;     // the field name is the unqualified type name T4
-	x, y int;  
-}
+chan T         // can send and receive values of type T
+chan <- float  // can only be used to send floats
+<-chan int     // can only receive ints
 
-The unqualified type name of an anonymous field must not conflict with the -field identifier (or unqualified type name for an anonymous field) of any -other field within the struct. The following declaration is illegal: +The value of an uninitialized channel is "nil". A new, initialized channel +value for a given element type T is made using the built-in function "make", +which takes the channel type and an optional capacity as arguments:
-struct {
-	T;         // conflicts with anonymous field *T and *P.T
-	*T;        // conflicts with anonymous field T and *P.T
-	*P.T;      // conflicts with anonymous field T and *T
-}
+my_chan = make(chan int, 100);
 
-Fields and methods (§Method declarations) of an anonymous field become directly -accessible as fields and methods of the struct without the need to provide the -type name of the respective anonymous field (§Selectors). +The capacity sets the size of the buffer in the communication channel. If the +capacity is greater than zero, the channel is asynchronous and, provided the +buffer is not full, sends can succeed without blocking. If the capacity is zero, +the communication succeeds only when both a sender and receiver are ready.

-A field declaration may be followed by an optional string literal tag which -becomes an ``attribute'' for all the identifiers in the corresponding -field declaration. The tags are available via the reflection library but -are ignored otherwise. A tag may contain arbitrary application-specific -information. +Assignment compatibility: A value of type channel can be assigned to a variable +of type channel only if a) both types are equal (§Type equality), or b) both +have equal channel value types and the value is a bidirectional channel. +

+Comparisons: A variable of channel type can be compared against "nil" with the +operators "==" and "!=" (§Comparison operators). The variable is +"nil" only if "nil" is assigned explicitly to the variable (§Assignments), or +if the variable has not been modified since creation (§Program initialization +and execution). +

+Two variables of channel type can be tested for equality with the +operators "==" and "!=" (§Comparison operators) if both variables have +the same ValueType. They are equal if both values were created by the same +"make" call (§Making slices, maps, and channels). -

-// A struct corresponding to the EventIdMessage protocol buffer.
-// The tag strings contain the protocol buffer field tags.
-struct {
-	time_usec uint64 "1";
-	server_ip uint32 "2";
-	process_id uint32 "3";
-}
-
-Assignment compatibility: Structs are assignment compatible to variables of -equal type only. +

Type equality

+ +

+Types may be ``different'', ``structurally equal'', or ``identical''. +Go is a type-safe language; generally different types cannot be mixed +in binary operations, and values cannot be assigned to variables of different +types. However, values may be assigned to variables of structurally +equal types. Finally, type guards succeed only if the dynamic type +is identical to or implements the type tested against (§Type guards). +

+Structural type equality (equality for short) is defined by these rules: +

+Two type names denote equal types if the types in the corresponding declarations +are equal. Two type literals specify equal types if they have the same +literal structure and corresponding components have equal types. Loosely +speaking, two types are equal if their values have the same layout in memory. +More precisely: +

+
    +
  • Two array types are equal if they have equal element types and if they + have the same array length. +
  • Two struct types are equal if they have the same number of fields in the + same order, corresponding fields either have both the same name or + are both anonymous, and corresponding field types are identical. -

    Pointer types

    +
  • Two pointer types are equal if they have equal base types. -A pointer type denotes the set of all pointers to variables of a given -type, called the ``base type'' of the pointer, and the value "nil". +
  • Two function types are equal if they have the same number of parameters + and result values and if corresponding parameter and result types are + equal (a "..." parameter is equal to another "..." parameter). + Note that parameter and result names do not have to match. -
    -PointerType = "*" BaseType .
    -BaseType = Type .
    -
    +
  • Two slice types are equal if they have equal element types. -
    -*int
    -map[string] chan
    -
    +
  • Two channel types are equal if they have equal value types and + the same direction. -The pointer base type may be denoted by an identifier referring to an -incomplete type (§Types), possibly declared via a forward declaration. -This allows the construction of recursive and mutually recursive types -such as: +
  • Two map types are equal if they have equal key and value types. -
    -type S struct { s *S }
    +	
  • Two interface types are equal if they have the same set of methods + with the same names and equal function types. Note that the order + of the methods in the respective type declarations is irrelevant. +
+ +

+Type identity is defined by these rules: +

+

+Two type names denote identical types if they originate in the same +type declaration. Two type literals specify identical types if they have the +same literal structure and corresponding components have identical types. +More precisely: +

+
    +
  • Two array types are identical if they have identical element types and if + they have the same array length. + +
  • Two struct types are identical if they have the same number of fields in + the same order, corresponding fields either have both the same name or + are both anonymous, and corresponding field types are identical. + +
  • Two pointer types are identical if they have identical base types. -type S2 struct // forward declaration of S2 -type S1 struct { s2 *S2 } -type S2 struct { s1 *S1 } -
+
  • Two function types are identical if they have the same number of + parameters and result values both with the same (or absent) names, and + if corresponding parameter and result types are identical (a "..." + parameter is identical to another "..." parameter with the same name). -Assignment compatibility: A pointer is assignment compatible to a variable -of pointer type, only if both types are equal. -

    -Comparisons: A variable of pointer type can be compared against "nil" with the -operators "==" and "!=" (§Comparison operators). The variable is -"nil" only if "nil" is assigned explicitly to the variable (§Assignments), or -if the variable has not been modified since creation (§Program initialization -and execution). -

    -Two variables of equal pointer type can be tested for equality with the -operators "==" and "!=" (§Comparison operators). The pointers are equal -if they point to the same location. +

  • Two slice types are identical if they have identical element types. -Pointer arithmetic of any kind is not permitted. +
  • Two channel types are identical if they have identical value types and + the same direction. +
  • Two map types are identical if they have identical key and value types. -

    Function types

    +
  • Two interface types are identical if they have the same set of methods + with the same names and identical function types. Note that the order + of the methods in the respective type declarations is irrelevant. + -A function type denotes the set of all functions with the same parameter -and result types, and the value "nil". +Note that the type denoted by a type name is identical only to the type literal +in the type name's declaration. +

    +Finally, two types are different if they are not structurally equal. +(By definition, they cannot be identical, either). -

    -FunctionType = "func" Signature .
    -Signature = "(" [ ParameterList ] ")" [ Result ] .
    -ParameterList = ParameterDecl { "," ParameterDecl } .
    -ParameterDecl = [ IdentifierList ] ( Type | "..." ) .
    -Result = Type | "(" ParameterList ")" .
    +For instance, given the declarations
    +
    +
    +type (
    +	T0 []string;
    +	T1 []string
    +	T2 struct { a, b int };
    +	T3 struct { a, c int };
    +	T4 func (int, float) *T0
    +	T5 func (x int, y float) *[]string
    +)
     
    -In ParameterList, the parameter names (IdentifierList) either must all be -present, or all be absent. If the parameters are named, each name stands -for one parameter of the specified type. If the parameters are unnamed, each -type stands for one parameter of that type. -

    -For the last incoming parameter only, instead of a parameter type one -may write "...". The ellipsis indicates that the last parameter stands -for an arbitrary number of additional arguments of any type (including -no additional arguments). If the parameters are named, the identifier -list immediately preceding "..." must contain only one identifier (the -name of the last parameter). +these are some types that are equal

    -func ()
    -func (x int)
    -func () int
    -func (string, float, ...)
    -func (a, b int, z float) bool
    -func (a, b int, z float) (bool)
    -func (a, b int, z float, opt ...) (success bool)
    -func (int, int, float) (float, *[]int)
    +T0 and T0
    +T0 and []string
    +T2 and T3
    +T4 and T5
    +T3 and struct { a int; int }
     
    -If the result type of a function is itself a function type, the result type -must be parenthesized to resolve a parsing ambiguity: +and these are some types that are identical
    -func (n int) (func (p* T))
    +T0 and T0
    +[]int and []int
    +struct { a, b *T5 } and struct { a, b *T5 }
     
    -Assignment compatibility: A function can be assigned to a function -variable only if both function types are equal. -

    -Comparisons: A variable of function type can be compared against "nil" with the -operators "==" and "!=" (§Comparison operators). The variable is -"nil" only if "nil" is assigned explicitly to the variable (§Assignments), or -if the variable has not been modified since creation (§Program initialization -and execution). -

    -Two variables of equal function type can be tested for equality with the -operators "==" and "!=" (§Comparison operators). The variables are equal -if they refer to the same function. +As an example, "T0" and "T1" are equal but not identical because they have +different declarations. +


    -

    Interface types

    -Type interfaces may be specified explicitly by interface types. -An interface type denotes the set of all types that implement at least -the set of methods specified by the interface type, and the value "nil". +

    Declarations and Scope

    + +

    +A declaration binds an identifier to a language entity such as +a variable or function and specifies properties such as its type. +Every identifier in a program must be declared. +

    -InterfaceType = "interface" [ "{" [ MethodSpecList ] "}" ] .
    -MethodSpecList = MethodSpec { ";" MethodSpec } [ ";" ] .
    -MethodSpec = IdentifierList Signature | TypeName .
    +Declaration = ConstDecl | TypeDecl | VarDecl | FunctionDecl | MethodDecl .
     
    + +

    +The scope of an identifier is the extent of source text within which the +identifier denotes the bound entity. No identifier may be declared twice in a +single scope, but inner blocks can declare a new entity with the same +identifier, in which case the scope created by the outer declaration excludes +that created by the inner. +

    +

    +There are levels of scoping in effect before each source file is compiled. +In order from outermost to innermost: +

    +
      +
    1. The universe scope contains all predeclared identifiers.
    2. +
    3. An implicit scope contains only the package name.
    4. +
    5. The package-level scope surrounds all declarations at the + top level of the file, that is, outside the body of any + function or method. That scope is shared across all + source files within the package (§Packages), allowing + package-level identifiers to be shared between source + files.
    6. +
    -
    -// An interface specifying a basic File type.
    -interface {
    -	Read, Write	(b Buffer) bool;
    -	Close		();
    -}
    -
    +

    +The scope of an identifier depends on the entity declared: +

    -Any type (including interface types) whose interface has, possibly as a -subset, the complete set of methods of an interface I is said to implement -interface I. For instance, if two types S1 and S2 have the methods +
      +
    1. The scope of predeclared identifiers is the universe scope.
    2. -
      -func (p T) Read(b Buffer) bool { return ... }
      -func (p T) Write(b Buffer) bool { return ... }
      -func (p T) Close() { ... }
      -
      +
    3. The scope of an (identifier denoting a) type, function or package + extends from the point of the identifier in the declaration + to the end of the innermost surrounding block.
    4. -(where T stands for either S1 or S2) then the File interface is -implemented by both S1 and S2, regardless of what other methods -S1 and S2 may have or share. +
    5. The scope of a constant or variable extends textually from + the end of the declaration to the end of the innermost + surrounding block. If the variable is declared in the + init statement of an if , for, + or switch statement, the + innermost surrounding block is the block associated + with that statement.
    6. -All types implement the empty interface: +
    7. The scope of a parameter or result is the body of the + corresponding function.
    8. -
      -interface {}
      -
      +
    9. The scope of a field or method is selectors for the + corresponding type containing the field or method (§Selectors).
    10. -In general, a type implements an arbitrary number of interfaces. -For instance, consider the interface +
    11. The scope of a label is a unique scope emcompassing + the body of the innermost surrounding function, excluding + nested functions. Labels do not conflict with variables.
    12. +
    -
    -type Lock interface {
    -	Lock, Unlock	();
    -}
    -
    +

    Predeclared identifiers

    -If S1 and S2 also implement +

    +The following identifiers are implicitly declared in the outermost scope: +

    +
    +Basic types:
    +	bool byte float32 float64 int8 int16 int32 int64 string uint8 uint16 uint32 uint64
     
    -
    -func (p T) Lock() { ... }
    -func (p T) Unlock() { ... }
    -
    +Platform-specific convenience types: + float int uint uintptr -they implement the Lock interface as well as the File interface. -

    -An interface may contain a type name T in place of a method specification. -T must denote another, complete (and not forward-declared) interface type. -Using this notation is equivalent to enumerating the methods of T explicitly -in the interface containing T. +Constants: + true false iota nil -

    -type ReadWrite interface {
    -	Read, Write	(b Buffer) bool;
    -}
    +Functions:
    +	cap convert len make new panic panicln print println typeof (TODO: typeof??)
     
    -type File interface {
    -	ReadWrite;  // same as enumerating the methods in ReadWrite
    -	Lock;       // same as enumerating the methods in Lock
    -	Close();
    -}
    +Packages:
    +	sys unsafe  (TODO: does sys endure?)
     
    -Forward declaration: -A interface type consisting of only the reserved word "interface" may be used in -a type declaration; it declares an incomplete interface type (§Type declarations). -This allows the construction of mutually recursive types such as: -
    -type T2 interface
    -type T1 interface {
    -	foo(T2) int;
    -}
    -type T2 interface {
    -	bar(T1) int;
    -}
    -
    +

    Exported identifiers

    -Assignment compatibility: A value can be assigned to an interface variable -if the static type of the value implements the interface or if the value is "nil".

    -Comparisons: A variable of interface type can be compared against "nil" with the -operators "==" and "!=" (§Comparison operators). The variable is -"nil" only if "nil" is assigned explicitly to the variable (§Assignments), or -if the variable has not been modified since creation (§Program initialization -and execution). +By default, identifiers are visible only within the package in which they are declared. +Some identifiers are exported and can be referenced using +qualified identifiers in other packages (§Qualified identifiers). +If an identifier satisfies these two conditions: +

    +
      +
    1. the first character of the identifier's name is a Unicode upper case letter; +
    2. the identifier is declared at the package level or is a field or method of a type +declared at the top level; +

    -Two variables of interface type can be tested for equality with the -operators "==" and "!=" (§Comparison operators) if both variables have the -same static type. They are equal if both their dynamic types and values are -equal. If the dynamic types are equal but the values do not support comparison, -a run-time error occurs. - +it will be exported automatically. +

    -

    Slice types

    +

    Const declarations

    -A slice type denotes the set of all slices (segments) of arrays -(§Array types) of a given element type, and the value "nil". -The number of elements of a slice is called its length; it is never negative. -The elements of a slice are designated by indices which are -integers from 0 through the length - 1. +

    +A constant declaration binds a list of identifiers (the names of +the constants) to the values of a list of constant expressions +(§Constant expressions). The number of identifiers must be equal +to the number of expressions, and the nth identifier on +the left is bound to value of the nth expression on the +right. +

    -SliceType = "[" "]" ElementType .
    -
    +ConstDecl = "const" ( ConstSpec | "(" [ ConstSpecList ] ")" ) . +ConstSpecList = ConstSpec { ";" ConstSpec } [ ";" ] . +ConstSpec = IdentifierList [ CompleteType ] [ "=" ExpressionList ] . -Syntactically and semantically, arrays and slices look and behave very -similarly, but with one important difference: A slice is a descriptor -of an array segment; in particular, different variables of a slice type may -refer to different (and possibly overlapping) segments of the same underlying -array. Thus, with respect to the underlying array, slices behave like -references. In contrast, two different variables of array type always -denote two different arrays. -

    -For slices, the actual array underlying the slice may extend past the current -slice length; the maximum length a slice may assume is called its capacity. -The capacity of any slice "a" can be discovered using the built-in function +IdentifierList = identifier { "," identifier } . +ExpressionList = Expression { "," Expression } . -

    -cap(a)
    +CompleteType = Type .
     
    -and the following relationship between "len()" and "cap()" holds: +

    +If the type (CompleteType) is omitted, the constants take the +individual types of the corresponding expressions, which may be +``ideal integer'' or ``ideal float'' (§Ideal number). If the type +is present, all constants take the type specified, and the types +of all the expressions must be assignment-compatible +with that type. +

    -0 <= len(a) <= cap(a)
    +const Pi float64 = 3.14159265358979323846
    +const E = 2.718281828
    +const (
    +	size int64 = 1024;
    +	eof = -1;
    +)
    +const a, b, c = 3, 4, "foo"  // a = 3, b = 4, c = "foo"
    +const u, v float = 0, 3      // u = 0.0, v = 3.0
     
    -The value of an uninitialized slice is "nil", and its length and capacity -are 0. A new, initialized slice value for a given element type T is -made using the built-in function "make", which takes a slice type -and parameters specifying the length and optionally the capacity: - -
    -make([]T, length)
    -make([]T, length, capacity)
    -
    - -The "make()" call allocates a new underlying array to which the returned -slice value refers. More precisely, calling "make" +

    +Within a parenthesized const declaration list the +expression list may be omitted from any but the first declaration. +Such an empty list is equivalent to the textual substitution of the +first preceding non-empty expression list. Omitting the list of +expressions is therefore equivalent to repeating the previous list. +The number of identifiers must be equal to the number of expressions +in the previous list. Together with the iota constant generator +(§Iota) this mechanism permits light-weight declaration of sequential values: +

    -make([]T, length, capacity)
    +const (
    +	Sunday = iota;
    +	Monday;
    +	Tuesday;
    +	Wednesday;
    +	Thursday;
    +	Friday;
    +	Partyday;
    +	numberOfDays;  // this constant is not exported
    +)
     
    -is effectively the same as allocating an array and slicing it -
    -new([capacity]T)[0 : length]
    -
    +

    Iota

    -Assignment compatibility: Slices are assignment compatible to variables -of the same type.

    -Indexing: Given a (pointer to) a slice variable "a", a slice element is -specified with an index operation: +Within a constant declaration, the predeclared pseudo-constant +iota represents successive integers. It is reset to 0 +whenever the reserved word const appears in the source +and increments with each semicolon. It can be used to construct a +set of related constants: +

    -a[i]
    +const (            // iota is reset to 0
    +	c0 = iota;  // c0 == 0
    +	c1 = iota;  // c1 == 1
    +	c2 = iota   // c2 == 2
    +)
    +
    +const (
    +	a = 1 << iota;  // a == 1 (iota has been reset)
    +	b = 1 << iota;  // b == 2
    +	c = 1 << iota;  // c == 4
    +)
    +
    +const (
    +	u       = iota * 42;  // u == 0     (ideal integer)
    +	v float = iota * 42;  // v == 42.0  (float)
    +	w       = iota * 42;  // w == 84    (ideal integer)
    +)
    +
    +const x = iota;  // x == 0 (iota has been reset)
    +const y = iota;  // y == 0 (iota has been reset)
     
    -This denotes the slice element at index "i". "i" must be within bounds, -that is "0 <= i < len(a)".

    -Slicing: Given a a slice variable "a", a sub-slice is created with a slice -operation: +Within an ExpressionList, the value of each iota is the same because +it is only incremented at a semicolon: +

    -a[i : j]
    +const (
    +	bit0, mask0 = 1 << iota, 1 << iota - 1;  // bit0 == 1, mask0 == 0
    +	bit1, mask1;                             // bit1 == 2, mask1 == 1
    +	bit2, mask2;                             // bit2 == 4, mask2 == 3
    +)
     
    -This creates the sub-slice consisting of the elements "a[i]" through "a[j - 1]" -(that is, excluding "a[j]"). The values "i" and "j" must satisfy the condition -"0 <= i <= j <= cap(a)". The length of the new slice is "j - i". The capacity of -the slice is "cap(a) - i"; thus if "i" is 0, the slice capacity does not change -as a result of a slice operation. The type of a sub-slice is the same as the -type of the slice. Unlike the capacity, the length of a sub-slice may be larger -than the length of the original slice.

    -Comparisons: A variable of slice type can be compared against "nil" with the -operators "==" and "!=" (§Comparison operators). The variable is -"nil" only if "nil" is assigned explicitly to the variable (§Assignments), or -if the variable has not been modified since creation (§Program initialization -and execution). +This last example exploits the implicit repetition of the +last non-empty expression list. +

    -

    Map types

    +

    Type declarations

    -A map is a composite type consisting of a variable number of entries -called (key, value) pairs. For a given map, the keys and values must -each be of a specific complete type (§Types) called the key and value type, -respectively. The number of entries in a map is called its length; it is never -negative. +

    +A type declaration binds an identifier, the type name, +to a new type. TODO: what exactly is a "new type"? +

    -MapType = "map" "[" KeyType "]" ValueType .
    -KeyType = CompleteType .
    -ValueType = CompleteType .
    +TypeDecl     = "type" ( TypeSpec | "(" [ TypeSpecList ] ")" ) .
    +TypeSpecList = TypeSpec { ";" TypeSpec } [ ";" ] .
    +TypeSpec     = identifier Type .
     
    -The comparison operators "==" and "!=" (§Comparison operators) must be defined -for operands of the key type; thus the key type must be a basic, pointer, -interface, or channel type. If the key type is an interface type, -the dynamic key types must support these comparison operators. In this case, -inserting a map value with a key that does not support testing for equality -is a run-time error. -

    -Upon creation, a map is empty and values may be added and removed -during execution. -

    -map [string] int
    -map [*T] struct { x, y float }
    -map [string] interface {}
    -
    +type IntArray [16] int -The length of a map "m" can be discovered using the built-in function +type ( + Point struct { x, y float }; + Polar Point +) -
    -len(m)
    +type TreeNode struct {
    +	left, right *TreeNode;
    +	value Point;
    +}
    +
    +type Comparable interface {
    +	cmp(Comparable) int
    +}
     
    -The value of an uninitialized map is "nil". A new, empty map value for given -map type M is made using the built-in function "make" which takes the map type -and an optional capacity as arguments: +

    Variable declarations

    + +

    +A variable declaration creates a variable, binds an identifier to it and +gives it a type and optionally an initial value. +The variable type must be a complete type (§Types). +

    +
    +VarDecl     = "var" ( VarSpec | "(" [ VarSpecList ] ")" ) .
    +VarSpecList = VarSpec { ";" VarSpec } [ ";" ] .
    +VarSpec     = IdentifierList ( CompleteType [ "=" ExpressionList ] | "=" ExpressionList ) .
    +
    -my_map := make(M, 100);
    +var i int
    +var U, V, W float
    +var k = 0
    +var x, y float = -1.0, -2.0
    +var (
    +	i int;
    +	u, v, s = 2.0, 3.0, "bar"
    +)
     
    -The map capacity is an allocation hint for more efficient incremental growth -of the map.

    -Assignment compatibility: A map type is assignment compatible to a variable of -map type only if both types are equal. +If there are expressions, their number must be equal +to the number of identifiers, and the nth variable +is initialized to the value of the nth expression. +Otherwise, each variable is initialized to the zero +of the type (§Program initialization and execution). +The expressions can be general expressions; they need not be constants. +

    -Comparisons: A variable of map type can be compared against "nil" with the -operators "==" and "!=" (§Comparison operators). The variable is -"nil" only if "nil" is assigned explicitly to the variable (§Assignments), or -if the variable has not been modified since creation (§Program initialization -and execution). +Either the type or the expression list must be present. If the +type is present, it sets the type of each variable and the expressions +(if any) must be assignment-compatible to that type. If the type +is absent, the variables take the types of the corresponding +expressions. +

    +

    +If the type is absent and the corresponding expression is a constant +expression of ideal integer or ideal float type, the type of the +declared variable is int or float +respectively: +

    +
    +var i = 0       // i has type int
    +var f = 3.1415  // f has type float
    +
    -

    Channel types

    +

    Short variable declarations

    -A channel provides a mechanism for two concurrently executing functions -to synchronize execution and exchange values of a specified type. This -type must be a complete type (§Types). (TODO could it be incomplete?) +A short variable declaration uses the syntax
    -ChannelType = Channel | SendChannel | RecvChannel .
    -Channel = "chan" ValueType .
    -SendChannel = "chan" "<-" ValueType .
    -RecvChannel = "<-" "chan" ValueType .
    +SimpleVarDecl = IdentifierList ":=" ExpressionList .
     
    -Upon creation, a channel can be used both to send and to receive. -By conversion or assignment, a channel may be constrained only to send or -to receive. This constraint is called a channel's ``direction''; either -bi-directional (unconstrained), send, or receive. +and is shorthand for the declaration syntax -
    -chan T         // can send and receive values of type T
    -chan <- float  // can only be used to send floats
    -<-chan int     // can only receive ints
    +
    +"var" IdentifierList = ExpressionList .
     
    -The value of an uninitialized channel is "nil". A new, initialized channel -value for a given element type T is made using the built-in function "make", -which takes the channel type and an optional capacity as arguments: -
    -my_chan = make(chan int, 100);
    +i, j := 0, 10;
    +f := func() int { return 7; }
    +ch := new(chan int);
     
    -The capacity sets the size of the buffer in the communication channel. If the -capacity is greater than zero, the channel is asynchronous and, provided the -buffer is not full, sends can succeed without blocking. If the capacity is zero, -the communication succeeds only when both a sender and receiver are ready. -

    -Assignment compatibility: A value of type channel can be assigned to a variable -of type channel only if a) both types are equal (§Type equality), or b) both -have equal channel value types and the value is a bidirectional channel. -

    -Comparisons: A variable of channel type can be compared against "nil" with the -operators "==" and "!=" (§Comparison operators). The variable is -"nil" only if "nil" is assigned explicitly to the variable (§Assignments), or -if the variable has not been modified since creation (§Program initialization -and execution).

    -Two variables of channel type can be tested for equality with the -operators "==" and "!=" (§Comparison operators) if both variables have -the same ValueType. They are equal if both values were created by the same -"make" call (§Making slices, maps, and channels). - +Unlike regular variable declarations, short variable declarations +can be used, by analogy with tuple assignment (§Assignments), to +receive the individual elements of a multi-valued expression such +as a call to a multi-valued function. In this form, the ExpressionLIst +must be a single such multi-valued expression, the number of +identifiers must equal the number of values, and the declared +variables will be assigned the corresponding values. +

    -

    Type equality

    +
    +count, error := os.Close(fd);  // os.Close()  returns two values
    +

    -Types may be ``different'', ``structurally equal'', or ``identical''. -Go is a type-safe language; generally different types cannot be mixed -in binary operations, and values cannot be assigned to variables of different -types. However, values may be assigned to variables of structurally -equal types. Finally, type guards succeed only if the dynamic type -is identical to or implements the type tested against (§Type guards). -

    -Structural type equality (equality for short) is defined by these rules: -

    -Two type names denote equal types if the types in the corresponding declarations -are equal. Two type literals specify equal types if they have the same -literal structure and corresponding components have equal types. Loosely -speaking, two types are equal if their values have the same layout in memory. -More precisely: +Short variable declarations may appear only inside functions. +In some contexts such as the initializers for if, +for, or switch statements, +they can be used to declare local temporary variables (§Statements).

    -
      -
    • Two array types are equal if they have equal element types and if they - have the same array length. -
    • Two struct types are equal if they have the same number of fields in the - same order, corresponding fields either have both the same name or - are both anonymous, and corresponding field types are identical. - -
    • Two pointer types are equal if they have equal base types. +

      Function declarations

      -
    • Two function types are equal if they have the same number of parameters - and result values and if corresponding parameter and result types are - equal (a "..." parameter is equal to another "..." parameter). - Note that parameter and result names do not have to match. +

      +A function declaration binds an identifier to a function (§Function types). +

      -
    • Two slice types are equal if they have equal element types. +
      +FunctionDecl = "func" identifier Signature [ Block ] .
      +
      -
    • Two channel types are equal if they have equal value types and - the same direction. +
      +func min(x int, y int) int {
      +	if x < y {
      +		return x;
      +	}
      +	return y;
      +}
      +
      -
    • Two map types are equal if they have equal key and value types. +

      +A function must be declared or forward-declared before it can be invoked (§Forward declarations). +Implementation restriction: Functions can only be declared at the package level. +

      -
    • Two interface types are equal if they have the same set of methods - with the same names and equal function types. Note that the order - of the methods in the respective type declarations is irrelevant. -
    +

    Method declarations

    -Type identity is defined by these rules: +A method declaration binds an identifier to a method, +which is a function with a receiver.

    +
    +MethodDecl = "func" Receiver identifier Signature [ Block ] .
    +Receiver = "(" [ identifier ] [ "*" ] TypeName ")" .
    +
    +

    -Two type names denote identical types if they originate in the same -type declaration. Two type literals specify identical types if they have the -same literal structure and corresponding components have identical types. -More precisely: +The receiver type must be a type name or a pointer to a type name, +and that name is called the receiver base type or just base type. +The base type must not be a pointer type and must be +declared in the same source file as the method. +The method is said to be bound to the base type +and is visible only within selectors for that type +(§Type declarations, §Selectors).

    -
      -
    • Two array types are identical if they have identical element types and if - they have the same array length. - -
    • Two struct types are identical if they have the same number of fields in - the same order, corresponding fields either have both the same name or - are both anonymous, and corresponding field types are identical. - -
    • Two pointer types are identical if they have identical base types. - -
    • Two function types are identical if they have the same number of - parameters and result values both with the same (or absent) names, and - if corresponding parameter and result types are identical (a "..." - parameter is identical to another "..." parameter with the same name). -
    • Two slice types are identical if they have identical element types. +

      +All methods bound to a base type must have the same receiver type, +either all pointers to the base type or all the base type itself. +Given type Point, the declarations +

      -
    • Two channel types are identical if they have identical value types and - the same direction. +
      +func (p *Point) Length() float {
      +	return Math.sqrt(p.x * p.x + p.y * p.y);
      +}
       
      -	
    • Two map types are identical if they have identical key and value types. +func (p *Point) Scale(factor float) { + p.x = p.x * factor; + p.y = p.y * factor; +} +
    • -
    • Two interface types are identical if they have the same set of methods - with the same names and identical function types. Note that the order - of the methods in the respective type declarations is irrelevant. -
    +

    +bind the methods Length and Scale +to the base type Point. +

    -Note that the type denoted by a type name is identical only to the type literal -in the type name's declaration.

    -Finally, two types are different if they are not structurally equal. -(By definition, they cannot be identical, either). +If the +receiver's value is not referenced inside the the body of the method, +its identifier may be omitted in the declaration. The same applies in +general to parameters of functions and methods. +

    -For instance, given the declarations +

    +Methods can be declared +only after their base type is declared or forward-declared, and invoked +only after their own declaration or forward-declaration (§Forward declarations). +Implementation restriction: They can only be declared at package level. +

    -
    -type (
    -	T0 []string;
    -	T1 []string
    -	T2 struct { a, b int };
    -	T3 struct { a, c int };
    -	T4 func (int, float) *T0
    -	T5 func (x int, y float) *[]string
    -)
    -
    +

    Forward declarations

    -these are some types that are equal +

    +Mutually-recursive types struct or interface types require that one be +forward declared so that it may be named in the other. +A forward declaration of a type omits the block containing the fields +or methods of the type. +

    -T0 and T0
    -T0 and []string
    -T2 and T3
    -T4 and T5
    -T3 and struct { a int; int }
    +type List struct  // forward declaration of List
    +type Item struct {
    +	value int;
    +	next *List;
    +}
    +type List struct {
    +	head, tail *Item
    +}
     
    - -and these are some types that are identical - +

    +A forward-declared type is incomplete (§Types) +until it is fully declared. The full declaration must follow +before the end of the block containing the forward declaration. +

    +

    +Functions and methods may similarly be forward-declared by omitting their body. +

    -T0 and T0
    -[]int and []int
    -struct { a, b *T5 } and struct { a, b *T5 }
    +func F(a int) int  // forward declaration of F
    +func G(a, b int) int {
    +	return F(a) + F(b)
    +}
    +func F(a int) int {
    +	if a <= 0 { return 0 }
    +	return G(a-1, b+1)
    +}
     
    -As an example, "T0" and "T1" are equal but not identical because they have -different declarations. -

    Expressions