Go - EBNF

Notation

The syntax is specified using Extended Backus-Naur Form (EBNF):

Production  = production_name "=" [ Expression ] "." .
Expression  = Alternative { "|" Alternative } .
Alternative = Term { Term } .
Term        = production_name | token [ "…" token ] | Group | Option | Repetition .
Group       = "(" Expression ")" .
Option      = "[" Expression "]" .
Repetition  = "{" Expression "}" .

Productions are expressions constructed from terms and the following operators, in increasing precedence:

|   alternation
()  grouping
[]  option (0 or 1 times)
{}  repetition (0 to n times)

Lower-case production names are used to identify lexical tokens. Non-terminals are in CamelCase. Lexical tokens are enclosed in double quotes "" or back quotes ``.

The form a … b represents the set of characters from a through b as alternatives. The horizontal ellipsis … is also used elsewhere in the spec to informally denote various enumerations or code snippets that are not further specified. The character … (as opposed to the three characters …) is not a token of the Go language.

Go EBNF

  • Characters

    newline        = /* the Unicode code point U+000A */ .
    unicode_char   = /* an arbitrary Unicode code point except newline */ .
    unicode_letter = /* a Unicode code point classified as "Letter" */ .
    unicode_digit  = /* a Unicode code point classified as "Number, decimal digit" */ .
    
  • Letters and digits

    letter        = unicode_letter | "_" .
    decimal_digit = "0" … "9" .
    octal_digit   = "0" … "7" .
    hex_digit     = "0" … "9" | "A" … "F" | "a" … "f" .
    
  • Identifiers

    identifier = letter { letter | unicode_digit } .
    
  • Keywords

    break        default      func         interface    select
    case         defer        go           map          struct
    chan         else         goto         package      switch
    const        fallthrough  if           range        type
    continue     for          import       return       var
    
  • Operators and Delimiters

    &     +=    &=     &&    ==    !=    (    )	   +
    |     -=    |=     ||    <     <=    [    ]	   -
    ^     *=    ^=     <-    >     >=    {    }    *
    /    <<    /=    <<=    ++    =     :=    ,    ;
    %    >>    %=    >>=    --    !     ...   .    :
    	 &^          &^=
    
  • Integer literals

    int_lit     = decimal_lit | octal_lit | hex_lit .
    decimal_lit = ( "1" … "9" ) { decimal_digit } .
    octal_lit   = "0" { octal_digit } .
    hex_lit     = "0" ( "x" | "X" ) hex_digit { hex_digit } .
    
  • Floating-point literals

    float_lit = decimals "." [ decimals ] [ exponent ] |
    	        decimals exponent |
        	    "." decimals [ exponent ] .
    decimals  = decimal_digit { decimal_digit } .
    exponent  = ( "e" | "E" ) [ "+" | "-" ] decimals .
    
  • Imaginary literals

    imaginary_lit = (decimals | float_lit) "i" .
    
  • Rune literals

    \a   U+0007 alert or bell
    \b   U+0008 backspace
    \f   U+000C form feed
    \n   U+000A line feed or newline
    \r   U+000D carriage return
    \t   U+0009 horizontal tab
    \v   U+000b vertical tab
    \\   U+005c backslash
    \'   U+0027 single quote  (valid escape only within rune literals)
    \"   U+0022 double quote  (valid escape only within string literals)
    
    rune_lit         = "'" ( unicode_value | byte_value ) "'" .
    unicode_value    = unicode_char | little_u_value | big_u_value | escaped_char .
    byte_value       = octal_byte_value | hex_byte_value .
    octal_byte_value = `\` octal_digit octal_digit octal_digit .
    hex_byte_value   = `\` "x" hex_digit hex_digit .
    little_u_value   = `\` "u" hex_digit hex_digit hex_digit hex_digit .
    big_u_value      = `\` "U" hex_digit hex_digit hex_digit hex_digit
    	                       hex_digit hex_digit hex_digit hex_digit .
    escaped_char     = `\` ( "a" | "b" | "f" | "n" | "r" | "t" | "v" | `\` | "'" | `"` ) .
    
  • String literals

    string_lit             = raw_string_lit | interpreted_string_lit .
    raw_string_lit         = "`" { unicode_char | newline } "`" .
    interpreted_string_lit = `"` { unicode_value | byte_value } `"` .
    
  • Types

    Type      = TypeName | TypeLit | "(" Type ")" .
    TypeName  = identifier | QualifiedIdent .
    TypeLit   = ArrayType | StructType | PointerType | FunctionType | InterfaceType |
    		    SliceType | MapType | ChannelType .
    
  • Numeric types

    uint8       the set of all unsigned  8-bit integers (0 to 255)
    uint16      the set of all unsigned 16-bit integers (0 to 65535)
    uint32      the set of all unsigned 32-bit integers (0 to 4294967295)
    uint64      the set of all unsigned 64-bit integers (0 to 18446744073709551615)
    
    int8        the set of all signed  8-bit integers (-128 to 127)
    int16       the set of all signed 16-bit integers (-32768 to 32767)
    int32       the set of all signed 32-bit integers (-2147483648 to 2147483647)
    int64       the set of all signed 64-bit integers (-9223372036854775808 to 9223372036854775807)
    
    float32     the set of all IEEE-754 32-bit floating-point numbers
    float64     the set of all IEEE-754 64-bit floating-point numbers
    
    complex64   the set of all complex numbers with float32 real and imaginary parts
    complex128  the set of all complex numbers with float64 real and imaginary parts
    
    byte        alias for uint8
    rune        alias for int32
    
    uint     either 32 or 64 bits
    int      same size as uint
    uintptr  an unsigned integer large enough to store the uninterpreted bits of a pointer value
    
  • Array types

    ArrayType   = "[" ArrayLength "]" ElementType .
    ArrayLength = Expression .
    ElementType = Type .
    
  • Slice types

    SliceType = "[" "]" ElementType .
    
    make([]T, length, capacity)
    make([]int, 50, 100)
    new([100]int)[0:50]
    
  • Struct types

    StructType     = "struct" "{" { FieldDecl ";" } "}" .
    FieldDecl      = (IdentifierList Type | AnonymousField) [ Tag ] .
    AnonymousField = [ "*" ] TypeName .
    Tag            = string_lit .
    
  • Pointer types

    PointerType = "*" BaseType .
    BaseType    = Type .
    
  • Function types

    FunctionType   = "func" Signature .
    Signature      = Parameters [ Result ] .
    Result         = Parameters | Type .
    Parameters     = "(" [ ParameterList [ "," ] ] ")" .
    ParameterList  = ParameterDecl { "," ParameterDecl } .
    ParameterDecl  = [ IdentifierList ] [ "..." ] Type .
    
  • Interface types

    InterfaceType      = "interface" "{" { MethodSpec ";" } "}" .
    MethodSpec         = MethodName Signature | InterfaceTypeName .
    MethodName         = identifier .
    InterfaceTypeName  = TypeName .
    
  • Map types

    MapType     = "map" "[" KeyType "]" ElementType .
    KeyType     = Type .
    
  • Channel types

    ChannelType = ( "chan" | "chan" "<-" | "<-" "chan" ) ElementType .
    
    chan T          // can be used to send and receive values of type T
    chan<- float64  // can only be used to send float64s
    <-chan int      // can only be used to receive ints
    
    chan<- chan int    // same as chan<- (chan int)
    chan<- <-chan int  // same as chan<- (<-chan int)
    <-chan <-chan int  // same as <-chan (<-chan int)
    chan (<-chan int)
    
    make(chan int, 100)
    
  • Type identity

    Two types are either identical or different.

    Two named types are identical if their type names originate in the same TypeSpec. A named and an unnamed type are always different. Two unnamed types are identical if the corresponding type literals are identical, that is, if they have the same literal structure and corresponding components have identical types. In detail:

    1. Two array types are identical if they have identical element types and the same array length.
    2. Two slice types are identical if they have identical element types.
    3. Two struct types are identical if they have the same sequence of fields, and if corresponding fields have the same names, and identical types, and identical tags. Two anonymous fields are considered to have the same name. Lower-case field names from different packages are always different.
    4. Two pointer types are identical if they have identical base types.
    5. Two function types are identical if they have the same number of parameters and result values, corresponding parameter and result types are identical, and either both functions are variadic or neither is. Parameter and result names are not required to match.
    6. Two interface types are identical if they have the same set of methods with the same names and identical function types. Lower-case method names from different packages are always different. The order of the methods is irrelevant.
    7. Two map types are identical if they have identical key and value types.
    8. Two channel types are identical if they have identical value types and the same direction.
  • Assignability

    A value x is assignable to a variable of type T (“x is assignable to T”) in any of these cases:

    1. x’s type is identical to T.
    2. x’s type V and T have identical underlying types and at least one of V or T is not a named type.
    3. T is an interface type and x implements T.
    4. x is a bidirectional channel value, T is a channel type, x’s type V and T have identical element types, and at least one of V or T is not a named type.
    5. x is the predeclared identifier nil and T is a pointer, function, slice, map, channel, or interface type.
    6. x is an untyped constant representable by a value of type T.
  • Blocks

    Block = "{" StatementList "}" .
    StatementList = { Statement ";" } .
    
  • Declarations and scope

    Declaration   = ConstDecl | TypeDecl | VarDecl .
    TopLevelDecl  = Declaration | FunctionDecl | MethodDecl .
    
  • Predeclared identifiers

    Types:
    	bool byte complex64 complex128 error float32 float64
    	int int8 int16 int32 int64 rune string
    	uint uint8 uint16 uint32 uint64 uintptr
    
    Constants:
    	true false iota
    
    Zero value:
    	nil
    
    Functions:
    	append cap close complex copy delete imag len
    	make new panic print println real recover
    
  • Exported identifiers

    An identifier may be exported to permit access to it from another package. An identifier is exported if both:

    1. the first character of the identifier’s name is a Unicode upper case letter (Unicode class “Lu”); and
    2. the identifier is declared in the package block or it is a field name or method name. All other identifiers are not exported.
  • Uniqueness of identifiers

    Given a set of identifiers, an identifier is called unique if it is different from every other in the set. Two identifiers are different if they are spelled differently, or if they appear in different packages and are not exported. Otherwise, they are the same.

  • Constant declarations

    ConstDecl      = "const" ( ConstSpec | "(" { ConstSpec ";" } ")" ) .
    ConstSpec      = IdentifierList [ [ Type ] "=" ExpressionList ] .
    
    IdentifierList = identifier { "," identifier } .
    ExpressionList = Expression { "," Expression } .
    
  • Iota Within a constant declaration, the predeclared identifier iota represents successive untyped integer constants. It is reset to 0 whenever the reserved word const appears in the source and increments after each ConstSpec. It can be used to construct a set of related constants:

    const ( // iota is reset to 0
    	c0 = iota  // c0 == 0
    	c1 = iota  // c1 == 1
    	c2 = iota  // c2 == 2
    )
    
    const ( // iota is reset to 0
    	a = 1 << iota  // a == 1
    	b = 1 << iota  // b == 2
    	c = 3          // c == 3  (iota is not used but still incremented)
    	d = 1 << iota  // d == 8
    )
    
    const ( // iota is reset to 0
    	u         = iota * 42  // u == 0     (untyped integer constant)
    	v float64 = iota * 42  // v == 42.0  (float64 constant)
    	w         = iota * 42  // w == 84    (untyped integer constant)
    )
    
    const x = iota  // x == 0  (iota has been reset)
    const y = iota  // y == 0  (iota has been reset)
    
    const (
    	bit0, mask0 = 1 << iota, 1<<iota - 1  // bit0 == 1, mask0 == 0
    	bit1, mask1                           // bit1 == 2, mask1 == 1
    	_, _                                  // skips iota == 2
    	bit3, mask3                           // bit3 == 8, mask3 == 7
    )
    
  • Type declarations

    TypeDecl     = "type" ( TypeSpec | "(" { TypeSpec ";" } ")" ) .
    TypeSpec     = identifier Type .
    
    type IntArray [16]int
    
    type (
    	Point struct{ x, y float64 }
    	Polar Point
    )
    
    type TreeNode struct {
    	left, right *TreeNode
    	value *Comparable
    }
    
    type Block interface {
    	BlockSize() int
    	Encrypt(src, dst []byte)
    	Decrypt(src, dst []byte)
    }
    

    The declared type does not inherit any methods bound to the existing type, but the method set of an interface type or of elements of a composite type remains unchanged:

    // A Mutex is a data type with two methods, Lock and Unlock.
    type Mutex struct         { /* Mutex fields */ }
    func (m *Mutex) Lock()    { /* Lock implementation */ }
    func (m *Mutex) Unlock()  { /* Unlock implementation */ }
    
    // NewMutex has the same composition as Mutex but its method set is empty.
    type NewMutex Mutex
    
    // The method set of the base type of PtrMutex remains unchanged,
    // but the method set of PtrMutex is empty.
    type PtrMutex *Mutex
    
    // The method set of *PrintableMutex contains the methods
    // Lock and Unlock bound to its anonymous field Mutex.
    type PrintableMutex struct {
    	Mutex
    }
    
    // MyBlock is an interface type that has the same method set as Block.
    type MyBlock Block
    

    A type declaration may be used to define a different boolean, numeric, or string type and attach methods to it:

    type TimeZone int
    
    const (
    	EST TimeZone = -(5 + iota)
    	CST
    	MST
    	PST
    )
    
    func (tz TimeZone) String() string {
    	return fmt.Sprintf("GMT%+dh", tz)
    }
    
  • Variable declarations

    VarDecl     = "var" ( VarSpec | "(" { VarSpec ";" } ")" ) .
    VarSpec     = IdentifierList ( Type [ "=" ExpressionList ] | "=" ExpressionList ) .
    
  • Short variable declarations

    ShortVarDecl = IdentifierList ":=" ExpressionList .
    

    It is shorthand for a regular variable declaration with initializer expressions but no types:

    "var" IdentifierList = ExpressionList .
    
    i, j := 0, 10
    f := func() int { return 7 }
    ch := make(chan int)
    r, w := os.Pipe(fd)  // os.Pipe() returns two values
    _, y, _ := coord(p)  // coord() returns three values; only interested in y coordinate
    

    Unlike regular variable declarations, a short variable declaration may redeclare variables provided they were originally declared earlier in the same block (or the parameter lists if the block is the function body) with the same type, and at least one of the non-blank variables is new. As a consequence, redeclaration can only appear in a multi-variable short declaration. Redeclaration does not introduce a new variable; it just assigns a new value to the original.

    field1, offset := nextField(str, 0)
    field2, offset := nextField(str, offset)  // redeclares offset
    a, a := 1, 2       // illegal: double declaration of a or no new variable if a was declared elsewhere
    

    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.

  • Function declarations

    FunctionDecl = "func" FunctionName ( Function | Signature ) .
    FunctionName = identifier .
    Function     = Signature FunctionBody .
    FunctionBody = Block .
    
  • Method declarations

    MethodDecl   = "func" Receiver MethodName ( Function | Signature ) .
    Receiver     = Parameters .
    
  • Operands

    Operand     = Literal | OperandName | MethodExpr | "(" Expression ")" .
    Literal     = BasicLit | CompositeLit | FunctionLit .
    BasicLit    = int_lit | float_lit | imaginary_lit | rune_lit | string_lit .
    OperandName = identifier | QualifiedIdent.
    
  • Qualified identifiers

    QualifiedIdent = PackageName "." identifier .
    
  • Composite literals

    CompositeLit  = LiteralType LiteralValue .
    LiteralType   = StructType | ArrayType | "[" "..." "]" ElementType |
    	            SliceType | MapType | TypeName .
    LiteralValue  = "{" [ ElementList [ "," ] ] "}" .
    ElementList   = KeyedElement { "," KeyedElement } .
    KeyedElement  = [ Key ":" ] Element .
    Key           = FieldName | Expression | LiteralValue .
    FieldName     = identifier .
    Element       = Expression | LiteralValue .
    
  • Function literals

    FunctionLit = "func" Function .
    
  • Primary expressions

    PrimaryExpr =
    	Operand |
    	Conversion |
    	PrimaryExpr Selector |
    	PrimaryExpr Index |
    	PrimaryExpr Slice |
    	PrimaryExpr TypeAssertion |
    	PrimaryExpr Arguments .
    
    Selector       = "." identifier .
    Index          = "[" Expression "]" .
    Slice          = "[" ( [ Expression ] ":" [ Expression ] ) |
                      ( [ Expression ] ":" Expression ":" Expression )
    	             "]" .
    TypeAssertion  = "." "(" Type ")" .
    Arguments      = "(" [ ( ExpressionList | Type [ "," ExpressionList ] ) [ "..." ] [ "," ] ] ")" .
    
  • Selectors

    For a primary expression x that is not a package name, the selector expression

    x.f
    

    denotes the field or method f of the value x (or sometimes *x; see below). The identifier f is called the (field or method) selector; it must not be the blank identifier. The type of the selector expression is the type of f. If x is a package name, see the section on qualified identifiers.

    A selector f may denote a field or method f of a type T, or it may refer to a field or method f of a nested anonymous field of T. The number of anonymous fields traversed to reach f is called its depth in T. The depth of a field or method f declared in T is zero. The depth of a field or method f declared in an anonymous field A in T is the depth of f in A plus one.

    The following rules apply to selectors:

    1. For a value x of type T or *T where T is not a pointer or interface type, x.f denotes the field or method at the shallowest depth in T where there is such an f. If there is not exactly one f with shallowest depth, the selector expression is illegal.
    2. For a value x of type I where I is an interface type, x.f denotes the actual method with name f of the dynamic value of x. If there is no method with name f in the method set of I, the selector expression is illegal.
    3. As an exception, if the type of x is a named pointer type and (*x).f is a valid selector expression denoting a field (but not a method), x.f is shorthand for (*x).f.
    4. In all other cases, x.f is illegal.
    5. If x is of pointer type and has the value nil and x.f denotes a struct field, assigning to or evaluating x.f causes a run-time panic.
    6. If x is of interface type and has the value nil, calling or evaluating the method x.f causes a run-time panic.
  • Method expressions

    MethodExpr    = ReceiverType "." MethodName .
    ReceiverType  = TypeName | "(" "*" TypeName ")" | "(" ReceiverType ")" .
    
  • Index expressions

    a[x]
    
  • Slice expressions

    a[low : high]
    
    a[low : high : max]
    
  • Type assertions

    x.(T)
    
  • Calls

    f(a1, a2, … an)
    
  • Passing arguments to … parameters

    Given the function and calls

    func Greeting(prefix string, who ...string)
    Greeting("nobody")
    Greeting("hello:", "Joe", "Anna", "Eileen")
    

    Given the slice s and call

    s := []string{"James", "Jasmine"}
    Greeting("goodbye:", s...)
    
  • Operators

    Expression = UnaryExpr | Expression binary_op Expression .
    UnaryExpr  = PrimaryExpr | unary_op UnaryExpr .
    
    binary_op  = "||" | "&&" | rel_op | add_op | mul_op .
    rel_op     = "==" | "!=" | "<" | "<=" | ">" | ">=" .
    add_op     = "+" | "-" | "|" | "^" .
    mul_op     = "*" | "/" | "%" | "<<" | ">>" | "&" | "&^" .
    
    unary_op   = "+" | "-" | "!" | "^" | "*" | "&" | "<-" .
    
  • Operator precedence

    Precedence    Operator
    5             *  /  %  <<  >>  &  &^
    4             +  -  |  ^
    3             ==  !=  <  <=  >  >=
    2             &&
    1             ||
    
  • Arithmetic operators

    +    sum                    integers, floats, complex values, strings
    -    difference             integers, floats, complex values
    *    product                integers, floats, complex values
    /    quotient               integers, floats, complex values
    %    remainder              integers
    
    &    bitwise AND            integers
    |    bitwise OR             integers
    ^    bitwise XOR            integers
    &^   bit clear (AND NOT)    integers
    
    <<   left shift             integer << unsigned integer
    >>   right shift            integer >> unsigned integer
    
  • Comparison operators

    ==    equal
    !=    not equal
    <     less
    <=    less or equal
    >     greater
    >=    greater or equal
    
  • Logical operators

    &&    conditional AND    p && q  is  "if p then q else false"
    ||    conditional OR     p || q  is  "if p then true else q"
    !     NOT                !p      is  "not p"
    
  • Address operators

    &x
    &a[f(2)]
    &Point{2, 3}
    *p
    *pf(x)
    
    var x *int = nil
    *x   // causes a run-time panic
    &*x  // causes a run-time panic
    
  • Receive operator

    v1 := <-ch
    v2 = <-ch
    f(<-ch)
    <-strobe  // wait until clock pulse and discard received value
    
    x, ok = <-ch
    x, ok := <-ch
    var x, ok = <-ch
    
  • Conversions

    Conversion = Type "(" Expression [ "," ] ")" .
    
  • Statements

    Statement =
    	Declaration | LabeledStmt | SimpleStmt |
    	GoStmt | ReturnStmt | BreakStmt | ContinueStmt | GotoStmt |
    	FallthroughStmt | Block | IfStmt | SwitchStmt | SelectStmt | ForStmt |
    	DeferStmt .
    
    SimpleStmt = EmptyStmt | ExpressionStmt | SendStmt | IncDecStmt | Assignment | ShortVarDecl .
    
  • Empty statements

    EmptyStmt = .
    
  • Labeled statements

    LabeledStmt = Label ":" Statement .
    Label       = identifier .
    
  • Expression statements

    ExpressionStmt = Expression .
    

    The following built-in functions are not permitted in statement context:

    append cap complex imag len make new real
    unsafe.Alignof unsafe.Offsetof unsafe.Sizeof
    
  • Send statements

    SendStmt = Channel "<-" Expression .
    Channel  = Expression .
    
  • IncDec statements

    IncDecStmt = Expression ( "++" | "--" ) .
    
  • Assignments

    Assignment = ExpressionList assign_op ExpressionList .
    
    assign_op = [ add_op | mul_op ] "=" .
    
  • If statements

    IfStmt = "if" [ SimpleStmt ";" ] Expression Block [ "else" ( IfStmt | Block ) ] .
    
  • Switch statements

    SwitchStmt = ExprSwitchStmt | TypeSwitchStmt .
    
  • Expression switches

    ExprSwitchStmt = "switch" [ SimpleStmt ";" ] [ Expression ] "{" { ExprCaseClause } "}" .
    ExprCaseClause = ExprSwitchCase ":" StatementList .
    ExprSwitchCase = "case" ExpressionList | "default" .
    
  • Type switches

    switch x.(type) {
    // cases
    }
    
    TypeSwitchStmt  = "switch" [ SimpleStmt ";" ] TypeSwitchGuard "{" { TypeCaseClause } "}" .
    TypeSwitchGuard = [ identifier ":=" ] PrimaryExpr "." "(" "type" ")" .
    TypeCaseClause  = TypeSwitchCase ":" StatementList .
    TypeSwitchCase  = "case" TypeList | "default" .
    TypeList        = Type { "," Type } .
    
  • For statements

    ForStmt = "for" [ Condition | ForClause | RangeClause ] Block .
    Condition = Expression .
    
    ForClause = [ InitStmt ] ";" [ Condition ] ";" [ PostStmt ] .
    InitStmt = SimpleStmt .
    PostStmt = SimpleStmt .
    
    RangeClause = [ ExpressionList "=" | IdentifierList ":=" ] "range" Expression .
    
    Range expression                          1st value          2nd value
    
    array or slice  a  [n]E, *[n]E, or []E    index    i  int    a[i]       E
    string          s  string type            index    i  int    see below  rune
    map             m  map[K]V                key      k  K      m[k]       V
    channel         c  chan E, <-chan E       element  e  E
    
  • Go statements

    GoStmt = "go" Expression .
    
  • Select statements

    SelectStmt = "select" "{" { CommClause } "}" .
    CommClause = CommCase ":" StatementList .
    CommCase   = "case" ( SendStmt | RecvStmt ) | "default" .
    RecvStmt   = [ ExpressionList "=" | IdentifierList ":=" ] RecvExpr .
    RecvExpr   = Expression .
    
  • Return statements

    ReturnStmt = "return" [ ExpressionList ] .
    
  • Break statements

    BreakStmt = "break" [ Label ] .
    
  • Continue statements

    ContinueStmt = "continue" [ Label ] .
    
  • Goto statements

    GotoStmt = "goto" Label .
    
  • Fallthrough statements

    FallthroughStmt = "fallthrough" .
    
  • Defer statements

    DeferStmt = "defer" Expression .
    
  • Source file organization

    SourceFile       = PackageClause ";" { ImportDecl ";" } { TopLevelDecl ";" } .
    
  • Package clause

    PackageClause  = "package" PackageName .
    PackageName    = identifier .
    
  • Import declarations

    ImportDecl       = "import" ( ImportSpec | "(" { ImportSpec ";" } ")" ) .
    ImportSpec       = [ "." | PackageName ] ImportPath .
    ImportPath       = string_lit .
    
    Import declaration          Local name of Sin
    
    import   "lib/math"         math.Sin
    import m "lib/math"         m.Sin
    import . "lib/math"         Sin
    
    import _ "lib/math"
    
  • Size and alignment guarantees

    For the numeric types, the following sizes are guaranteed:

    type                                 size in bytes
    
    byte, uint8, int8                     1
    uint16, int16                         2
    uint32, int32, float32                4
    uint64, int64, float64, complex64     8
    complex128                           16
    

    The following minimal alignment properties are guaranteed:

    • For a variable x of any type: unsafe.Alignof(x) is at least 1.
    • 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.
    • For a variable x of array type: unsafe.Alignof(x) is the same as unsafe.Alignof(x[0]), but at least 1.

    A struct or array type has size zero if it contains no fields (or elements, respectively) that have a size greater than zero. Two distinct zero-size variables may have the same address in memory.


(Note: The Go Programming Language Specification is here )

 Makefile:简介 爱 

Comments