From f27e9f072d006d1378864f1c4af8fd2f960c14f3 Mon Sep 17 00:00:00 2001
From: Rob Pike
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 form "a ... b" represents the set of characters from
-a through b as alternatives.
+The form
@@ -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
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
-Exported identifiers (§Exported identifiers) start with a capital_letter.
-
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:
R=gri
DELTA=664 (222 added, 189 deleted, 253 changed)
OCL=25294
CL=25352
---
doc/go_spec.html | 811 ++++++++++++++++++++++++-----------------------
1 file changed, 422 insertions(+), 389 deletions(-)
diff --git a/doc/go_spec.html b/doc/go_spec.html
index 483a1e68c5..f3a52b970a 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:
""
(the double quote symbol is written as
+'"'
).
"a ... b"
represents the set of characters from
+a
through b
as alternatives.
Letters and digits
_
(U+005F) is considered a letter.
>
letter = unicode_letter | "_" .
@@ -248,9 +241,9 @@ hex_digit = "0" ... "9" | "A" ... "F" | "a" ... "f" .
//
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 } .
-
-TODO: This sentence feels out of place.
-
a
_x9
@@ -320,9 +308,9 @@ The following character sequences represent operators, delimiters, and other spe
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.
\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 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.
+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 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: +
if
, for
,
+ or switch
statement, the
+ innermost surrounding block is the block associated
+ with that statement.-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?)
-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: +
+- -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. +
+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. -
+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. +
+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 { }-
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. +
++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 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:
+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 +
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).
+
+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. +
+ ++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. +
+ ++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) +} +
-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 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; ++ +
+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;- -TODO: Complete this list as needed. -
-Constant expressions can be evaluated at compile time.
+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.
+
-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.