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 -->
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:
-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 speAn 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
andA-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-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: - -e
orE
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 literala
, Unicode U+0061, value0x61
, while +'ä'
holds two bytes (0xc3
0xa4
) representing +a literala
-dieresis, U+00E4, value0xe4
.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:
@@ -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\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.\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 above0x10FFFF
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
@@ -550,129 +538,140 @@ literal.""
. 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 value0xFF
=255, whileÿ
, +\u00FF
,\U000000FF
and\xc3\xbf
represent +the two bytes0xc3 0xbf
of the UTF-8 encoding of character U+00FF.
-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: +
++
+- The universe scope contains all predeclared identifiers.
+- An implicit scope contains only the package name.
+- 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.
+-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: +
-
- The scope of predeclared identifiers is the entire source file. +
- The scope of predeclared identifiers is the universe scope.
-- 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. +
- 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.
- 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
, + orswitch
statement, the + innermost surrounding block is the block associated + with that statement.- The scope of a parameter or result identifier is the body of the - corresponding function. +
- The scope of a parameter or result is the body of the + corresponding function.
-- The scope of a field or method identifier is selectors for the - corresponding type containing the field or method (§Selectors). - -
- 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. +
- The scope of a field or method is selectors for the + corresponding type containing the field or method (§Selectors).
+ +- 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: +
++
- the first character of the identifier's name is a Unicode upper case letter; +
- 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 theiota
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 wordconst
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
orfloat
+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 syntaxSimpleVarDecl = 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
, orswitch
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
andScale
+to the base typePoint
. ++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 { }-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 asunsafe.Sizeof
+andlen
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 evenint64
. +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:
-FunctionDecl = "func" identifier Signature [ Block ] . -- -
-func min(x int, y int) int { - if x < y { - return x; - } - return y; -} -- -A function declaration without a block serves as a forward declaration: - -
-func MakeNode(left, right *Node) *Node -- - -Implementation restrictions: Functions can only be declared at the global level. -A function must be declared or forward-declared before it can be invoked. - - -
-MethodDecl = "func" Receiver identifier Signature [ Block ] . -Receiver = "(" [ identifier ] [ "*" ] TypeName ")" . -- -All methods bound to a receiver base type must have the same receiver type: -Either all receiver types are pointers to the base type or they are the base -type. -(TODO: This restriction can be relaxed at the cost of more complicated -assignment rules to interface types). - - -For instance, 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 receiver base type "Point". - -Method declarations may appear anywhere after the declaration of the receiver -base type and may be forward-declared. - - -
In the following discussion, assume we have a package in the @@ -3711,75 +3743,76 @@ When main.main() returns, the program exits.
unsafe
-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
.
+
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:
x
of any type: 1 <= unsafe.Alignof(x) <= unsafe.Maxalign
.
-x
of arithmetic type: unsafe.Alignof(x)
is the smaller
+ of unsafe.Sizeof(x)
and unsafe.Maxalign
, but at least 1.
-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.
-x
of array type: unsafe.Alignof(x)
is the same as
+ unsafe.Alignof(x[0])
, but at least 1.