lang-spec
Rune 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
The value of a raw string literal is the string composed of the uninterpreted (implicitly UTF-8-encoded) characters between the quotes; in particular, backslashes have no special meaning and the string may contain newlines
string_lit = raw_string_lit | interpreted_string_lit .
raw_string_lit = "`" { unicode_char | newline } "`" .
interpreted_string_lit = `"` { unicode_value | byte_value } `"` .
Constants
Numeric constants represent exact values of arbitrary precision and do not overflow
An untyped constant has a default type which is the type to which the constant is implicitly converted in contexts where a typed value is required
The default type of an untyped constant is bool, rune, int, float64, complex128, or string respectively, depending on whether it is a boolean, rune, integer, floating-point, complex, or string constant
Variables
The static type (or just type) of a variable is the type given in its declaration, the type provided in the new call or composite literal, or the type of an element of a structured variable. Variables of interface type also have a distinct dynamic type, which is the (non-interface) type of the value assigned to the variable at run time
Types
A type may also be specified using a type literal, which composes a type from existing types
Type = TypeName [ TypeArgs ] | TypeLit | "(" Type ")" .
TypeName = identifier | QualifiedIdent .
TypeArgs = "[" TypeList [ "," ] "]" .
TypeList = Type { "," Type } .
TypeLit = ArrayType | StructType | PointerType | FunctionType | InterfaceType |
SliceType | MapType | ChannelType .
Numeric types
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
String types
Strings are immutable: once created, it is impossible to change the contents of a string
Array types
An array is a numbered sequence of elements of a single type, called the element type
Slice types
make([]T, length, capacity)
make([]int, 50, 100)
new([100]int)[0:50]
Struct types
StructType = "struct" "{" { FieldDecl ";" } "}" .
FieldDecl = (IdentifierList Type | EmbeddedField) [ Tag ] .
EmbeddedField = [ "*" ] TypeName [ TypeArgs ] .
Tag = string_lit .
Function types
Within a list of parameters or results, the names (IdentifierList) must either all be present or all be absent
Parameter and result lists are always parenthesized except that if there is exactly one unnamed result it may be written as an unparenthesized type
The final incoming parameter in a function signature may have a type prefixed with .... A function with such a parameter is called variadic and may be invoked with zero or more arguments for that parameter
Interface types
InterfaceType = "interface" "{" { InterfaceElem ";" } "}" .
InterfaceElem = MethodElem | TypeElem .
MethodElem = MethodName Signature .
MethodName = identifier .
TypeElem = TypeTerm { "|" TypeTerm } .
TypeTerm = Type | UnderlyingType .
UnderlyingType = "~" Type .
Basic interfaces
Interfaces whose type sets can be defined entirely by a list of methods are called basic interfaces
Embedded interfaces
type ReadWriter interface {
Reader // includes methods of Reader in ReadWriter's method set
Writer // includes methods of Writer in ReadWriter's method set
}
General interfaces
- The type set of the empty interface is the set of all non-interface types.
- The type set of a non-empty interface is the intersection of the type sets of its interface elements.
- The type set of a method specification is the set of all non-interface types whose method sets include that method.
- The type set of a non-interface type term is the set consisting of just that type.
- The type set of a term of the form ~T is the set of all types whose underlying type is T.
- The type set of a union of terms t1|t2|…|tn is the union of the type sets of the terms.
Interfaces that are not basic may only be used as type constraints, or as elements of other interfaces used as constraints. They cannot be the types of values or variables, or components of other, non-interface types
var x Float // illegal: Float is not a basic interface
var x interface{} = Float(nil) // illegal
type Floatish struct {
f Float // illegal
}
Map types
A map is an unordered group of elements of one type, called the element type, indexed by a set of unique keys of another type, called the key type
A nil map is equivalent to an empty map except that no elements may be added
Channel types
ChannelType = ( "chan" | "chan" "<-" | "<-" "chan" ) ElementType .
The optional <-
operator specifies the channel direction, send or receive. If a direction is given, the channel is directional, otherwise it is bidirectional
A nil channel is never ready for communication
Properties of types and values
Underlying types
Each type T has an underlying type: If T is one of the predeclared boolean, numeric, or string types, or a type literal, the corresponding underlying type is T itself. Otherwise, T's underlying type is the underlying type of the type to which T refers in its declaration
Type identity
A named type is always different from any other type. Otherwise, two types are identical if their underlying type literals are structurally equivalent
Assignability
A value x of type V is assignable to a variable of type T ("x is assignable to T") if one of the following conditions applies:
- V and T are identical.
- V and T have identical underlying types but are not type parameters and at least one of V or T is not a named type.
- V and T are channel types with identical element types, V is a bidirectional channel, and at least one of V or T is not a named type.
- T is an interface type, but not a type parameter, and x implements T.
- x is the predeclared identifier nil and T is a pointer, function, slice, map, channel, or interface type, but not a type parameter.
- x is an untyped constant representable by a value of type T
Blocks
In addition to explicit blocks in the source code, there are implicit blocks:
- The universe block encompasses all Go source text.
- Each package has a package block containing all Go source text for that package.
- Each file has a file block containing all Go source text in that file.
- Each "if", "for", and "switch" statement is considered to be in its own implicit block.
- Each clause in a "switch" or "select" statement acts as an implicit block
Constant declarations
Within a parenthesized const declaration list the expression list may be omitted from any but the first ConstSpec. Such an empty list is equivalent to the textual substitution of the first preceding non-empty expression list and its type if any. Omitting the list of expressions is therefore equivalent to repeating the previous list
Type declarations
TypeDecl = "type" ( TypeSpec | "(" { TypeSpec ";" } ")" ) .
TypeSpec = AliasDecl | TypeDef .
Alias declarations
AliasDecl = identifier "=" Type .
Type definitions
TypeDef = identifier [ TypeParameters ] Type .
The new type is called a defined type. It is different from any other type, including the type it is created from
type (
Point struct{ x, y float64 } // Point and struct{ x, y float64 } are different types
polar Point // polar and Point denote different types
)
A defined type may have methods associated with it. It does not inherit any methods bound to the given type, but the method set of an interface type or of elements of a composite type remains unchanged
Type parameter declarations
TypeParameters = "[" TypeParamList [ "," ] "]" .
TypeParamList = TypeParamDecl { "," TypeParamDecl } .
TypeParamDecl = IdentifierList TypeConstraint .
The predeclared interface type comparable denotes the set of all non-interface types that are strictly comparable
Short variable declarations
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
Short variable declarations may appear only inside functions
Function declarations
A function declaration without type parameters may omit the body. Such a declaration provides the signature for a function implemented outside Go, such as an assembly routine
Method declarations
A receiver base type cannot be a pointer or interface type and it must be defined in the same package as the method. The method is said to be bound to its receiver base type and the method name is visible only within selectors for type T or *T.
Expressions
An expression specifies the computation of a value by applying operators and functions to operands