From a9ed30ff377976b9e2fd7fb4a897ffda71649474 Mon Sep 17 00:00:00 2001 From: Rob Pike Date: Mon, 23 Feb 2009 19:26:07 -0800 Subject: [PATCH] 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 --- doc/go_spec.html | 935 ++++++++++++++++++++++++----------------------- 1 file changed, 468 insertions(+), 467 deletions(-) diff --git a/doc/go_spec.html b/doc/go_spec.html index f3a52b970a5..32ac34e3db2 100644 --- a/doc/go_spec.html +++ b/doc/go_spec.html @@ -538,473 +538,6 @@ literal.


-

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

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

-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. - -
  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. - -
  7. The scope of a parameter or result is the body of the - corresponding function.
  8. - -
  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. -
- -

Predeclared identifiers

- -

-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
-
-Constants:
-	true false iota nil
-
-Functions:
-	cap convert len make new panic panicln print println typeof (TODO: typeof??)
-
-Packages:
-	sys unsafe  (TODO: does sys endure?)
-
- - -

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

- -

Const declarations

- -

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

- -
-ConstDecl      = "const" ( ConstSpec | "(" [ ConstSpecList ] ")" ) .
-ConstSpecList  = ConstSpec { ";" ConstSpec } [ ";" ] .
-ConstSpec      = IdentifierList [ CompleteType ] [ "=" ExpressionList ] .
-
-IdentifierList = identifier { "," identifier } .
-ExpressionList = Expression { "," Expression } .
-
-CompleteType = Type .
-
- -

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

-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: -

- -
-const (
-	Sunday = iota;
-	Monday;
-	Tuesday;
-	Wednesday;
-	Thursday;
-	Friday;
-	Partyday;
-	numberOfDays;  // this constant is not exported
-)
-
- - -

Iota

- -

-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: -

- -
-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)
-
- -

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

- -
-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 last example exploits the implicit repetition of the -last non-empty expression list. -

- - -

Type declarations

- -

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

- -
-TypeDecl     = "type" ( TypeSpec | "(" [ TypeSpecList ] ")" ) .
-TypeSpecList = TypeSpec { ";" TypeSpec } [ ";" ] .
-TypeSpec     = identifier Type .
-
- -
-type IntArray [16] int
-
-type (
-	Point struct { x, y float };
-	Polar Point
-)
-
-type TreeNode struct {
-	left, right *TreeNode;
-	value Point;
-}
-
-type Comparable interface {
-	cmp(Comparable) int
-}
-
- -

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 ) .
-
- -
-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"
-)
-
- -

-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: -

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

Short variable declarations

- -A short variable declaration uses the syntax - -
-SimpleVarDecl = IdentifierList ":=" ExpressionList .
-
- -and is shorthand for the declaration syntax - -
-"var" IdentifierList = ExpressionList .
-
- -
-i, j := 0, 10;
-f := func() int { return 7; }
-ch := new(chan int);
-
- -

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

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

-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

- -

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

- -
-FunctionDecl = "func" identifier Signature [ Block ] .
-
- -
-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. -

- -

Method declarations

- -

-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 ")" .
-
- -

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

- -
-func (p *Point) Length() float {
-	return Math.sqrt(p.x * p.x + p.y * p.y);
-}
-
-func (p *Point) Scale(factor float) {
-	p.x = p.x * factor;
-	p.y = p.y * factor;
-}
-
- -

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

- -

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

- -

-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

- -

-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 List struct  // forward declaration of List
-type Item struct {
-	value int;
-	next *List;
-}
-type List struct {
-	head, tail *Item
-}
-
-

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

-
-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)
-}
-
- -
-

Types

A type specifies the set of values that variables of that type may assume @@ -1803,6 +1336,474 @@ different declarations.
+ +

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

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

+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. + +
  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. + +
  7. The scope of a parameter or result is the body of the + corresponding function.
  8. + +
  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. +
+ +

Predeclared identifiers

+ +

+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
+
+Constants:
+	true false iota nil
+
+Functions:
+	cap convert len make new panic panicln print println typeof (TODO: typeof??)
+
+Packages:
+	sys unsafe  (TODO: does sys endure?)
+
+ + +

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

+ +

Const declarations

+ +

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

+ +
+ConstDecl      = "const" ( ConstSpec | "(" [ ConstSpecList ] ")" ) .
+ConstSpecList  = ConstSpec { ";" ConstSpec } [ ";" ] .
+ConstSpec      = IdentifierList [ CompleteType ] [ "=" ExpressionList ] .
+
+IdentifierList = identifier { "," identifier } .
+ExpressionList = Expression { "," Expression } .
+
+CompleteType = Type .
+
+ +

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

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

+ +
+const (
+	Sunday = iota;
+	Monday;
+	Tuesday;
+	Wednesday;
+	Thursday;
+	Friday;
+	Partyday;
+	numberOfDays;  // this constant is not exported
+)
+
+ + +

Iota

+ +

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

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

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

+ +
+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 last example exploits the implicit repetition of the +last non-empty expression list. +

+ + +

Type declarations

+ +

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

+ +
+TypeDecl     = "type" ( TypeSpec | "(" [ TypeSpecList ] ")" ) .
+TypeSpecList = TypeSpec { ";" TypeSpec } [ ";" ] .
+TypeSpec     = identifier Type .
+
+ +
+type IntArray [16] int
+
+type (
+	Point struct { x, y float };
+	Polar Point
+)
+
+type TreeNode struct {
+	left, right *TreeNode;
+	value Point;
+}
+
+type Comparable interface {
+	cmp(Comparable) int
+}
+
+ +

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

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

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

Short variable declarations

+ +A short variable declaration uses the syntax + +
+SimpleVarDecl = IdentifierList ":=" ExpressionList .
+
+ +and is shorthand for the declaration syntax + +
+"var" IdentifierList = ExpressionList .
+
+ +
+i, j := 0, 10;
+f := func() int { return 7; }
+ch := new(chan int);
+
+ +

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

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

+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

+ +

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

+ +
+FunctionDecl = "func" identifier Signature [ Block ] .
+
+ +
+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. +

+ +

Method declarations

+ +

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

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

+ +
+func (p *Point) Length() float {
+	return Math.sqrt(p.x * p.x + p.y * p.y);
+}
+
+func (p *Point) Scale(factor float) {
+	p.x = p.x * factor;
+	p.y = p.y * factor;
+}
+
+ +

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

+ +

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

+ +

+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

+ +

+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 List struct  // forward declaration of List
+type Item struct {
+	value int;
+	next *List;
+}
+type List struct {
+	head, tail *Item
+}
+
+

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

+
+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)
+}
+
+ +
+

Expressions

An expression specifies the computation of a value via the application of