diff --git a/doc/go_spec.html b/doc/go_spec.html index 483a1e68c5b..f3a52b970a5 100644 --- a/doc/go_spec.html +++ b/doc/go_spec.html @@ -126,13 +126,6 @@ Closed: [x] func literal like a composite type - should probably require the '&' to get address (NO) [x] & needed to get a function pointer from a function? (NO - there is the "func" keyword - 9/19/08) -Timeline (9/5/08): -- threads: 1 month -- reflection code: 2 months -- proto buf support: 3 months -- GC: 6 months -- debugger -- Jan 1, 2009: enough support to write interesting programs -->

Introduction

@@ -186,13 +179,13 @@ operators, in increasing precedence:

Lower-case production names are used to identify lexical tokens. Non-terminals are in CamelCase. Lexical symbols are enclosed in -double quotes "" (the double quote symbol is written as -'"'). +double quotes "" (the double quote symbol is written as +'"').

-The form "a ... b" represents the set of characters from -a through b as alternatives. +The form "a ... b" represents the set of characters from +a through b as alternatives.

@@ -232,7 +225,7 @@ The following terms are used to denote specific Unicode character classes:

Letters and digits

-The underscore character _ (U+005F) is considered a letter. +The underscore character _ (U+005F) is considered a letter.

 letter        = unicode_letter | "_" .
@@ -248,9 +241,9 @@ hex_digit     = "0" ... "9" | "A" ... "F" | "a" ... "f" .
 
 

There are two forms of comments. The first starts at the character -sequence // and continues through the next newline. The -second starts at the character sequence /* and continues -through the character sequence */. Comments do not nest. +sequence // and continues through the next newline. The +second starts at the character sequence /* and continues +through the character sequence */. Comments do not nest.

Tokens

@@ -276,11 +269,6 @@ The first character in an identifier must be a letter.
 identifier    = letter { letter | unicode_digit } .
 
-

-Exported identifiers (§Exported identifiers) start with a capital_letter. -
-TODO: This sentence feels out of place. -

 a
 _x9
@@ -320,9 +308,9 @@ The following character sequences represent operators, delimiters, and other spe
 

An integer literal is a sequence of one or more digits in the corresponding base, which may be 8, 10, or 16. An optional prefix -sets a non-decimal base: 0 for octal, 0x or -0X for hexadecimal. In hexadecimal literals, letters -a-f and A-F represent values 10 through 15. +sets a non-decimal base: 0 for octal, 0x or +0X for hexadecimal. In hexadecimal literals, letters +a-f and A-F represent values 10 through 15.

 int_lit       = decimal_lit | octal_lit | hex_lit .
@@ -343,7 +331,7 @@ hex_lit       = "0" ( "x" | "X" ) hex_digit { hex_digit } .
 A floating-point literal is a decimal representation of a floating-point
 number.  It has an integer part, a decimal point, a fractional part,
 and an exponent part.  The integer and fractional part comprise
-decimal digits; the exponent part is an e or E
+decimal digits; the exponent part is an e or E
 followed by an optionally signed decimal exponent.  One of the
 integer part or the fractional part may be elided; one of the decimal
 point or the exponent may be elided.
@@ -398,18 +386,18 @@ values in various formats.
 The simplest form represents the single character within the quotes;
 since Go source text is Unicode characters encoded in UTF-8, multiple
 UTF-8-encoded bytes may represent a single integer value.  For
-instance, the literal 'a' holds a single byte representing
-a literal a, Unicode U+0061, value 0x61, while
-'ä' holds two bytes (0xc3 0xa4) representing
-a literal a-dieresis, U+00E4, value 0xe4.
+instance, the literal 'a' holds a single byte representing
+a literal a, Unicode U+0061, value 0x61, while
+'ä' holds two bytes (0xc3 0xa4) representing
+a literal a-dieresis, U+00E4, value 0xe4.
 

Several backslash escapes allow arbitrary values to be represented as ASCII text. There are four ways to represent the integer value -as a numeric constant: \x followed by exactly two hexadecimal -digits; \u followed by exactly four hexadecimal digits; -\U followed by exactly eight hexadecimal digits, and a -plain backslash \ followed by exactly three octal digits. +as a numeric constant: \x followed by exactly two hexadecimal +digits; \u followed by exactly four hexadecimal digits; +\U followed by exactly eight hexadecimal digits, and a +plain backslash \ followed by exactly three octal digits. In each case the value of the literal is the value represented by the digits in the corresponding base.

@@ -417,9 +405,9 @@ the digits in the corresponding base. Although these representations all result in an integer, they have different valid ranges. Octal escapes must represent a value between 0 and 255 inclusive. (Hexadecimal escapes satisfy this condition -by construction). The `Unicode' escapes \u and \U +by construction). The `Unicode' escapes \u and \U represent Unicode code points so within them some values are illegal, -in particular those above 0x10FFFF and surrogate halves. +in particular those above 0x10FFFF and surrogate halves.

After a backslash, certain single-character escapes represent special values: @@ -472,30 +460,30 @@ integer literals.

String literals

-String literals represent constant values of type string. +String literals represent constant values of type string. There are two forms: raw string literals and interpreted string literals.

Raw string literals are character sequences between back quotes -``. Within the quotes, any character is legal except +``. Within the quotes, any character is legal except newline and back quote. The value of a raw string literal is the string composed of the uninterpreted bytes between the quotes; in particular, backslashes have no special meaning.

Interpreted string literals are character sequences between double -quotes "". The text between the quotes forms the +quotes "". The text between the quotes forms the value of the literal, with backslash escapes interpreted as they -are in character literals (except that \' is illegal and -\" is legal). The three-digit octal (\000) -and two-digit hexadecimal (\x00) escapes represent individual +are in character literals (except that \' is illegal and +\" is legal). The three-digit octal (\000) +and two-digit hexadecimal (\x00) escapes represent individual bytes of the resulting string; all other escapes represent the (possibly multi-byte) UTF-8 encoding of individual characters. -Thus inside a string literal \377 and \xFF represent -a single byte of value 0xFF=255, while ÿ, -\u00FF, \U000000FF and \xc3\xbf represent -the two bytes 0xc3 0xbf of the UTF-8 encoding of character +Thus inside a string literal \377 and \xFF represent +a single byte of value 0xFF=255, while ÿ, +\u00FF, \U000000FF and \xc3\xbf represent +the two bytes 0xc3 0xbf of the UTF-8 encoding of character U+00FF.

@@ -550,129 +538,140 @@ literal.


-

Declarations and scope rules

+

Declarations and Scope

-A declaration ``binds'' an identifier to a language entity (such as -a package, constant, type, struct field, variable, parameter, result, -function, method) and specifies properties of that entity such as its type. +

+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 .
 
-Every identifier in a program must be declared; some identifiers, such as "int" -and "true", are predeclared (§Predeclared identifiers).

-The ``scope'' of an identifier is the extent of source text within which the +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. Go is lexically scoped: An identifier denotes the entity it is -bound to only within the scope of the identifier. +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. +

-For instance, for a variable named "x", the scope of identifier "x" is the -extent of source text within which "x" denotes that particular variable. -It is illegal to declare another identifier "x" within the same scope. +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. The scope for -an identifier always excludes scopes redeclaring the identifier in nested -blocks. An identifier declared in a nested block is said to ``shadow'' the -same identifier declared in an outer block. +The scope of an identifier depends on the entity declared: +

    -
  1. The scope of predeclared identifiers is the entire source file. +
  2. The scope of predeclared identifiers is the universe scope.
  3. -
  4. The scope of an identifier denoting a type, function or package - extends textually from the point of the identifier in the declaration - to the end of the innermost surrounding block. +
  5. 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.
  6. The scope of a constant or variable extends textually from - after 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 the respective statement. + 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.
  7. -
  8. The scope of a parameter or result identifier is the body of the - corresponding function. +
  9. The scope of a parameter or result is the body of the + corresponding function.
  10. -
  11. The scope of a field or method identifier is selectors for the - corresponding type containing the field or method (§Selectors). - -
  12. The scope of a label is the body of the innermost surrounding - function and does not intersect with any non-label scope. Thus, - each function has its own private label scope. +
  13. The scope of a field or method is selectors for the + corresponding type containing the field or method (§Selectors).
  14. + +
  15. 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.

Predeclared identifiers

-The following identifiers are predeclared: -

- -

-All basic types: +The following identifiers are implicitly declared in the outermost scope:

-bool, byte, uint8, uint16, uint32, uint64, int8, int16, int32, int64,
-float32, float64, string
-
- -A set of platform-specific convenience types: +Basic types: + bool byte float32 float64 int8 int16 int32 int64 string uint8 uint16 uint32 uint64 -
-uint, int, float, uintptr
-
- -The predeclared constants: +Platform-specific convenience types: + float int uint uintptr -
-true, false, iota, nil
-
- -The predeclared functions (note: this list is likely to change): +Constants: + true false iota nil -
-cap(), convert(), len(), make(), new(), panic(), panicln(), print(), println(), typeof(), ...
+Functions:
+	cap convert len make new panic panicln print println typeof (TODO: typeof??)
+
+Packages:
+	sys unsafe  (TODO: does sys endure?)
 

Exported identifiers

-Identifiers that start with a capital_letter (§Identifiers) are ``exported'', -thus making the identifiers accessible outside the current package. A file -belonging to another package may then import the package (§Packages) and access -exported identifiers via qualified identifiers (§Qualified identifiers).

-All other identifiers are ``internal''; they are only visible in files -belonging to the same package which declares them. +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; +

- -TODO: This should be made clearer. For instance, function-local identifiers -are never exported, but non-global fields/methods may be exported. - - +it will be exported automatically. +

Const declarations

-A constant declaration binds an identifier to the value of a constant -expression (§Constant expressions). +

+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 ] .
+ConstDecl      = "const" ( ConstSpec | "(" [ ConstSpecList ] ")" ) .
+ConstSpecList  = ConstSpec { ";" ConstSpec } [ ";" ] .
+ConstSpec      = IdentifierList [ CompleteType ] [ "=" ExpressionList ] .
 
 IdentifierList = identifier { "," identifier } .
 ExpressionList = Expression { "," Expression } .
+
+CompleteType = Type .
 
-A constant declaration binds a list of identifiers (the names of the constants) -to the values of a list of constant expressions. The number of identifiers must -be equal to the number of expressions, with the i'th identifier on the left -corresponding to the i'th expression on the right. If CompleteType is omitted, -the types of the constants are the types of the corresponding expressions; -different expressions may have different types. If CompleteType is present, -the type of all constants is the type specified, and the types of all -expressions in ExpressionList must be assignment-compatible with the -constant 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
@@ -685,16 +684,16 @@ 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
 
-As a special case, within a parenthesized "const" declaration list the -ExpressionList may be omitted from any but the first declaration. Such an empty -ExpressionList is equivalent to the textual substitution of the first preceding -non-empty ExpressionList in the same "const" declaration list. -That is, omitting the list of expressions is 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 implicit repetition of -ExpressionLists permit light-weight declaration of enumerated values (§Iota): +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 (
@@ -705,61 +704,26 @@ const (
 	Thursday;
 	Friday;
 	Partyday;
-	numberOfDays;  // this constant in not exported
+	numberOfDays;  // this constant is not exported
 )
 
-The initializing expression for a numeric constant is evaluated -using the principles described in the section on numeric literals: -constants are mathematical values given a size only upon assignment -to a variable. Intermediate values, and the constants themselves, -may require precision significantly larger than any concrete type -in the language. Thus the following is legal: - -
-const Huge = 1 << 100;
-const Four int8 = Huge >> 98;
-
- -A given numeric constant expression is, however, defined to be -either an integer or a floating point value, depending on the syntax -of the literals it comprises (123 vs. 1.0e4). This is because the -nature of the arithmetic operations depends on the type of the -values; for example, 3/2 is an integer division yielding 1, while -3./2. is a floating point division yielding 1.5. Thus - -
-const x = 3./2. + 3/2;
-
- -yields a floating point constant of value 2.5 (1.5 + 1); its -constituent expressions are evaluated using different rules for -division. -

-If the type is missing from a numeric constant declaration, the constant -represents a value of abitrary precision, either integer or floating -point, determined by the type of the initializing expression. Such -a constant may be assigned to any variable that can represent its -value accurately, regardless of type. For instance, 3 can be -assigned to any integer variable but also to any floating point variable, -while 1e12 can be assigned to a "float32", "float64", or even "int64". -It is erroneous to assign a value with a non-zero fractional part -to an integer, or if the assignment would overflow or underflow. -

Iota

-Within a constant declaration, the predeclared operand "iota" represents -successive elements of an integer sequence. It is reset to 0 whenever the -reserved word "const" appears in the source and increments with each -semicolon. For instance, "iota" can be used to construct a set of related -constants: +

+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 set to 0
-	enum0 = iota;  // sets enum0 to 0, etc.
-	enum1 = iota;
-	enum2 = iota
+const (            // iota is reset to 0
+	c0 = iota;  // c0 == 0
+	c1 = iota;  // c1 == 1
+	c2 = iota   // c2 == 2
 )
 
 const (
@@ -778,63 +742,38 @@ const x = iota;  // x == 0 (iota has been reset)
 const y = iota;  // y == 0 (iota has been reset)
 
-Within an ExpressionList, the value of all "iota"'s is the same because "iota" -is only incremented at each semicolon: +

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

 const (
-	base0, mask0 int64 = 1 << iota, i << iota - 1;  // base0 == 1, mask0 = 0
-	base1, mask1 int64 = 1 << iota, i << iota - 1;  // base1 == 2, mask1 = 1
-	base2, mask2 int64 = 1 << iota, i << iota - 1;  // base2 == 4, mask2 = 3
+	bit0, mask0 = 1 << iota, 1 << iota - 1;  // bit0 == 1, mask0 == 0
+	bit1, mask1;                             // bit1 == 2, mask1 == 1
+	bit2, mask2;                             // bit2 == 4, mask2 == 3
 )
 
-Since the ExpressionList in constant declarations repeats implicitly -if omitted, some of the examples above can be abbreviated: - -
-const (
-	enum0 = iota;
-	enum1;
-	enum2
-)
-
-const (
-	a = 1 << iota;
-	b;
-	c;
-)
-
-const (
-	u = iota * 42;
-	v float;
-	w;
-)
-
-const (
-	base0, mask0 int64 = 1 << iota, i << iota - 1;
-	base1, mask1 int64;
-	base2, mask2 int64;
-)
-
+

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

Type declarations

-A type declaration specifies a new type and binds an identifier to it. -The identifier is called the ``type name''; it denotes the type. +

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

-TypeDecl = "type" ( TypeSpec | "(" [ TypeSpecList ] ")" ) .
+TypeDecl     = "type" ( TypeSpec | "(" [ TypeSpecList ] ")" ) .
 TypeSpecList = TypeSpec { ";" TypeSpec } [ ";" ] .
-TypeSpec = identifier Type .
+TypeSpec     = identifier Type .
 
-A struct or interface type may be forward-declared (§Struct types, -§Interface types). A forward-declared type is incomplete (§Types) -until it is fully declared. The full declaration must must follow -within the same block containing the forward declaration. -
 type IntArray [16] int
 
@@ -853,19 +792,17 @@ type Comparable interface {
 }
 
-

Variable declarations

+

A variable declaration creates a variable, binds an identifier to it and -gives it a type. It may optionally give the variable an initial value. +gives it a type and optionally an initial value. The variable type must be a complete type (§Types). -In some forms of declaration the type of the initial value defines the type -of the variable. - +

-VarDecl = "var" ( VarSpec | "(" [ VarSpecList ] ")" ) .
+VarDecl     = "var" ( VarSpec | "(" [ VarSpecList ] ")" ) .
 VarSpecList = VarSpec { ";" VarSpec } [ ";" ] .
-VarSpec = IdentifierList ( CompleteType [ "=" ExpressionList ] | "=" ExpressionList ) .
+VarSpec     = IdentifierList ( CompleteType [ "=" ExpressionList ] | "=" ExpressionList ) .
 
@@ -879,30 +816,42 @@ var (
 )
 
-If the expression list is present, it must have the same number of elements -as there are variables in the variable specification.

-If the variable type is omitted, an initialization expression (or expression -list) must be present, and the variable type is the type of the expression -value (in case of a list of variables, the variables assume the types of the -corresponding expression values). +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. +

-If the variable type is omitted, and the corresponding initialization expression -is a constant expression of abstract int or floating point type, the type -of the variable is "int" or "float" respectively: +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 int type
-var f = 3.1415  // f has float type
+var i = 0       // i has type int
+var f = 3.1415  // f has type float
 
-The syntax +

Short variable declarations

+ +A short variable declaration uses the syntax
 SimpleVarDecl = IdentifierList ":=" ExpressionList .
 
-is shorthand for +and is shorthand for the declaration syntax
 "var" IdentifierList = ExpressionList .
@@ -913,9 +862,146 @@ i, j := 0, 10;
 f := func() int { return 7; }
 ch := new(chan int);
 
- -Also, in some contexts such as "if", "for", or "switch" statements, -this construct can be used to declare local temporary variables. + +

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

@@ -952,10 +1038,6 @@ type of a pointer type, may be incomplete). Incomplete types are subject to usag restrictions; for instance the type of a variable must be complete where the variable is declared. -
-CompleteType = Type .
-
- 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; @@ -1185,17 +1267,6 @@ struct { }
-Forward declaration: -A struct type consisting of only the reserved word "struct" may be used in -a type declaration; it declares an incomplete struct type (§Type declarations). -This allows the construction of mutually recursive types such as: - -
-type S2 struct // forward declaration of S2
-type S1 struct { s2 *S2 }
-type S2 struct { s1 *S1 }
-
- Assignment compatibility: Structs are assignment compatible to variables of equal type only. @@ -2637,19 +2708,54 @@ to "false" otherwise.

Constant expressions

-A constant expression is an expression whose operands are all constants -(§Constants). Additionally, the result of the predeclared functions -below (with appropriate arguments) is also constant: +

+Constant expressions may contain only constants, iota, +numeric literals, string literals, and +some constant-valued built-in functions such as unsafe.Sizeof +and len applied to an array. +In practice, constant expressions are those that can be evaluated at compile time. +

+The type of a constant expression is determined by the type of its +elements. If it contains only numeric literals, its type is ``ideal +integer'' or ``ideal float'' (§Ideal number). Whether it is an +integer or float depends on whether the value can be represented +precisely as an integer (123 vs. 1.23). The nature of the arithmetic +operations within the expression depends, elementwise, on the values; +for example, 3/2 is an integer division yielding 1, while 3./2. is +a floating point division yielding 1.5. Thus +

-len(a)		if a is an array (as opposed to an array slice)
+const x = 3./2. + 3/2;
 
- -TODO: Complete this list as needed. -

-Constant expressions can be evaluated at compile time. +yields a floating point constant of ideal float value 2.5 (1.5 + +1); its constituent expressions are evaluated using distinct rules +for division. +

+ +

+Intermediate values and the constants themselves +may require precision significantly larger than any concrete type +in the language. The following are legal declarations: +

+ +
+const Huge = 1 << 100;
+const Four int8 = Huge >> 98;
+
+ +

+A constant expression may appear in any context, such as assignment +to a variable of any numeric type, as long as the value of the +expression can be represented accurately in that context. For +instance, 3 can be assigned to any integer variable but also to any +floating point variable, while 1e12 can be assigned to a +float32, float64, or even int64. +It is erroneous to assign a value with a non-zero fractional part +to an integer, or if the assignment would overflow or underflow. +


@@ -2680,7 +2786,7 @@ StatementList = Statement { OptSemicolon Statement } . A semicolon may be omitted immediately following:

-An import statement makes the exported top-level identifiers of the named +An import statement makes the exported package-level identifiers of the named package file accessible to this package.

In the following discussion, assume we have a package in the @@ -3711,75 +3743,76 @@ When main.main() returns, the program exits.


-

Systems considerations

+

System considerations

-

Package unsafe

+

Package unsafe

-The built-in package "unsafe", known to the compiler, provides facilities -for low-level programming including operations that violate the Go type -system. A package using "unsafe" must be vetted manually for type safety.

-The package "unsafe" provides (at least) the following package interface: +The built-in package unsafe, known to the compiler, provides facilities +for low-level programming including operations that violate the type +system. A package using unsafe must be vetted manually for type safety. +The package provides the following interface: +

 package unsafe
 
 const Maxalign int
 
-type Pointer *any
+type Pointer *any  // "any" is shorthand for any Go type; it is not a real type.
 
 func Alignof(variable any) int
 func Offsetof(selector any) int
 func Sizeof(variable any) int
 
-The pseudo type "any" stands for any Go type; "any" is not a type generally -available in Go programs.

-Any pointer type as well as values of type "uintptr" can be converted into -an "unsafe.Pointer" and vice versa. +Any pointer or value of type uintptr can be converted into +a Pointer and vice versa. +

-The function "Sizeof" takes an expression denoting a variable of any type -and returns the size of the variable in bytes. +The function Sizeof takes an expression denoting a +variable of any type and returns the size of the variable in bytes. +

-The function "Offsetof" takes a selector (§Selectors) denoting a struct +The function Offsetof takes a selector (§Selectors) denoting a struct field of any type and returns the field offset in bytes relative to the -struct address. Specifically, the following condition is satisfied for -a struct "s" with field "f": +struct's address. For a struct s with field f: +

-uintptr(unsafe.Pointer(&s)) + uintptr(unsafe.Offsetof(s.f)) ==
-uintptr(unsafe.Pointer(&s.f))
+uintptr(unsafe.Pointer(&s)) + uintptr(unsafe.Offsetof(s.f)) == uintptr(unsafe.Pointer(&s.f))
 
-Computer architectures may impose restrictions on the memory addresses accessed -directly by machine instructions. A common such restriction is the requirement -for such addresses to be ``aligned''; that is, addresses must be a multiple -of a factor, the ``alignment''. The alignment depends on the type of datum -accessed.

-The function "Alignof" takes an expression denoting a variable of any type -and returns the alignment of the variable in bytes. The following alignment -condition is satisfied for a variable "x": +Computer architectures may require memory addresses to be aligned; +that is, for addresses of a variable to be a multiple of a factor, +the variable's type's alignment. The function Alignof +takes an expression denoting a variable of any type and returns the +alignment of the (type of the) variable in bytes. For a variable +x: +

 uintptr(unsafe.Pointer(&x)) % uintptr(unsafe.Alignof(x)) == 0
 
-The maximum alignment is given by the constant "unsafe.Maxalign". -It usually corresponds to the value of "unsafe.Sizeof(x)" for -a variable "x" of the largest arithmetic type (8 for a float64), but may -be smaller on systems that have less stringent alignment restrictions -or are space constrained.

-The results of calls to "unsafe.Alignof", "unsafe.Offsetof", and -"unsafe.Sizeof" are compile-time constants. +The maximum alignment is given by the constant Maxalign. +It usually corresponds to the value of Sizeof(x) for +a variable x of the largest arithmetic type (8 for a +float64), but may +be smaller on systems with weaker alignment restrictions. +

+

+Calls to Alignof, Offsetof, and +Sizeof are constant expressions of type int. +

Size and alignment guarantees

-For the arithmetic types (§Arithmetic types), a Go compiler guarantees the -following sizes: +For the arithmetic types (§Arithmetic types), the following sizes are guaranteed:
 type                      size in bytes
@@ -3791,19 +3824,19 @@ uint64, int64, float64    8
 

-A Go compiler guarantees the following minimal alignment properties: +The following minimal alignment properties are guaranteed:

    -
  1. For a variable "x" of any type: "1 <= unsafe.Alignof(x) <= unsafe.Maxalign". +
  2. For a variable x of any type: 1 <= unsafe.Alignof(x) <= unsafe.Maxalign. -
  3. For a variable "x" of arithmetic type: "unsafe.Alignof(x)" is the smaller - of "unsafe.Sizeof(x)" and "unsafe.Maxalign", but at least 1. +
  4. For a variable x of arithmetic type: unsafe.Alignof(x) is the smaller + of unsafe.Sizeof(x) and unsafe.Maxalign, but at least 1. -
  5. For a variable "x" of struct type: "unsafe.Alignof(x)" is the largest of - all the values "unsafe.Alignof(x.f)" for each field "f" of x, but at least 1. +
  6. For a variable x of struct type: unsafe.Alignof(x) is the largest of + all the values unsafe.Alignof(x.f) for each field f of x, but at least 1. -
  7. For a variable "x" of array type: "unsafe.Alignof(x)" is the same as - unsafe.Alignof(x[0]), but at least 1. +
  8. For a variable x of array type: unsafe.Alignof(x) is the same as + unsafe.Alignof(x[0]), but at least 1.