From 43a123c1ae6613b3efeed291fa552ecd909d3acf Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Tue, 16 Apr 2024 21:23:18 +0200 Subject: Adding upstream version 1.20.14. Signed-off-by: Daniel Baumann --- doc/asm.html | 1056 +++++++ doc/go1.17_spec.html | 6858 +++++++++++++++++++++++++++++++++++++++++ doc/go1.20.html | 1246 ++++++++ doc/go_mem.html | 965 ++++++ doc/go_spec.html | 8296 ++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 18421 insertions(+) create mode 100644 doc/asm.html create mode 100644 doc/go1.17_spec.html create mode 100644 doc/go1.20.html create mode 100644 doc/go_mem.html create mode 100644 doc/go_spec.html (limited to 'doc') diff --git a/doc/asm.html b/doc/asm.html new file mode 100644 index 0000000..f7787a4 --- /dev/null +++ b/doc/asm.html @@ -0,0 +1,1056 @@ + + +

A Quick Guide to Go's Assembler

+ +

+This document is a quick outline of the unusual form of assembly language used by the gc Go compiler. +The document is not comprehensive. +

+ +

+The assembler is based on the input style of the Plan 9 assemblers, which is documented in detail +elsewhere. +If you plan to write assembly language, you should read that document although much of it is Plan 9-specific. +The current document provides a summary of the syntax and the differences with +what is explained in that document, and +describes the peculiarities that apply when writing assembly code to interact with Go. +

+ +

+The most important thing to know about Go's assembler is that it is not a direct representation of the underlying machine. +Some of the details map precisely to the machine, but some do not. +This is because the compiler suite (see +this description) +needs no assembler pass in the usual pipeline. +Instead, the compiler operates on a kind of semi-abstract instruction set, +and instruction selection occurs partly after code generation. +The assembler works on the semi-abstract form, so +when you see an instruction like MOV +what the toolchain actually generates for that operation might +not be a move instruction at all, perhaps a clear or load. +Or it might correspond exactly to the machine instruction with that name. +In general, machine-specific operations tend to appear as themselves, while more general concepts like +memory move and subroutine call and return are more abstract. +The details vary with architecture, and we apologize for the imprecision; the situation is not well-defined. +

+ +

+The assembler program is a way to parse a description of that +semi-abstract instruction set and turn it into instructions to be +input to the linker. +If you want to see what the instructions look like in assembly for a given architecture, say amd64, there +are many examples in the sources of the standard library, in packages such as +runtime and +math/big. +You can also examine what the compiler emits as assembly code +(the actual output may differ from what you see here): +

+ +
+$ cat x.go
+package main
+
+func main() {
+	println(3)
+}
+$ GOOS=linux GOARCH=amd64 go tool compile -S x.go        # or: go build -gcflags -S x.go
+"".main STEXT size=74 args=0x0 locals=0x10
+	0x0000 00000 (x.go:3)	TEXT	"".main(SB), $16-0
+	0x0000 00000 (x.go:3)	MOVQ	(TLS), CX
+	0x0009 00009 (x.go:3)	CMPQ	SP, 16(CX)
+	0x000d 00013 (x.go:3)	JLS	67
+	0x000f 00015 (x.go:3)	SUBQ	$16, SP
+	0x0013 00019 (x.go:3)	MOVQ	BP, 8(SP)
+	0x0018 00024 (x.go:3)	LEAQ	8(SP), BP
+	0x001d 00029 (x.go:3)	FUNCDATA	$0, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
+	0x001d 00029 (x.go:3)	FUNCDATA	$1, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
+	0x001d 00029 (x.go:3)	FUNCDATA	$2, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
+	0x001d 00029 (x.go:4)	PCDATA	$0, $0
+	0x001d 00029 (x.go:4)	PCDATA	$1, $0
+	0x001d 00029 (x.go:4)	CALL	runtime.printlock(SB)
+	0x0022 00034 (x.go:4)	MOVQ	$3, (SP)
+	0x002a 00042 (x.go:4)	CALL	runtime.printint(SB)
+	0x002f 00047 (x.go:4)	CALL	runtime.printnl(SB)
+	0x0034 00052 (x.go:4)	CALL	runtime.printunlock(SB)
+	0x0039 00057 (x.go:5)	MOVQ	8(SP), BP
+	0x003e 00062 (x.go:5)	ADDQ	$16, SP
+	0x0042 00066 (x.go:5)	RET
+	0x0043 00067 (x.go:5)	NOP
+	0x0043 00067 (x.go:3)	PCDATA	$1, $-1
+	0x0043 00067 (x.go:3)	PCDATA	$0, $-1
+	0x0043 00067 (x.go:3)	CALL	runtime.morestack_noctxt(SB)
+	0x0048 00072 (x.go:3)	JMP	0
+...
+
+ +

+The FUNCDATA and PCDATA directives contain information +for use by the garbage collector; they are introduced by the compiler. +

+ +

+To see what gets put in the binary after linking, use go tool objdump: +

+ +
+$ go build -o x.exe x.go
+$ go tool objdump -s main.main x.exe
+TEXT main.main(SB) /tmp/x.go
+  x.go:3		0x10501c0		65488b0c2530000000	MOVQ GS:0x30, CX
+  x.go:3		0x10501c9		483b6110		CMPQ 0x10(CX), SP
+  x.go:3		0x10501cd		7634			JBE 0x1050203
+  x.go:3		0x10501cf		4883ec10		SUBQ $0x10, SP
+  x.go:3		0x10501d3		48896c2408		MOVQ BP, 0x8(SP)
+  x.go:3		0x10501d8		488d6c2408		LEAQ 0x8(SP), BP
+  x.go:4		0x10501dd		e86e45fdff		CALL runtime.printlock(SB)
+  x.go:4		0x10501e2		48c7042403000000	MOVQ $0x3, 0(SP)
+  x.go:4		0x10501ea		e8e14cfdff		CALL runtime.printint(SB)
+  x.go:4		0x10501ef		e8ec47fdff		CALL runtime.printnl(SB)
+  x.go:4		0x10501f4		e8d745fdff		CALL runtime.printunlock(SB)
+  x.go:5		0x10501f9		488b6c2408		MOVQ 0x8(SP), BP
+  x.go:5		0x10501fe		4883c410		ADDQ $0x10, SP
+  x.go:5		0x1050202		c3			RET
+  x.go:3		0x1050203		e83882ffff		CALL runtime.morestack_noctxt(SB)
+  x.go:3		0x1050208		ebb6			JMP main.main(SB)
+
+ +

Constants

+ +

+Although the assembler takes its guidance from the Plan 9 assemblers, +it is a distinct program, so there are some differences. +One is in constant evaluation. +Constant expressions in the assembler are parsed using Go's operator +precedence, not the C-like precedence of the original. +Thus 3&1<<2 is 4, not 0—it parses as (3&1)<<2 +not 3&(1<<2). +Also, constants are always evaluated as 64-bit unsigned integers. +Thus -2 is not the integer value minus two, +but the unsigned 64-bit integer with the same bit pattern. +The distinction rarely matters but +to avoid ambiguity, division or right shift where the right operand's +high bit is set is rejected. +

+ +

Symbols

+ +

+Some symbols, such as R1 or LR, +are predefined and refer to registers. +The exact set depends on the architecture. +

+ +

+There are four predeclared symbols that refer to pseudo-registers. +These are not real registers, but rather virtual registers maintained by +the toolchain, such as a frame pointer. +The set of pseudo-registers is the same for all architectures: +

+ + + +

+All user-defined symbols are written as offsets to the pseudo-registers +FP (arguments and locals) and SB (globals). +

+ +

+The SB pseudo-register can be thought of as the origin of memory, so the symbol foo(SB) +is the name foo as an address in memory. +This form is used to name global functions and data. +Adding <> to the name, as in foo<>(SB), makes the name +visible only in the current source file, like a top-level static declaration in a C file. +Adding an offset to the name refers to that offset from the symbol's address, so +foo+4(SB) is four bytes past the start of foo. +

+ +

+The FP pseudo-register is a virtual frame pointer +used to refer to function arguments. +The compilers maintain a virtual frame pointer and refer to the arguments on the stack as offsets from that pseudo-register. +Thus 0(FP) is the first argument to the function, +8(FP) is the second (on a 64-bit machine), and so on. +However, when referring to a function argument this way, it is necessary to place a name +at the beginning, as in first_arg+0(FP) and second_arg+8(FP). +(The meaning of the offset—offset from the frame pointer—distinct +from its use with SB, where it is an offset from the symbol.) +The assembler enforces this convention, rejecting plain 0(FP) and 8(FP). +The actual name is semantically irrelevant but should be used to document +the argument's name. +It is worth stressing that FP is always a +pseudo-register, not a hardware +register, even on architectures with a hardware frame pointer. +

+ +

+For assembly functions with Go prototypes, go vet will check that the argument names +and offsets match. +On 32-bit systems, the low and high 32 bits of a 64-bit value are distinguished by adding +a _lo or _hi suffix to the name, as in arg_lo+0(FP) or arg_hi+4(FP). +If a Go prototype does not name its result, the expected assembly name is ret. +

+ +

+The SP pseudo-register is a virtual stack pointer +used to refer to frame-local variables and the arguments being +prepared for function calls. +It points to the highest address within the local stack frame, so references should use negative offsets +in the range [−framesize, 0): +x-8(SP), y-4(SP), and so on. +

+ +

+On architectures with a hardware register named SP, +the name prefix distinguishes +references to the virtual stack pointer from references to the architectural +SP register. +That is, x-8(SP) and -8(SP) +are different memory locations: +the first refers to the virtual stack pointer pseudo-register, +while the second refers to the +hardware's SP register. +

+ +

+On machines where SP and PC are +traditionally aliases for a physical, numbered register, +in the Go assembler the names SP and PC +are still treated specially; +for instance, references to SP require a symbol, +much like FP. +To access the actual hardware register use the true R name. +For example, on the ARM architecture the hardware +SP and PC are accessible as +R13 and R15. +

+ +

+Branches and direct jumps are always written as offsets to the PC, or as +jumps to labels: +

+ +
+label:
+	MOVW $0, R1
+	JMP label
+
+ +

+Each label is visible only within the function in which it is defined. +It is therefore permitted for multiple functions in a file to define +and use the same label names. +Direct jumps and call instructions can target text symbols, +such as name(SB), but not offsets from symbols, +such as name+4(SB). +

+ +

+Instructions, registers, and assembler directives are always in UPPER CASE to remind you +that assembly programming is a fraught endeavor. +(Exception: the g register renaming on ARM.) +

+ +

+In Go object files and binaries, the full name of a symbol is the +package path followed by a period and the symbol name: +fmt.Printf or math/rand.Int. +Because the assembler's parser treats period and slash as punctuation, +those strings cannot be used directly as identifier names. +Instead, the assembler allows the middle dot character U+00B7 +and the division slash U+2215 in identifiers and rewrites them to +plain period and slash. +Within an assembler source file, the symbols above are written as +fmt·Printf and math∕rand·Int. +The assembly listings generated by the compilers when using the -S flag +show the period and slash directly instead of the Unicode replacements +required by the assemblers. +

+ +

+Most hand-written assembly files do not include the full package path +in symbol names, because the linker inserts the package path of the current +object file at the beginning of any name starting with a period: +in an assembly source file within the math/rand package implementation, +the package's Int function can be referred to as ·Int. +This convention avoids the need to hard-code a package's import path in its +own source code, making it easier to move the code from one location to another. +

+ +

Directives

+ +

+The assembler uses various directives to bind text and data to symbol names. +For example, here is a simple complete function definition. The TEXT +directive declares the symbol runtime·profileloop and the instructions +that follow form the body of the function. +The last instruction in a TEXT block must be some sort of jump, usually a RET (pseudo-)instruction. +(If it's not, the linker will append a jump-to-itself instruction; there is no fallthrough in TEXTs.) +After the symbol, the arguments are flags (see below) +and the frame size, a constant (but see below): +

+ +
+TEXT runtime·profileloop(SB),NOSPLIT,$8
+	MOVQ	$runtime·profileloop1(SB), CX
+	MOVQ	CX, 0(SP)
+	CALL	runtime·externalthreadhandler(SB)
+	RET
+
+ +

+In the general case, the frame size is followed by an argument size, separated by a minus sign. +(It's not a subtraction, just idiosyncratic syntax.) +The frame size $24-8 states that the function has a 24-byte frame +and is called with 8 bytes of argument, which live on the caller's frame. +If NOSPLIT is not specified for the TEXT, +the argument size must be provided. +For assembly functions with Go prototypes, go vet will check that the +argument size is correct. +

+ +

+Note that the symbol name uses a middle dot to separate the components and is specified as an offset from the +static base pseudo-register SB. +This function would be called from Go source for package runtime using the +simple name profileloop. +

+ +

+Global data symbols are defined by a sequence of initializing +DATA directives followed by a GLOBL directive. +Each DATA directive initializes a section of the +corresponding memory. +The memory not explicitly initialized is zeroed. +The general form of the DATA directive is + +

+DATA	symbol+offset(SB)/width, value
+
+ +

+which initializes the symbol memory at the given offset and width with the given value. +The DATA directives for a given symbol must be written with increasing offsets. +

+ +

+The GLOBL directive declares a symbol to be global. +The arguments are optional flags and the size of the data being declared as a global, +which will have initial value all zeros unless a DATA directive +has initialized it. +The GLOBL directive must follow any corresponding DATA directives. +

+ +

+For example, +

+ +
+DATA divtab<>+0x00(SB)/4, $0xf4f8fcff
+DATA divtab<>+0x04(SB)/4, $0xe6eaedf0
+...
+DATA divtab<>+0x3c(SB)/4, $0x81828384
+GLOBL divtab<>(SB), RODATA, $64
+
+GLOBL runtime·tlsoffset(SB), NOPTR, $4
+
+ +

+declares and initializes divtab<>, a read-only 64-byte table of 4-byte integer values, +and declares runtime·tlsoffset, a 4-byte, implicitly zeroed variable that +contains no pointers. +

+ +

+There may be one or two arguments to the directives. +If there are two, the first is a bit mask of flags, +which can be written as numeric expressions, added or or-ed together, +or can be set symbolically for easier absorption by a human. +Their values, defined in the standard #include file textflag.h, are: +

+ + + +

Interacting with Go types and constants

+ +

+If a package has any .s files, then go build will direct +the compiler to emit a special header called go_asm.h, +which the .s files can then #include. +The file contains symbolic #define constants for the +offsets of Go struct fields, the sizes of Go struct types, and most +Go const declarations defined in the current package. +Go assembly should avoid making assumptions about the layout of Go +types and instead use these constants. +This improves the readability of assembly code, and keeps it robust to +changes in data layout either in the Go type definitions or in the +layout rules used by the Go compiler. +

+ +

+Constants are of the form const_name. +For example, given the Go declaration const bufSize = +1024, assembly code can refer to the value of this constant +as const_bufSize. +

+ +

+Field offsets are of the form type_field. +Struct sizes are of the form type__size. +For example, consider the following Go definition: +

+ +
+type reader struct {
+	buf [bufSize]byte
+	r   int
+}
+
+ +

+Assembly can refer to the size of this struct +as reader__size and the offsets of the two fields +as reader_buf and reader_r. +Hence, if register R1 contains a pointer to +a reader, assembly can reference the r field +as reader_r(R1). +

+ +

+If any of these #define names are ambiguous (for example, +a struct with a _size field), #include +"go_asm.h" will fail with a "redefinition of macro" error. +

+ +

Runtime Coordination

+ +

+For garbage collection to run correctly, the runtime must know the +location of pointers in all global data and in most stack frames. +The Go compiler emits this information when compiling Go source files, +but assembly programs must define it explicitly. +

+ +

+A data symbol marked with the NOPTR flag (see above) +is treated as containing no pointers to runtime-allocated data. +A data symbol with the RODATA flag +is allocated in read-only memory and is therefore treated +as implicitly marked NOPTR. +A data symbol with a total size smaller than a pointer +is also treated as implicitly marked NOPTR. +It is not possible to define a symbol containing pointers in an assembly source file; +such a symbol must be defined in a Go source file instead. +Assembly source can still refer to the symbol by name +even without DATA and GLOBL directives. +A good general rule of thumb is to define all non-RODATA +symbols in Go instead of in assembly. +

+ +

+Each function also needs annotations giving the location of +live pointers in its arguments, results, and local stack frame. +For an assembly function with no pointer results and +either no local stack frame or no function calls, +the only requirement is to define a Go prototype for the function +in a Go source file in the same package. The name of the assembly +function must not contain the package name component (for example, +function Syscall in package syscall should +use the name ·Syscall instead of the equivalent name +syscall·Syscall in its TEXT directive). +For more complex situations, explicit annotation is needed. +These annotations use pseudo-instructions defined in the standard +#include file funcdata.h. +

+ +

+If a function has no arguments and no results, +the pointer information can be omitted. +This is indicated by an argument size annotation of $n-0 +on the TEXT instruction. +Otherwise, pointer information must be provided by +a Go prototype for the function in a Go source file, +even for assembly functions not called directly from Go. +(The prototype will also let go vet check the argument references.) +At the start of the function, the arguments are assumed +to be initialized but the results are assumed uninitialized. +If the results will hold live pointers during a call instruction, +the function should start by zeroing the results and then +executing the pseudo-instruction GO_RESULTS_INITIALIZED. +This instruction records that the results are now initialized +and should be scanned during stack movement and garbage collection. +It is typically easier to arrange that assembly functions do not +return pointers or do not contain call instructions; +no assembly functions in the standard library use +GO_RESULTS_INITIALIZED. +

+ +

+If a function has no local stack frame, +the pointer information can be omitted. +This is indicated by a local frame size annotation of $0-n +on the TEXT instruction. +The pointer information can also be omitted if the +function contains no call instructions. +Otherwise, the local stack frame must not contain pointers, +and the assembly must confirm this fact by executing the +pseudo-instruction NO_LOCAL_POINTERS. +Because stack resizing is implemented by moving the stack, +the stack pointer may change during any function call: +even pointers to stack data must not be kept in local variables. +

+ +

+Assembly functions should always be given Go prototypes, +both to provide pointer information for the arguments and results +and to let go vet check that +the offsets being used to access them are correct. +

+ +

Architecture-specific details

+ +

+It is impractical to list all the instructions and other details for each machine. +To see what instructions are defined for a given machine, say ARM, +look in the source for the obj support library for +that architecture, located in the directory src/cmd/internal/obj/arm. +In that directory is a file a.out.go; it contains +a long list of constants starting with A, like this: +

+ +
+const (
+	AAND = obj.ABaseARM + obj.A_ARCHSPECIFIC + iota
+	AEOR
+	ASUB
+	ARSB
+	AADD
+	...
+
+ +

+This is the list of instructions and their spellings as known to the assembler and linker for that architecture. +Each instruction begins with an initial capital A in this list, so AAND +represents the bitwise and instruction, +AND (without the leading A), +and is written in assembly source as AND. +The enumeration is mostly in alphabetical order. +(The architecture-independent AXXX, defined in the +cmd/internal/obj package, +represents an invalid instruction). +The sequence of the A names has nothing to do with the actual +encoding of the machine instructions. +The cmd/internal/obj package takes care of that detail. +

+ +

+The instructions for both the 386 and AMD64 architectures are listed in +cmd/internal/obj/x86/a.out.go. +

+ +

+The architectures share syntax for common addressing modes such as +(R1) (register indirect), +4(R1) (register indirect with offset), and +$foo(SB) (absolute address). +The assembler also supports some (not necessarily all) addressing modes +specific to each architecture. +The sections below list these. +

+ +

+One detail evident in the examples from the previous sections is that data in the instructions flows from left to right: +MOVQ $0, CX clears CX. +This rule applies even on architectures where the conventional notation uses the opposite direction. +

+ +

+Here follow some descriptions of key Go-specific details for the supported architectures. +

+ +

32-bit Intel 386

+ +

+The runtime pointer to the g structure is maintained +through the value of an otherwise unused (as far as Go is concerned) register in the MMU. +In the runtime package, assembly code can include go_tls.h, which defines +an OS- and architecture-dependent macro get_tls for accessing this register. +The get_tls macro takes one argument, which is the register to load the +g pointer into. +

+ +

+For example, the sequence to load g and m +using CX looks like this: +

+ +
+#include "go_tls.h"
+#include "go_asm.h"
+...
+get_tls(CX)
+MOVL	g(CX), AX     // Move g into AX.
+MOVL	g_m(AX), BX   // Move g.m into BX.
+
+ +

+The get_tls macro is also defined on amd64. +

+ +

+Addressing modes: +

+ + + +

+When using the compiler and assembler's +-dynlink or -shared modes, +any load or store of a fixed memory location such as a global variable +must be assumed to overwrite CX. +Therefore, to be safe for use with these modes, +assembly sources should typically avoid CX except between memory references. +

+ +

64-bit Intel 386 (a.k.a. amd64)

+ +

+The two architectures behave largely the same at the assembler level. +Assembly code to access the m and g +pointers on the 64-bit version is the same as on the 32-bit 386, +except it uses MOVQ rather than MOVL: +

+ +
+get_tls(CX)
+MOVQ	g(CX), AX     // Move g into AX.
+MOVQ	g_m(AX), BX   // Move g.m into BX.
+
+ +

+Register BP is callee-save. +The assembler automatically inserts BP save/restore when frame size is larger than zero. +Using BP as a general purpose register is allowed, +however it can interfere with sampling-based profiling. +

+ +

ARM

+ +

+The registers R10 and R11 +are reserved by the compiler and linker. +

+ +

+R10 points to the g (goroutine) structure. +Within assembler source code, this pointer must be referred to as g; +the name R10 is not recognized. +

+ +

+To make it easier for people and compilers to write assembly, the ARM linker +allows general addressing forms and pseudo-operations like DIV or MOD +that may not be expressible using a single hardware instruction. +It implements these forms as multiple instructions, often using the R11 register +to hold temporary values. +Hand-written assembly can use R11, but doing so requires +being sure that the linker is not also using it to implement any of the other +instructions in the function. +

+ +

+When defining a TEXT, specifying frame size $-4 +tells the linker that this is a leaf function that does not need to save LR on entry. +

+ +

+The name SP always refers to the virtual stack pointer described earlier. +For the hardware register, use R13. +

+ +

+Condition code syntax is to append a period and the one- or two-letter code to the instruction, +as in MOVW.EQ. +Multiple codes may be appended: MOVM.IA.W. +The order of the code modifiers is irrelevant. +

+ +

+Addressing modes: +

+ + + +

ARM64

+ +

+R18 is the "platform register", reserved on the Apple platform. +To prevent accidental misuse, the register is named R18_PLATFORM. +R27 and R28 are reserved by the compiler and linker. +R29 is the frame pointer. +R30 is the link register. +

+ +

+Instruction modifiers are appended to the instruction following a period. +The only modifiers are P (postincrement) and W +(preincrement): +MOVW.P, MOVW.W +

+ +

+Addressing modes: +

+ + + +

+Reference: Go ARM64 Assembly Instructions Reference Manual +

+ +

PPC64

+ +

+This assembler is used by GOARCH values ppc64 and ppc64le. +

+ +

+Reference: Go PPC64 Assembly Instructions Reference Manual +

+ +

IBM z/Architecture, a.k.a. s390x

+ +

+The registers R10 and R11 are reserved. +The assembler uses them to hold temporary values when assembling some instructions. +

+ +

+R13 points to the g (goroutine) structure. +This register must be referred to as g; the name R13 is not recognized. +

+ +

+R15 points to the stack frame and should typically only be accessed using the +virtual registers SP and FP. +

+ +

+Load- and store-multiple instructions operate on a range of registers. +The range of registers is specified by a start register and an end register. +For example, LMG (R9), R5, R7 would load +R5, R6 and R7 with the 64-bit values at +0(R9), 8(R9) and 16(R9) respectively. +

+ +

+Storage-and-storage instructions such as MVC and XC are written +with the length as the first argument. +For example, XC $8, (R9), (R9) would clear +eight bytes at the address specified in R9. +

+ +

+If a vector instruction takes a length or an index as an argument then it will be the +first argument. +For example, VLEIF $1, $16, V2 will load +the value sixteen into index one of V2. +Care should be taken when using vector instructions to ensure that they are available at +runtime. +To use vector instructions a machine must have both the vector facility (bit 129 in the +facility list) and kernel support. +Without kernel support a vector instruction will have no effect (it will be equivalent +to a NOP instruction). +

+ +

+Addressing modes: +

+ + + +

MIPS, MIPS64

+ +

+General purpose registers are named R0 through R31, +floating point registers are F0 through F31. +

+ +

+R30 is reserved to point to g. +R23 is used as a temporary register. +

+ +

+In a TEXT directive, the frame size $-4 for MIPS or +$-8 for MIPS64 instructs the linker not to save LR. +

+ +

+SP refers to the virtual stack pointer. +For the hardware register, use R29. +

+ +

+Addressing modes: +

+ + + +

+The value of GOMIPS environment variable (hardfloat or +softfloat) is made available to assembly code by predefining either +GOMIPS_hardfloat or GOMIPS_softfloat. +

+ +

+The value of GOMIPS64 environment variable (hardfloat or +softfloat) is made available to assembly code by predefining either +GOMIPS64_hardfloat or GOMIPS64_softfloat. +

+ +

Unsupported opcodes

+ +

+The assemblers are designed to support the compiler so not all hardware instructions +are defined for all architectures: if the compiler doesn't generate it, it might not be there. +If you need to use a missing instruction, there are two ways to proceed. +One is to update the assembler to support that instruction, which is straightforward +but only worthwhile if it's likely the instruction will be used again. +Instead, for simple one-off cases, it's possible to use the BYTE +and WORD directives +to lay down explicit data into the instruction stream within a TEXT. +Here's how the 386 runtime defines the 64-bit atomic load function. +

+ +
+// uint64 atomicload64(uint64 volatile* addr);
+// so actually
+// void atomicload64(uint64 *res, uint64 volatile *addr);
+TEXT runtime·atomicload64(SB), NOSPLIT, $0-12
+	MOVL	ptr+0(FP), AX
+	TESTL	$7, AX
+	JZ	2(PC)
+	MOVL	0, AX // crash with nil ptr deref
+	LEAL	ret_lo+4(FP), BX
+	// MOVQ (%EAX), %MM0
+	BYTE $0x0f; BYTE $0x6f; BYTE $0x00
+	// MOVQ %MM0, 0(%EBX)
+	BYTE $0x0f; BYTE $0x7f; BYTE $0x03
+	// EMMS
+	BYTE $0x0F; BYTE $0x77
+	RET
+
diff --git a/doc/go1.17_spec.html b/doc/go1.17_spec.html new file mode 100644 index 0000000..0b374e7 --- /dev/null +++ b/doc/go1.17_spec.html @@ -0,0 +1,6858 @@ + + +

Introduction

+ +

+This is a reference manual for the Go programming language. For +more information and other documents, see golang.org. +

+ +

+Go is a general-purpose language designed with systems programming +in mind. It is strongly typed and garbage-collected and has explicit +support for concurrent programming. Programs are constructed from +packages, whose properties allow efficient management of +dependencies. +

+ +

+The grammar is compact and simple to parse, allowing for easy analysis +by automatic tools such as integrated development environments. +

+ +

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. +

+ +

Source code representation

+ +

+Source code is Unicode text encoded in +UTF-8. The text is not +canonicalized, so a single accented code point is distinct from the +same character constructed from combining an accent and a letter; +those are treated as two code points. For simplicity, this document +will use the unqualified term character to refer to a Unicode code point +in the source text. +

+

+Each code point is distinct; for instance, upper and lower case letters +are different characters. +

+

+Implementation restriction: For compatibility with other tools, a +compiler may disallow the NUL character (U+0000) in the source text. +

+

+Implementation restriction: For compatibility with other tools, a +compiler may ignore a UTF-8-encoded byte order mark +(U+FEFF) if it is the first Unicode code point in the source text. +A byte order mark may be disallowed anywhere else in the source. +

+ +

Characters

+ +

+The following terms are used to denote specific Unicode character classes: +

+
+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" */ .
+
+ +

+In The Unicode Standard 8.0, +Section 4.5 "General Category" defines a set of character categories. +Go treats all characters in any of the Letter categories Lu, Ll, Lt, Lm, or Lo +as Unicode letters, and those in the Number category Nd as Unicode digits. +

+ +

Letters and digits

+ +

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

+
+letter        = unicode_letter | "_" .
+decimal_digit = "0" … "9" .
+binary_digit  = "0" | "1" .
+octal_digit   = "0" … "7" .
+hex_digit     = "0" … "9" | "A" … "F" | "a" … "f" .
+
+ +

Lexical elements

+ +

Comments

+ +

+Comments serve as program documentation. There are two forms: +

+ +
    +
  1. +Line comments start with the character sequence // +and stop at the end of the line. +
  2. +
  3. +General comments start with the character sequence /* +and stop with the first subsequent character sequence */. +
  4. +
+ +

+A comment cannot start inside a rune or +string literal, or inside a comment. +A general comment containing no newlines acts like a space. +Any other comment acts like a newline. +

+ +

Tokens

+ +

+Tokens form the vocabulary of the Go language. +There are four classes: identifiers, keywords, operators +and punctuation, and literals. White space, formed from +spaces (U+0020), horizontal tabs (U+0009), +carriage returns (U+000D), and newlines (U+000A), +is ignored except as it separates tokens +that would otherwise combine into a single token. Also, a newline or end of file +may trigger the insertion of a semicolon. +While breaking the input into tokens, +the next token is the longest sequence of characters that form a +valid token. +

+ +

Semicolons

+ +

+The formal grammar uses semicolons ";" as terminators in +a number of productions. Go programs may omit most of these semicolons +using the following two rules: +

+ +
    +
  1. +When the input is broken into tokens, a semicolon is automatically inserted +into the token stream immediately after a line's final token if that token is + +
  2. + +
  3. +To allow complex statements to occupy a single line, a semicolon +may be omitted before a closing ")" or "}". +
  4. +
+ +

+To reflect idiomatic use, code examples in this document elide semicolons +using these rules. +

+ + +

Identifiers

+ +

+Identifiers name program entities such as variables and types. +An identifier is a sequence of one or more letters and digits. +The first character in an identifier must be a letter. +

+
+identifier = letter { letter | unicode_digit } .
+
+
+a
+_x9
+ThisVariableIsExported
+αβ
+
+ +

+Some identifiers are predeclared. +

+ + +

Keywords

+ +

+The following keywords are reserved and may not be used as identifiers. +

+
+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 punctuation

+ +

+The following character sequences represent operators +(including assignment operators) and punctuation: +

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

Integer literals

+ +

+An integer literal is a sequence of digits representing an +integer constant. +An optional prefix sets a non-decimal base: 0b or 0B +for binary, 0, 0o, or 0O for octal, +and 0x or 0X for hexadecimal. +A single 0 is considered a decimal zero. +In hexadecimal literals, letters a through f +and A through F represent values 10 through 15. +

+ +

+For readability, an underscore character _ may appear after +a base prefix or between successive digits; such underscores do not change +the literal's value. +

+
+int_lit        = decimal_lit | binary_lit | octal_lit | hex_lit .
+decimal_lit    = "0" | ( "1" … "9" ) [ [ "_" ] decimal_digits ] .
+binary_lit     = "0" ( "b" | "B" ) [ "_" ] binary_digits .
+octal_lit      = "0" [ "o" | "O" ] [ "_" ] octal_digits .
+hex_lit        = "0" ( "x" | "X" ) [ "_" ] hex_digits .
+
+decimal_digits = decimal_digit { [ "_" ] decimal_digit } .
+binary_digits  = binary_digit { [ "_" ] binary_digit } .
+octal_digits   = octal_digit { [ "_" ] octal_digit } .
+hex_digits     = hex_digit { [ "_" ] hex_digit } .
+
+ +
+42
+4_2
+0600
+0_600
+0o600
+0O600       // second character is capital letter 'O'
+0xBadFace
+0xBad_Face
+0x_67_7a_2f_cc_40_c6
+170141183460469231731687303715884105727
+170_141183_460469_231731_687303_715884_105727
+
+_42         // an identifier, not an integer literal
+42_         // invalid: _ must separate successive digits
+4__2        // invalid: only one _ at a time
+0_xBadFace  // invalid: _ must separate successive digits
+
+ + +

Floating-point literals

+ +

+A floating-point literal is a decimal or hexadecimal representation of a +floating-point constant. +

+ +

+A decimal floating-point literal consists of an integer part (decimal digits), +a decimal point, a fractional part (decimal digits), and an exponent part +(e or E followed by an optional sign and decimal digits). +One of the integer part or the fractional part may be elided; one of the decimal point +or the exponent part may be elided. +An exponent value exp scales the mantissa (integer and fractional part) by 10exp. +

+ +

+A hexadecimal floating-point literal consists of a 0x or 0X +prefix, an integer part (hexadecimal digits), a radix point, a fractional part (hexadecimal digits), +and an exponent part (p or P followed by an optional sign and decimal digits). +One of the integer part or the fractional part may be elided; the radix point may be elided as well, +but the exponent part is required. (This syntax matches the one given in IEEE 754-2008 §5.12.3.) +An exponent value exp scales the mantissa (integer and fractional part) by 2exp. +

+ +

+For readability, an underscore character _ may appear after +a base prefix or between successive digits; such underscores do not change +the literal value. +

+ +
+float_lit         = decimal_float_lit | hex_float_lit .
+
+decimal_float_lit = decimal_digits "." [ decimal_digits ] [ decimal_exponent ] |
+                    decimal_digits decimal_exponent |
+                    "." decimal_digits [ decimal_exponent ] .
+decimal_exponent  = ( "e" | "E" ) [ "+" | "-" ] decimal_digits .
+
+hex_float_lit     = "0" ( "x" | "X" ) hex_mantissa hex_exponent .
+hex_mantissa      = [ "_" ] hex_digits "." [ hex_digits ] |
+                    [ "_" ] hex_digits |
+                    "." hex_digits .
+hex_exponent      = ( "p" | "P" ) [ "+" | "-" ] decimal_digits .
+
+ +
+0.
+72.40
+072.40       // == 72.40
+2.71828
+1.e+0
+6.67428e-11
+1E6
+.25
+.12345E+5
+1_5.         // == 15.0
+0.15e+0_2    // == 15.0
+
+0x1p-2       // == 0.25
+0x2.p10      // == 2048.0
+0x1.Fp+0     // == 1.9375
+0X.8p-0      // == 0.5
+0X_1FFFP-16  // == 0.1249847412109375
+0x15e-2      // == 0x15e - 2 (integer subtraction)
+
+0x.p1        // invalid: mantissa has no digits
+1p-2         // invalid: p exponent requires hexadecimal mantissa
+0x1.5e-2     // invalid: hexadecimal mantissa requires p exponent
+1_.5         // invalid: _ must separate successive digits
+1._5         // invalid: _ must separate successive digits
+1.5_e1       // invalid: _ must separate successive digits
+1.5e_1       // invalid: _ must separate successive digits
+1.5e1_       // invalid: _ must separate successive digits
+
+ + +

Imaginary literals

+ +

+An imaginary literal represents the imaginary part of a +complex constant. +It consists of an integer or +floating-point literal +followed by the lower-case letter i. +The value of an imaginary literal is the value of the respective +integer or floating-point literal multiplied by the imaginary unit i. +

+ +
+imaginary_lit = (decimal_digits | int_lit | float_lit) "i" .
+
+ +

+For backward compatibility, an imaginary literal's integer part consisting +entirely of decimal digits (and possibly underscores) is considered a decimal +integer, even if it starts with a leading 0. +

+ +
+0i
+0123i         // == 123i for backward-compatibility
+0o123i        // == 0o123 * 1i == 83i
+0xabci        // == 0xabc * 1i == 2748i
+0.i
+2.71828i
+1.e+0i
+6.67428e-11i
+1E6i
+.25i
+.12345E+5i
+0x1p-2i       // == 0x1p-2 * 1i == 0.25i
+
+ + +

Rune literals

+ +

+A rune literal represents a rune constant, +an integer value identifying a Unicode code point. +A rune literal is expressed as one or more characters enclosed in single quotes, +as in 'x' or '\n'. +Within the quotes, any character may appear except newline and unescaped single +quote. A single quoted character represents the Unicode value +of the character itself, +while multi-character sequences beginning with a backslash encode +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. +

+ +

+Several backslash escapes allow arbitrary values to be encoded 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. +In each case the value of the literal is the value represented by +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 escapes \u and \U +represent Unicode code points so within them some values are illegal, +in particular those above 0x10FFFF and surrogate halves. +

+ +

+After a backslash, certain single-character escapes represent special values: +

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

+All other sequences starting with a backslash are illegal inside 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" | `\` | "'" | `"` ) .
+
+ +
+'a'
+'ä'
+'本'
+'\t'
+'\000'
+'\007'
+'\377'
+'\x07'
+'\xff'
+'\u12e4'
+'\U00101234'
+'\''         // rune literal containing single quote character
+'aa'         // illegal: too many characters
+'\xa'        // illegal: too few hexadecimal digits
+'\0'         // illegal: too few octal digits
+'\uDFFF'     // illegal: surrogate half
+'\U00110000' // illegal: invalid Unicode code point
+
+ + +

String literals

+ +

+A string literal represents a string constant +obtained from concatenating a sequence of characters. There are two forms: +raw string literals and interpreted string literals. +

+ +

+Raw string literals are character sequences between back quotes, as in +`foo`. Within the quotes, any character may appear except +back quote. 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. +Carriage return characters ('\r') inside raw string literals +are discarded from the raw string value. +

+ +

+Interpreted string literals are character sequences between double +quotes, as in "bar". +Within the quotes, any character may appear except newline and unescaped double quote. +The text between the quotes forms the +value of the literal, with backslash escapes interpreted as they +are in rune literals (except that \' is illegal and +\" is legal), with the same restrictions. +The three-digit octal (\nnn) +and two-digit hexadecimal (\xnn) 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 +U+00FF. +

+ +
+string_lit             = raw_string_lit | interpreted_string_lit .
+raw_string_lit         = "`" { unicode_char | newline } "`" .
+interpreted_string_lit = `"` { unicode_value | byte_value } `"` .
+
+ +
+`abc`                // same as "abc"
+`\n
+\n`                  // same as "\\n\n\\n"
+"\n"
+"\""                 // same as `"`
+"Hello, world!\n"
+"日本語"
+"\u65e5本\U00008a9e"
+"\xff\u00FF"
+"\uD800"             // illegal: surrogate half
+"\U00110000"         // illegal: invalid Unicode code point
+
+ +

+These examples all represent the same string: +

+ +
+"日本語"                                 // UTF-8 input text
+`日本語`                                 // UTF-8 input text as a raw literal
+"\u65e5\u672c\u8a9e"                    // the explicit Unicode code points
+"\U000065e5\U0000672c\U00008a9e"        // the explicit Unicode code points
+"\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e"  // the explicit UTF-8 bytes
+
+ +

+If the source code represents a character as two code points, such as +a combining form involving an accent and a letter, the result will be +an error if placed in a rune literal (it is not a single code +point), and will appear as two code points if placed in a string +literal. +

+ + +

Constants

+ +

There are boolean constants, +rune constants, +integer constants, +floating-point constants, complex constants, +and string constants. Rune, integer, floating-point, +and complex constants are +collectively called numeric constants. +

+ +

+A constant value is represented by a +rune, +integer, +floating-point, +imaginary, +or +string literal, +an identifier denoting a constant, +a constant expression, +a conversion with a result that is a constant, or +the result value of some built-in functions such as +unsafe.Sizeof applied to any value, +cap or len applied to +some expressions, +real and imag applied to a complex constant +and complex applied to numeric constants. +The boolean truth values are represented by the predeclared constants +true and false. The predeclared identifier +iota denotes an integer constant. +

+ +

+In general, complex constants are a form of +constant expression +and are discussed in that section. +

+ +

+Numeric constants represent exact values of arbitrary precision and do not overflow. +Consequently, there are no constants denoting the IEEE-754 negative zero, infinity, +and not-a-number values. +

+ +

+Constants may be typed or untyped. +Literal constants, true, false, iota, +and certain constant expressions +containing only untyped constant operands are untyped. +

+ +

+A constant may be given a type explicitly by a constant declaration +or conversion, or implicitly when used in a +variable declaration or an +assignment or as an +operand in an expression. +It is an error if the constant value +cannot be represented as a value of the respective type. +

+ +

+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, +for instance, in a short variable declaration +such as i := 0 where there is no explicit type. +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. +

+ +

+Implementation restriction: Although numeric constants have arbitrary +precision in the language, a compiler may implement them using an +internal representation with limited precision. That said, every +implementation must: +

+ + + +

+These requirements apply both to literal constants and to the result +of evaluating constant +expressions. +

+ + +

Variables

+ +

+A variable is a storage location for holding a value. +The set of permissible values is determined by the +variable's type. +

+ +

+A variable declaration +or, for function parameters and results, the signature +of a function declaration +or function literal reserves +storage for a named variable. + +Calling the built-in function new +or taking the address of a composite literal +allocates storage for a variable at run time. +Such an anonymous variable is referred to via a (possibly implicit) +pointer indirection. +

+ +

+Structured variables of array, slice, +and struct types have elements and fields that may +be addressed individually. Each such element +acts like a variable. +

+ +

+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 concrete type of the value assigned to the variable at run time +(unless the value is the predeclared identifier nil, +which has no type). +The dynamic type may vary during execution but values stored in interface +variables are always assignable +to the static type of the variable. +

+ +
+var x interface{}  // x is nil and has static type interface{}
+var v *T           // v has value nil, static type *T
+x = 42             // x has value 42 and dynamic type int
+x = v              // x has value (*T)(nil) and dynamic type *T
+
+ +

+A variable's value is retrieved by referring to the variable in an +expression; it is the most recent value +assigned to the variable. +If a variable has not yet been assigned a value, its value is the +zero value for its type. +

+ + +

Types

+ +

+A type determines a set of values together with operations and methods specific +to those values. A type may be denoted by a type name, if it has one, +or specified using a type literal, which composes a type from existing types. +

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

+The language predeclares certain type names. +Others are introduced with type declarations. +Composite types—array, struct, pointer, function, +interface, slice, map, and channel types—may be constructed using +type literals. +

+ +

+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 +type declaration. +

+ +
+type (
+	A1 = string
+	A2 = A1
+)
+
+type (
+	B1 string
+	B2 B1
+	B3 []B1
+	B4 B3
+)
+
+ +

+The underlying type of string, A1, A2, B1, +and B2 is string. +The underlying type of []B1, B3, and B4 is []B1. +

+ +

Method sets

+

+A type has a (possibly empty) method set associated with it. +The method set of an interface type is its interface. +The method set of any other type T consists of all +methods declared with receiver type T. +The method set of the corresponding pointer type *T +is the set of all methods declared with receiver *T or T +(that is, it also contains the method set of T). +Further rules apply to structs containing embedded fields, as described +in the section on struct types. +Any other type has an empty method set. +In a method set, each method must have a +unique +non-blank method name. +

+ +

+The method set of a type determines the interfaces that the +type implements +and the methods that can be called +using a receiver of that type. +

+ +

Boolean types

+ +

+A boolean type represents the set of Boolean truth values +denoted by the predeclared constants true +and false. The predeclared boolean type is bool; +it is a defined type. +

+ +

Numeric types

+ +

+A numeric type represents sets of integer or floating-point values. +The predeclared architecture-independent numeric types are: +

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

+The value of an n-bit integer is n bits wide and represented using +two's complement arithmetic. +

+ +

+There is also a set of predeclared numeric types with implementation-specific sizes: +

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

+To avoid portability issues all numeric types are defined +types and thus distinct except +byte, which is an alias for uint8, and +rune, which is an alias for int32. +Explicit conversions +are required when different numeric types are mixed in an expression +or assignment. For instance, int32 and int +are not the same type even though they may have the same size on a +particular architecture. + + +

String types

+ +

+A string type represents the set of string values. +A string value is a (possibly empty) sequence of bytes. +The number of bytes is called the length of the string and is never negative. +Strings are immutable: once created, +it is impossible to change the contents of a string. +The predeclared string type is string; +it is a defined type. +

+ +

+The length of a string s can be discovered using +the built-in function len. +The length is a compile-time constant if the string is a constant. +A string's bytes can be accessed by integer indices +0 through len(s)-1. +It is illegal to take the address of such an element; if +s[i] is the i'th byte of a +string, &s[i] is invalid. +

+ + +

Array types

+ +

+An array is a numbered sequence of elements of a single +type, called the element type. +The number of elements is called the length of the array and is never negative. +

+ +
+ArrayType   = "[" ArrayLength "]" ElementType .
+ArrayLength = Expression .
+ElementType = Type .
+
+ +

+The length is part of the array's type; it must evaluate to a +non-negative constant +representable by a value +of type int. +The length of array a can be discovered +using the built-in function len. +The elements can be addressed by integer indices +0 through len(a)-1. +Array types are always one-dimensional but may be composed to form +multi-dimensional types. +

+ +
+[32]byte
+[2*N] struct { x, y int32 }
+[1000]*float64
+[3][5]int
+[2][2][2]float64  // same as [2]([2]([2]float64))
+
+ +

Slice types

+ +

+A slice is a descriptor for a contiguous segment of an underlying array and +provides access to a numbered sequence of elements from that array. +A slice type denotes the set of all slices of arrays of its element type. +The number of elements is called the length of the slice and is never negative. +The value of an uninitialized slice is nil. +

+ +
+SliceType = "[" "]" ElementType .
+
+ +

+The length of a slice s can be discovered by the built-in function +len; unlike with arrays it may change during +execution. The elements can be addressed by integer indices +0 through len(s)-1. The slice index of a +given element may be less than the index of the same element in the +underlying array. +

+

+A slice, once initialized, is always associated with an underlying +array that holds its elements. A slice therefore shares storage +with its array and with other slices of the same array; by contrast, +distinct arrays always represent distinct storage. +

+

+The array underlying a slice may extend past the end of the slice. +The capacity is a measure of that extent: it is the sum of +the length of the slice and the length of the array beyond the slice; +a slice of length up to that capacity can be created by +slicing a new one from the original slice. +The capacity of a slice a can be discovered using the +built-in function cap(a). +

+ +

+A new, initialized slice value for a given element type T is +made using the built-in function +make, +which takes a slice type +and parameters specifying the length and optionally the capacity. +A slice created with make always allocates a new, hidden array +to which the returned slice value refers. That is, executing +

+ +
+make([]T, length, capacity)
+
+ +

+produces the same slice as allocating an array and slicing +it, so these two expressions are equivalent: +

+ +
+make([]int, 50, 100)
+new([100]int)[0:50]
+
+ +

+Like arrays, slices are always one-dimensional but may be composed to construct +higher-dimensional objects. +With arrays of arrays, the inner arrays are, by construction, always the same length; +however with slices of slices (or arrays of slices), the inner lengths may vary dynamically. +Moreover, the inner slices must be initialized individually. +

+ +

Struct types

+ +

+A struct is a sequence of named elements, called fields, each of which has a +name and a type. Field names may be specified explicitly (IdentifierList) or +implicitly (EmbeddedField). +Within a struct, non-blank field names must +be unique. +

+ +
+StructType    = "struct" "{" { FieldDecl ";" } "}" .
+FieldDecl     = (IdentifierList Type | EmbeddedField) [ Tag ] .
+EmbeddedField = [ "*" ] TypeName .
+Tag           = string_lit .
+
+ +
+// An empty struct.
+struct {}
+
+// A struct with 6 fields.
+struct {
+	x, y int
+	u float32
+	_ float32  // padding
+	A *[]int
+	F func()
+}
+
+ +

+A field declared with a type but no explicit field name is called an embedded field. +An embedded field must be specified as +a type name T or as a pointer to a non-interface type name *T, +and T itself may not be +a pointer type. The unqualified type name acts as the field name. +

+ +
+// A struct with four embedded fields of types T1, *T2, P.T3 and *P.T4
+struct {
+	T1        // field name is T1
+	*T2       // field name is T2
+	P.T3      // field name is T3
+	*P.T4     // field name is T4
+	x, y int  // field names are x and y
+}
+
+ +

+The following declaration is illegal because field names must be unique +in a struct type: +

+ +
+struct {
+	T     // conflicts with embedded field *T and *P.T
+	*T    // conflicts with embedded field T and *P.T
+	*P.T  // conflicts with embedded field T and *T
+}
+
+ +

+A field or method f of an +embedded field in a struct x is called promoted if +x.f is a legal selector that denotes +that field or method f. +

+ +

+Promoted fields act like ordinary fields +of a struct except that they cannot be used as field names in +composite literals of the struct. +

+ +

+Given a struct type S and a defined type +T, promoted methods are included in the method set of the struct as follows: +

+ + +

+A field declaration may be followed by an optional string literal tag, +which becomes an attribute for all the fields in the corresponding +field declaration. An empty tag string is equivalent to an absent tag. +The tags are made visible through a reflection interface +and take part in type identity for structs +but are otherwise ignored. +

+ +
+struct {
+	x, y float64 ""  // an empty tag string is like an absent tag
+	name string  "any string is permitted as a tag"
+	_    [4]byte "ceci n'est pas un champ de structure"
+}
+
+// A struct corresponding to a TimeStamp protocol buffer.
+// The tag strings define the protocol buffer field numbers;
+// they follow the convention outlined by the reflect package.
+struct {
+	microsec  uint64 `protobuf:"1"`
+	serverIP6 uint64 `protobuf:"2"`
+}
+
+ +

Pointer types

+ +

+A pointer type denotes the set of all pointers to variables of a given +type, called the base type of the pointer. +The value of an uninitialized pointer is nil. +

+ +
+PointerType = "*" BaseType .
+BaseType    = Type .
+
+ +
+*Point
+*[4]int
+
+ +

Function types

+ +

+A function type denotes the set of all functions with the same parameter +and result types. The value of an uninitialized variable of function type +is nil. +

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

+Within a list of parameters or results, the names (IdentifierList) +must either all be present or all be absent. If present, each name +stands for one item (parameter or result) of the specified type and +all non-blank names in the signature +must be unique. +If absent, each type stands for one item of that type. +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. +

+ +
+func()
+func(x int) int
+func(a, _ int, z float32) bool
+func(a, b int, z float32) (bool)
+func(prefix string, values ...int)
+func(a, b int, z float64, opt ...interface{}) (success bool)
+func(int, int, float64) (float64, *[]int)
+func(n int) func(p *T)
+
+ + +

Interface types

+ +

+An interface type specifies a method set called its interface. +A variable of interface type can store a value of any type with a method set +that is any superset of the interface. Such a type is said to +implement the interface. +The value of an uninitialized variable of interface type is nil. +

+ +
+InterfaceType      = "interface" "{" { ( MethodSpec | InterfaceTypeName ) ";" } "}" .
+MethodSpec         = MethodName Signature .
+MethodName         = identifier .
+InterfaceTypeName  = TypeName .
+
+ +

+An interface type may specify methods explicitly through method specifications, +or it may embed methods of other interfaces through interface type names. +

+ +
+// A simple File interface.
+interface {
+	Read([]byte) (int, error)
+	Write([]byte) (int, error)
+	Close() error
+}
+
+ +

+The name of each explicitly specified method must be unique +and not blank. +

+ +
+interface {
+	String() string
+	String() string  // illegal: String not unique
+	_(x int)         // illegal: method must have non-blank name
+}
+
+ +

+More than one type may implement an interface. +For instance, if two types S1 and S2 +have the method set +

+ +
+func (p T) Read(p []byte) (n int, err error)
+func (p T) Write(p []byte) (n int, err error)
+func (p T) Close() error
+
+ +

+(where T stands for either S1 or S2) +then the File interface is implemented by both S1 and +S2, regardless of what other methods +S1 and S2 may have or share. +

+ +

+A type implements any interface comprising any subset of its methods +and may therefore implement several distinct interfaces. For +instance, all types implement the empty interface: +

+ +
+interface{}
+
+ +

+Similarly, consider this interface specification, +which appears within a type declaration +to define an interface called Locker: +

+ +
+type Locker interface {
+	Lock()
+	Unlock()
+}
+
+ +

+If S1 and S2 also implement +

+ +
+func (p T) Lock() { … }
+func (p T) Unlock() { … }
+
+ +

+they implement the Locker interface as well +as the File interface. +

+ +

+An interface T may use a (possibly qualified) interface type +name E in place of a method specification. This is called +embedding interface E in T. +The method set of T is the union +of the method sets of T’s explicitly declared methods and of +T’s embedded interfaces. +

+ +
+type Reader interface {
+	Read(p []byte) (n int, err error)
+	Close() error
+}
+
+type Writer interface {
+	Write(p []byte) (n int, err error)
+	Close() error
+}
+
+// ReadWriter's methods are Read, Write, and Close.
+type ReadWriter interface {
+	Reader  // includes methods of Reader in ReadWriter's method set
+	Writer  // includes methods of Writer in ReadWriter's method set
+}
+
+ +

+A union of method sets contains the (exported and non-exported) +methods of each method set exactly once, and methods with the +same names must +have identical signatures. +

+ +
+type ReadCloser interface {
+	Reader   // includes methods of Reader in ReadCloser's method set
+	Close()  // illegal: signatures of Reader.Close and Close are different
+}
+
+ +

+An interface type T may not embed itself +or any interface type that embeds T, recursively. +

+ +
+// illegal: Bad cannot embed itself
+type Bad interface {
+	Bad
+}
+
+// illegal: Bad1 cannot embed itself using Bad2
+type Bad1 interface {
+	Bad2
+}
+type Bad2 interface {
+	Bad1
+}
+
+ +

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. +The value of an uninitialized map is nil. +

+ +
+MapType     = "map" "[" KeyType "]" ElementType .
+KeyType     = Type .
+
+ +

+The comparison operators +== and != must be fully defined +for operands of the key type; thus the key type must not be a function, map, or +slice. +If the key type is an interface type, these +comparison operators must be defined for the dynamic key values; +failure will cause a run-time panic. + +

+ +
+map[string]int
+map[*T]struct{ x, y float64 }
+map[string]interface{}
+
+ +

+The number of map elements is called its length. +For a map m, it can be discovered using the +built-in function len +and may change during execution. Elements may be added during execution +using assignments and retrieved with +index expressions; they may be removed with the +delete built-in function. +

+

+A new, empty map value is made using the built-in +function make, +which takes the map type and an optional capacity hint as arguments: +

+ +
+make(map[string]int)
+make(map[string]int, 100)
+
+ +

+The initial capacity does not bound its size: +maps grow to accommodate the number of items +stored in them, with the exception of nil maps. +A nil map is equivalent to an empty map except that no elements +may be added. + +

Channel types

+ +

+A channel provides a mechanism for +concurrently executing functions +to communicate by +sending and +receiving +values of a specified element type. +The value of an uninitialized channel is nil. +

+ +
+ChannelType = ( "chan" | "chan" "<-" | "<-" "chan" ) ElementType .
+
+ +

+The optional <- operator specifies the channel direction, +send or receive. If no direction is given, the channel is +bidirectional. +A channel may be constrained only to send or only to receive by +assignment or +explicit conversion. +

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

+The <- operator associates with the leftmost chan +possible: +

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

+A new, initialized channel +value can be made using the built-in function +make, +which takes the channel type and an optional capacity as arguments: +

+ +
+make(chan int, 100)
+
+ +

+The capacity, in number of elements, sets the size of the buffer in the channel. +If the capacity is zero or absent, the channel is unbuffered and communication +succeeds only when both a sender and receiver are ready. Otherwise, the channel +is buffered and communication succeeds without blocking if the buffer +is not full (sends) or not empty (receives). +A nil channel is never ready for communication. +

+ +

+A channel may be closed with the built-in function +close. +The multi-valued assignment form of the +receive operator +reports whether a received value was sent before +the channel was closed. +

+ +

+A single channel may be used in +send statements, +receive operations, +and calls to the built-in functions +cap and +len +by any number of goroutines without further synchronization. +Channels act as first-in-first-out queues. +For example, if one goroutine sends values on a channel +and a second goroutine receives them, the values are +received in the order sent. +

+ +

Properties of types and values

+ +

Type identity

+ +

+Two types are either identical or different. +

+ +

+A defined type is always different from any other type. +Otherwise, two types are identical if their underlying type literals are +structurally equivalent; that is, they have the same literal structure and corresponding +components have identical types. In detail: +

+ + + +

+Given the declarations +

+ +
+type (
+	A0 = []string
+	A1 = A0
+	A2 = struct{ a, b int }
+	A3 = int
+	A4 = func(A3, float64) *A0
+	A5 = func(x int, _ float64) *[]string
+)
+
+type (
+	B0 A0
+	B1 []string
+	B2 struct{ a, b int }
+	B3 struct{ a, c int }
+	B4 func(int, float64) *B0
+	B5 func(x int, y float64) *A1
+)
+
+type	C0 = B0
+
+ +

+these types are identical: +

+ +
+A0, A1, and []string
+A2 and struct{ a, b int }
+A3 and int
+A4, func(int, float64) *[]string, and A5
+
+B0 and C0
+[]int and []int
+struct{ a, b *T5 } and struct{ a, b *T5 }
+func(x int, y float64) *[]string, func(int, float64) (result *[]string), and A5
+
+ +

+B0 and B1 are different because they are new types +created by distinct type definitions; +func(int, float64) *B0 and func(x int, y float64) *[]string +are different because B0 is different from []string. +

+ + +

Assignability

+ +

+A value x is assignable to a variable of type T +("x is assignable to T") if one of the following conditions applies: +

+ + + + +

Representability

+ +

+A constant x is representable +by a value of type T if one of the following conditions applies: +

+ + + +
+x                   T           x is representable by a value of T because
+
+'a'                 byte        97 is in the set of byte values
+97                  rune        rune is an alias for int32, and 97 is in the set of 32-bit integers
+"foo"               string      "foo" is in the set of string values
+1024                int16       1024 is in the set of 16-bit integers
+42.0                byte        42 is in the set of unsigned 8-bit integers
+1e10                uint64      10000000000 is in the set of unsigned 64-bit integers
+2.718281828459045   float32     2.718281828459045 rounds to 2.7182817 which is in the set of float32 values
+-1e-1000            float64     -1e-1000 rounds to IEEE -0.0 which is further simplified to 0.0
+0i                  int         0 is an integer value
+(42 + 0i)           float32     42.0 (with zero imaginary part) is in the set of float32 values
+
+ +
+x                   T           x is not representable by a value of T because
+
+0                   bool        0 is not in the set of boolean values
+'a'                 string      'a' is a rune, it is not in the set of string values
+1024                byte        1024 is not in the set of unsigned 8-bit integers
+-1                  uint16      -1 is not in the set of unsigned 16-bit integers
+1.1                 int         1.1 is not an integer value
+42i                 float32     (0 + 42i) is not in the set of float32 values
+1e1000              float64     1e1000 overflows to IEEE +Inf after rounding
+
+ + +

Blocks

+ +

+A block is a possibly empty sequence of declarations and statements +within matching brace brackets. +

+ +
+Block = "{" StatementList "}" .
+StatementList = { Statement ";" } .
+
+ +

+In addition to explicit blocks in the source code, there are implicit blocks: +

+ +
    +
  1. The universe block encompasses all Go source text.
  2. + +
  3. Each package has a package block containing all + Go source text for that package.
  4. + +
  5. Each file has a file block containing all Go source text + in that file.
  6. + +
  7. Each "if", + "for", and + "switch" + statement is considered to be in its own implicit block.
  8. + +
  9. Each clause in a "switch" + or "select" statement + acts as an implicit block.
  10. +
+ +

+Blocks nest and influence scoping. +

+ + +

Declarations and scope

+ +

+A declaration binds a non-blank identifier to a +constant, +type, +variable, +function, +label, or +package. +Every identifier in a program must be declared. +No identifier may be declared twice in the same block, and +no identifier may be declared in both the file and package block. +

+ +

+The blank identifier may be used like any other identifier +in a declaration, but it does not introduce a binding and thus is not declared. +In the package block, the identifier init may only be used for +init function declarations, +and like the blank identifier it does not introduce a new binding. +

+ +
+Declaration   = ConstDecl | TypeDecl | VarDecl .
+TopLevelDecl  = Declaration | FunctionDecl | MethodDecl .
+
+ +

+The scope of a declared identifier is the extent of source text in which +the identifier denotes the specified constant, type, variable, function, label, or package. +

+ +

+Go is lexically scoped using blocks: +

+ +
    +
  1. The scope of a predeclared identifier is the universe block.
  2. + +
  3. The scope of an identifier denoting a constant, type, variable, + or function (but not method) declared at top level (outside any + function) is the package block.
  4. + +
  5. The scope of the package name of an imported package is the file block + of the file containing the import declaration.
  6. + +
  7. The scope of an identifier denoting a method receiver, function parameter, + or result variable is the function body.
  8. + +
  9. The scope of a constant or variable identifier declared + inside a function begins at the end of the ConstSpec or VarSpec + (ShortVarDecl for short variable declarations) + and ends at the end of the innermost containing block.
  10. + +
  11. The scope of a type identifier declared inside a function + begins at the identifier in the TypeSpec + and ends at the end of the innermost containing block.
  12. +
+ +

+An identifier declared in a block may be redeclared in an inner block. +While the identifier of the inner declaration is in scope, it denotes +the entity declared by the inner declaration. +

+ +

+The package clause is not a declaration; the package name +does not appear in any scope. Its purpose is to identify the files belonging +to the same package and to specify the default package name for import +declarations. +

+ + +

Label scopes

+ +

+Labels are declared by labeled statements and are +used in the "break", +"continue", and +"goto" statements. +It is illegal to define a label that is never used. +In contrast to other identifiers, labels are not block scoped and do +not conflict with identifiers that are not labels. The scope of a label +is the body of the function in which it is declared and excludes +the body of any nested function. +

+ + +

Blank identifier

+ +

+The blank identifier is represented by the underscore character _. +It serves as an anonymous placeholder instead of a regular (non-blank) +identifier and has special meaning in declarations, +as an operand, and in assignments. +

+ + +

Predeclared identifiers

+ +

+The following identifiers are implicitly declared in the +universe block: +

+
+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. +
  3. the identifier is declared in the package block + or it is a field name or + method name.
  4. +
+

+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

+ +

+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, and the nth identifier on +the left is bound to the value of the nth expression on the +right. +

+ +
+ConstDecl      = "const" ( ConstSpec | "(" { ConstSpec ";" } ")" ) .
+ConstSpec      = IdentifierList [ [ Type ] "=" ExpressionList ] .
+
+IdentifierList = identifier { "," identifier } .
+ExpressionList = Expression { "," Expression } .
+
+ +

+If the type is present, all constants take the type specified, and +the expressions must be assignable to that type. +If the type is omitted, the constants take the +individual types of the corresponding expressions. +If the expression values are untyped constants, +the declared constants remain untyped and the constant identifiers +denote the constant values. For instance, if the expression is a +floating-point literal, the constant identifier denotes a floating-point +constant, even if the literal's fractional part is zero. +

+ +
+const Pi float64 = 3.14159265358979323846
+const zero = 0.0         // untyped floating-point constant
+const (
+	size int64 = 1024
+	eof        = -1  // untyped integer constant
+)
+const a, b, c = 3, 4, "foo"  // a = 3, b = 4, c = "foo", untyped integer and string constants
+const u, v float32 = 0, 3    // u = 0.0, v = 3.0
+
+ +

+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. The number of identifiers must be equal +to the number of expressions in the previous list. +Together with the iota constant generator +this mechanism permits light-weight declaration of sequential values: +

+ +
+const (
+	Sunday = iota
+	Monday
+	Tuesday
+	Wednesday
+	Thursday
+	Friday
+	Partyday
+	numberOfDays  // this constant is not exported
+)
+
+ + +

Iota

+ +

+Within a constant declaration, the predeclared identifier +iota represents successive untyped integer +constants. Its value is the index of the respective ConstSpec +in that constant declaration, starting at zero. +It can be used to construct a set of related constants: +

+ +
+const (
+	c0 = iota  // c0 == 0
+	c1 = iota  // c1 == 1
+	c2 = iota  // c2 == 2
+)
+
+const (
+	a = 1 << iota  // a == 1  (iota == 0)
+	b = 1 << iota  // b == 2  (iota == 1)
+	c = 3          // c == 3  (iota == 2, unused)
+	d = 1 << iota  // d == 8  (iota == 3)
+)
+
+const (
+	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
+const y = iota  // y == 0
+
+ +

+By definition, multiple uses of iota in the same ConstSpec all have the same value: +

+ +
+const (
+	bit0, mask0 = 1 << iota, 1<<iota - 1  // bit0 == 1, mask0 == 0  (iota == 0)
+	bit1, mask1                           // bit1 == 2, mask1 == 1  (iota == 1)
+	_, _                                  //                        (iota == 2, unused)
+	bit3, mask3                           // bit3 == 8, mask3 == 7  (iota == 3)
+)
+
+ +

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

+ + +

Type declarations

+ +

+A type declaration binds an identifier, the type name, to a type. +Type declarations come in two forms: alias declarations and type definitions. +

+ +
+TypeDecl = "type" ( TypeSpec | "(" { TypeSpec ";" } ")" ) .
+TypeSpec = AliasDecl | TypeDef .
+
+ +

Alias declarations

+ +

+An alias declaration binds an identifier to the given type. +

+ +
+AliasDecl = identifier "=" Type .
+
+ +

+Within the scope of +the identifier, it serves as an alias for the type. +

+ +
+type (
+	nodeList = []*Node  // nodeList and []*Node are identical types
+	Polar    = polar    // Polar and polar denote identical types
+)
+
+ + +

Type definitions

+ +

+A type definition creates a new, distinct type with the same +underlying type and operations as the given type, +and binds an identifier to it. +

+ +
+TypeDef = identifier 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
+)
+
+type TreeNode struct {
+	left, right *TreeNode
+	value *Comparable
+}
+
+type Block interface {
+	BlockSize() int
+	Encrypt(src, dst []byte)
+	Decrypt(src, dst []byte)
+}
+
+ +

+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: +

+ +
+// 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 PtrMutex's underlying type *Mutex 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 embedded field Mutex.
+type PrintableMutex struct {
+	Mutex
+}
+
+// MyBlock is an interface type that has the same method set as Block.
+type MyBlock Block
+
+ +

+Type definitions may be used to define different boolean, numeric, +or string types and associate methods with them: +

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

Variable declarations

+ +

+A variable declaration creates one or more variables, +binds corresponding identifiers to them, and gives each a type and an initial value. +

+ +
+VarDecl     = "var" ( VarSpec | "(" { VarSpec ";" } ")" ) .
+VarSpec     = IdentifierList ( Type [ "=" ExpressionList ] | "=" ExpressionList ) .
+
+ +
+var i int
+var U, V, W float64
+var k = 0
+var x, y float32 = -1, -2
+var (
+	i       int
+	u, v, s = 2.0, 3.0, "bar"
+)
+var re, im = complexSqrt(-1)
+var _, found = entries[name]  // map lookup; only interested in "found"
+
+ +

+If a list of expressions is given, the variables are initialized +with the expressions following the rules for assignments. +Otherwise, each variable is initialized to its zero value. +

+ +

+If a type is present, each variable is given that type. +Otherwise, each variable is given the type of the corresponding +initialization value in the assignment. +If that value is an untyped constant, it is first implicitly +converted to its default type; +if it is an untyped boolean value, it is first implicitly converted to type bool. +The predeclared value nil cannot be used to initialize a variable +with no explicit type. +

+ +
+var d = math.Sin(0.5)  // d is float64
+var i = 42             // i is int
+var t, ok = x.(T)      // t is T, ok is bool
+var n = nil            // illegal
+
+ +

+Implementation restriction: A compiler may make it illegal to declare a variable +inside a function body if the variable is +never used. +

+ +

Short variable declarations

+ +

+A short variable declaration uses the syntax: +

+ +
+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()  // os.Pipe() returns a connected pair of Files and an error, if any
+_, 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

+ +

+A function declaration binds an identifier, the function name, +to a function. +

+ +
+FunctionDecl = "func" FunctionName Signature [ FunctionBody ] .
+FunctionName = identifier .
+FunctionBody = Block .
+
+ +

+If the function's signature declares +result parameters, the function body's statement list must end in +a terminating statement. +

+ +
+func IndexRune(s string, r rune) int {
+	for i, c := range s {
+		if c == r {
+			return i
+		}
+	}
+	// invalid: missing return statement
+}
+
+ +

+A function declaration may omit the body. Such a declaration provides the +signature for a function implemented outside Go, such as an assembly routine. +

+ +
+func min(x int, y int) int {
+	if x < y {
+		return x
+	}
+	return y
+}
+
+func flushICache(begin, end uintptr)  // implemented externally
+
+ +

Method declarations

+ +

+A method is a function with a receiver. +A method declaration binds an identifier, the method name, to a method, +and associates the method with the receiver's base type. +

+ +
+MethodDecl = "func" Receiver MethodName Signature [ FunctionBody ] .
+Receiver   = Parameters .
+
+ +

+The receiver is specified via an extra parameter section preceding the method +name. That parameter section must declare a single non-variadic parameter, the receiver. +Its type must be a defined type T or a +pointer to a defined type T. T is called the receiver +base type. 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. +

+ +

+A non-blank receiver identifier must be +unique in the method signature. +If the receiver's value is not referenced inside the body of the method, +its identifier may be omitted in the declaration. The same applies in +general to parameters of functions and methods. +

+ +

+For a base type, the non-blank names of methods bound to it must be unique. +If the base type is a struct type, +the non-blank method and field names must be distinct. +

+ +

+Given defined type Point, the declarations +

+ +
+func (p *Point) Length() float64 {
+	return math.Sqrt(p.x * p.x + p.y * p.y)
+}
+
+func (p *Point) Scale(factor float64) {
+	p.x *= factor
+	p.y *= factor
+}
+
+ +

+bind the methods Length and Scale, +with receiver type *Point, +to the base type Point. +

+ +

+The type of a method is the type of a function with the receiver as first +argument. For instance, the method Scale has type +

+ +
+func(p *Point, factor float64)
+
+ +

+However, a function declared this way is not a method. +

+ + +

Expressions

+ +

+An expression specifies the computation of a value by applying +operators and functions to operands. +

+ +

Operands

+ +

+Operands denote the elementary values in an expression. An operand may be a +literal, a (possibly qualified) +non-blank identifier denoting a +constant, +variable, or +function, +or a parenthesized expression. +

+ +

+The blank identifier may appear as an +operand only on the left-hand side of an assignment. +

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

Qualified identifiers

+ +

+A qualified identifier is an identifier qualified with a package name prefix. +Both the package name and the identifier must not be +blank. +

+ +
+QualifiedIdent = PackageName "." identifier .
+
+ +

+A qualified identifier accesses an identifier in a different package, which +must be imported. +The identifier must be exported and +declared in the package block of that package. +

+ +
+math.Sin	// denotes the Sin function in package math
+
+ +

Composite literals

+ +

+Composite literals construct values for structs, arrays, slices, and maps +and create a new value each time they are evaluated. +They consist of the type of the literal followed by a brace-bound list of elements. +Each element may optionally be preceded by a corresponding key. +

+ +
+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 .
+
+ +

+The LiteralType's underlying type must be a struct, array, slice, or map type +(the grammar enforces this constraint except when the type is given +as a TypeName). +The types of the elements and keys must be assignable +to the respective field, element, and key types of the literal type; +there is no additional conversion. +The key is interpreted as a field name for struct literals, +an index for array and slice literals, and a key for map literals. +For map literals, all elements must have a key. It is an error +to specify multiple elements with the same field name or +constant key value. For non-constant map keys, see the section on +evaluation order. +

+ +

+For struct literals the following rules apply: +

+ + +

+Given the declarations +

+
+type Point3D struct { x, y, z float64 }
+type Line struct { p, q Point3D }
+
+ +

+one may write +

+ +
+origin := Point3D{}                            // zero value for Point3D
+line := Line{origin, Point3D{y: -4, z: 12.3}}  // zero value for line.q.x
+
+ +

+For array and slice literals the following rules apply: +

+ + +

+Taking the address of a composite literal +generates a pointer to a unique variable initialized +with the literal's value. +

+ +
+var pointer *Point3D = &Point3D{y: 1000}
+
+ +

+Note that the zero value for a slice or map +type is not the same as an initialized but empty value of the same type. +Consequently, taking the address of an empty slice or map composite literal +does not have the same effect as allocating a new slice or map value with +new. +

+ +
+p1 := &[]int{}    // p1 points to an initialized, empty slice with value []int{} and length 0
+p2 := new([]int)  // p2 points to an uninitialized slice with value nil and length 0
+
+ +

+The length of an array literal is the length specified in the literal type. +If fewer elements than the length are provided in the literal, the missing +elements are set to the zero value for the array element type. +It is an error to provide elements with index values outside the index range +of the array. The notation ... specifies an array length equal +to the maximum element index plus one. +

+ +
+buffer := [10]string{}             // len(buffer) == 10
+intSet := [6]int{1, 2, 3, 5}       // len(intSet) == 6
+days := [...]string{"Sat", "Sun"}  // len(days) == 2
+
+ +

+A slice literal describes the entire underlying array literal. +Thus the length and capacity of a slice literal are the maximum +element index plus one. A slice literal has the form +

+ +
+[]T{x1, x2, … xn}
+
+ +

+and is shorthand for a slice operation applied to an array: +

+ +
+tmp := [n]T{x1, x2, … xn}
+tmp[0 : n]
+
+ +

+Within a composite literal of array, slice, or map type T, +elements or map keys that are themselves composite literals may elide the respective +literal type if it is identical to the element or key type of T. +Similarly, elements or keys that are addresses of composite literals may elide +the &T when the element or key type is *T. +

+ +
+[...]Point{{1.5, -3.5}, {0, 0}}     // same as [...]Point{Point{1.5, -3.5}, Point{0, 0}}
+[][]int{{1, 2, 3}, {4, 5}}          // same as [][]int{[]int{1, 2, 3}, []int{4, 5}}
+[][]Point{{{0, 1}, {1, 2}}}         // same as [][]Point{[]Point{Point{0, 1}, Point{1, 2}}}
+map[string]Point{"orig": {0, 0}}    // same as map[string]Point{"orig": Point{0, 0}}
+map[Point]string{{0, 0}: "orig"}    // same as map[Point]string{Point{0, 0}: "orig"}
+
+type PPoint *Point
+[2]*Point{{1.5, -3.5}, {}}          // same as [2]*Point{&Point{1.5, -3.5}, &Point{}}
+[2]PPoint{{1.5, -3.5}, {}}          // same as [2]PPoint{PPoint(&Point{1.5, -3.5}), PPoint(&Point{})}
+
+ +

+A parsing ambiguity arises when a composite literal using the +TypeName form of the LiteralType appears as an operand between the +keyword and the opening brace of the block +of an "if", "for", or "switch" statement, and the composite literal +is not enclosed in parentheses, square brackets, or curly braces. +In this rare case, the opening brace of the literal is erroneously parsed +as the one introducing the block of statements. To resolve the ambiguity, +the composite literal must appear within parentheses. +

+ +
+if x == (T{a,b,c}[i]) { … }
+if (x == T{a,b,c}[i]) { … }
+
+ +

+Examples of valid array, slice, and map literals: +

+ +
+// list of prime numbers
+primes := []int{2, 3, 5, 7, 9, 2147483647}
+
+// vowels[ch] is true if ch is a vowel
+vowels := [128]bool{'a': true, 'e': true, 'i': true, 'o': true, 'u': true, 'y': true}
+
+// the array [10]float32{-1, 0, 0, 0, -0.1, -0.1, 0, 0, 0, -1}
+filter := [10]float32{-1, 4: -0.1, -0.1, 9: -1}
+
+// frequencies in Hz for equal-tempered scale (A4 = 440Hz)
+noteFrequency := map[string]float32{
+	"C0": 16.35, "D0": 18.35, "E0": 20.60, "F0": 21.83,
+	"G0": 24.50, "A0": 27.50, "B0": 30.87,
+}
+
+ + +

Function literals

+ +

+A function literal represents an anonymous function. +

+ +
+FunctionLit = "func" Signature FunctionBody .
+
+ +
+func(a, b int, z float64) bool { return a*b < int(z) }
+
+ +

+A function literal can be assigned to a variable or invoked directly. +

+ +
+f := func(x, y int) int { return x + y }
+func(ch chan int) { ch <- ACK }(replyChan)
+
+ +

+Function literals are closures: they may refer to variables +defined in a surrounding function. Those variables are then shared between +the surrounding function and the function literal, and they survive as long +as they are accessible. +

+ + +

Primary expressions

+ +

+Primary expressions are the operands for unary and binary expressions. +

+ +
+PrimaryExpr =
+	Operand |
+	Conversion |
+	MethodExpr |
+	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 ] ) [ "..." ] [ "," ] ] ")" .
+
+ + +
+x
+2
+(s + ".txt")
+f(3.1415, true)
+Point{1, 2}
+m["foo"]
+s[i : j + 1]
+obj.color
+f.p[i].x()
+
+ + +

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 +embedded field of T. +The number of embedded 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 embedded 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. + +
  3. +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. +
  4. + +
  5. +As an exception, if the type of x is a defined +pointer type and (*x).f is a valid selector expression denoting a field +(but not a method), x.f is shorthand for (*x).f. +
  6. + +
  7. +In all other cases, x.f is illegal. +
  8. + +
  9. +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. +
  10. + +
  11. +If x is of interface type and has the value +nil, calling or +evaluating the method x.f +causes a run-time panic. +
  12. +
+ +

+For example, given the declarations: +

+ +
+type T0 struct {
+	x int
+}
+
+func (*T0) M0()
+
+type T1 struct {
+	y int
+}
+
+func (T1) M1()
+
+type T2 struct {
+	z int
+	T1
+	*T0
+}
+
+func (*T2) M2()
+
+type Q *T2
+
+var t T2     // with t.T0 != nil
+var p *T2    // with p != nil and (*p).T0 != nil
+var q Q = p
+
+ +

+one may write: +

+ +
+t.z          // t.z
+t.y          // t.T1.y
+t.x          // (*t.T0).x
+
+p.z          // (*p).z
+p.y          // (*p).T1.y
+p.x          // (*(*p).T0).x
+
+q.x          // (*(*q).T0).x        (*q).x is a valid field selector
+
+p.M0()       // ((*p).T0).M0()      M0 expects *T0 receiver
+p.M1()       // ((*p).T1).M1()      M1 expects T1 receiver
+p.M2()       // p.M2()              M2 expects *T2 receiver
+t.M2()       // (&t).M2()           M2 expects *T2 receiver, see section on Calls
+
+ +

+but the following is invalid: +

+ +
+q.M0()       // (*q).M0 is valid but not a field selector
+
+ + +

Method expressions

+ +

+If M is in the method set of type T, +T.M is a function that is callable as a regular function +with the same arguments as M prefixed by an additional +argument that is the receiver of the method. +

+ +
+MethodExpr    = ReceiverType "." MethodName .
+ReceiverType  = Type .
+
+ +

+Consider a struct type T with two methods, +Mv, whose receiver is of type T, and +Mp, whose receiver is of type *T. +

+ +
+type T struct {
+	a int
+}
+func (tv  T) Mv(a int) int         { return 0 }  // value receiver
+func (tp *T) Mp(f float32) float32 { return 1 }  // pointer receiver
+
+var t T
+
+ +

+The expression +

+ +
+T.Mv
+
+ +

+yields a function equivalent to Mv but +with an explicit receiver as its first argument; it has signature +

+ +
+func(tv T, a int) int
+
+ +

+That function may be called normally with an explicit receiver, so +these five invocations are equivalent: +

+ +
+t.Mv(7)
+T.Mv(t, 7)
+(T).Mv(t, 7)
+f1 := T.Mv; f1(t, 7)
+f2 := (T).Mv; f2(t, 7)
+
+ +

+Similarly, the expression +

+ +
+(*T).Mp
+
+ +

+yields a function value representing Mp with signature +

+ +
+func(tp *T, f float32) float32
+
+ +

+For a method with a value receiver, one can derive a function +with an explicit pointer receiver, so +

+ +
+(*T).Mv
+
+ +

+yields a function value representing Mv with signature +

+ +
+func(tv *T, a int) int
+
+ +

+Such a function indirects through the receiver to create a value +to pass as the receiver to the underlying method; +the method does not overwrite the value whose address is passed in +the function call. +

+ +

+The final case, a value-receiver function for a pointer-receiver method, +is illegal because pointer-receiver methods are not in the method set +of the value type. +

+ +

+Function values derived from methods are called with function call syntax; +the receiver is provided as the first argument to the call. +That is, given f := T.Mv, f is invoked +as f(t, 7) not t.f(7). +To construct a function that binds the receiver, use a +function literal or +method value. +

+ +

+It is legal to derive a function value from a method of an interface type. +The resulting function takes an explicit receiver of that interface type. +

+ +

Method values

+ +

+If the expression x has static type T and +M is in the method set of type T, +x.M is called a method value. +The method value x.M is a function value that is callable +with the same arguments as a method call of x.M. +The expression x is evaluated and saved during the evaluation of the +method value; the saved copy is then used as the receiver in any calls, +which may be executed later. +

+ +
+type S struct { *T }
+type T int
+func (t T) M() { print(t) }
+
+t := new(T)
+s := S{T: t}
+f := t.M                    // receiver *t is evaluated and stored in f
+g := s.M                    // receiver *(s.T) is evaluated and stored in g
+*t = 42                     // does not affect stored receivers in f and g
+
+ +

+The type T may be an interface or non-interface type. +

+ +

+As in the discussion of method expressions above, +consider a struct type T with two methods, +Mv, whose receiver is of type T, and +Mp, whose receiver is of type *T. +

+ +
+type T struct {
+	a int
+}
+func (tv  T) Mv(a int) int         { return 0 }  // value receiver
+func (tp *T) Mp(f float32) float32 { return 1 }  // pointer receiver
+
+var t T
+var pt *T
+func makeT() T
+
+ +

+The expression +

+ +
+t.Mv
+
+ +

+yields a function value of type +

+ +
+func(int) int
+
+ +

+These two invocations are equivalent: +

+ +
+t.Mv(7)
+f := t.Mv; f(7)
+
+ +

+Similarly, the expression +

+ +
+pt.Mp
+
+ +

+yields a function value of type +

+ +
+func(float32) float32
+
+ +

+As with selectors, a reference to a non-interface method with a value receiver +using a pointer will automatically dereference that pointer: pt.Mv is equivalent to (*pt).Mv. +

+ +

+As with method calls, a reference to a non-interface method with a pointer receiver +using an addressable value will automatically take the address of that value: t.Mp is equivalent to (&t).Mp. +

+ +
+f := t.Mv; f(7)   // like t.Mv(7)
+f := pt.Mp; f(7)  // like pt.Mp(7)
+f := pt.Mv; f(7)  // like (*pt).Mv(7)
+f := t.Mp; f(7)   // like (&t).Mp(7)
+f := makeT().Mp   // invalid: result of makeT() is not addressable
+
+ +

+Although the examples above use non-interface types, it is also legal to create a method value +from a value of interface type. +

+ +
+var i interface { M(int) } = myVal
+f := i.M; f(7)  // like i.M(7)
+
+ + +

Index expressions

+ +

+A primary expression of the form +

+ +
+a[x]
+
+ +

+denotes the element of the array, pointer to array, slice, string or map a indexed by x. +The value x is called the index or map key, respectively. +The following rules apply: +

+ +

+If a is not a map: +

+ + +

+For a of array type A: +

+ + +

+For a of pointer to array type: +

+ + +

+For a of slice type S: +

+ + +

+For a of string type: +

+ + +

+For a of map type M: +

+ + +

+Otherwise a[x] is illegal. +

+ +

+An index expression on a map a of type map[K]V +used in an assignment or initialization of the special form +

+ +
+v, ok = a[x]
+v, ok := a[x]
+var v, ok = a[x]
+
+ +

+yields an additional untyped boolean value. The value of ok is +true if the key x is present in the map, and +false otherwise. +

+ +

+Assigning to an element of a nil map causes a +run-time panic. +

+ + +

Slice expressions

+ +

+Slice expressions construct a substring or slice from a string, array, pointer +to array, or slice. There are two variants: a simple form that specifies a low +and high bound, and a full form that also specifies a bound on the capacity. +

+ +

Simple slice expressions

+ +

+For a string, array, pointer to array, or slice a, the primary expression +

+ +
+a[low : high]
+
+ +

+constructs a substring or slice. The indices low and +high select which elements of operand a appear +in the result. The result has indices starting at 0 and length equal to +high - low. +After slicing the array a +

+ +
+a := [5]int{1, 2, 3, 4, 5}
+s := a[1:4]
+
+ +

+the slice s has type []int, length 3, capacity 4, and elements +

+ +
+s[0] == 2
+s[1] == 3
+s[2] == 4
+
+ +

+For convenience, any of the indices may be omitted. A missing low +index defaults to zero; a missing high index defaults to the length of the +sliced operand: +

+ +
+a[2:]  // same as a[2 : len(a)]
+a[:3]  // same as a[0 : 3]
+a[:]   // same as a[0 : len(a)]
+
+ +

+If a is a pointer to an array, a[low : high] is shorthand for +(*a)[low : high]. +

+ +

+For arrays or strings, the indices are in range if +0 <= low <= high <= len(a), +otherwise they are out of range. +For slices, the upper index bound is the slice capacity cap(a) rather than the length. +A constant index must be non-negative and +representable by a value of type +int; for arrays or constant strings, constant indices must also be in range. +If both indices are constant, they must satisfy low <= high. +If the indices are out of range at run time, a run-time panic occurs. +

+ +

+Except for untyped strings, if the sliced operand is a string or slice, +the result of the slice operation is a non-constant value of the same type as the operand. +For untyped string operands the result is a non-constant value of type string. +If the sliced operand is an array, it must be addressable +and the result of the slice operation is a slice with the same element type as the array. +

+ +

+If the sliced operand of a valid slice expression is a nil slice, the result +is a nil slice. Otherwise, if the result is a slice, it shares its underlying +array with the operand. +

+ +
+var a [10]int
+s1 := a[3:7]   // underlying array of s1 is array a; &s1[2] == &a[5]
+s2 := s1[1:4]  // underlying array of s2 is underlying array of s1 which is array a; &s2[1] == &a[5]
+s2[1] = 42     // s2[1] == s1[2] == a[5] == 42; they all refer to the same underlying array element
+
+ + +

Full slice expressions

+ +

+For an array, pointer to array, or slice a (but not a string), the primary expression +

+ +
+a[low : high : max]
+
+ +

+constructs a slice of the same type, and with the same length and elements as the simple slice +expression a[low : high]. Additionally, it controls the resulting slice's capacity +by setting it to max - low. Only the first index may be omitted; it defaults to 0. +After slicing the array a +

+ +
+a := [5]int{1, 2, 3, 4, 5}
+t := a[1:3:5]
+
+ +

+the slice t has type []int, length 2, capacity 4, and elements +

+ +
+t[0] == 2
+t[1] == 3
+
+ +

+As for simple slice expressions, if a is a pointer to an array, +a[low : high : max] is shorthand for (*a)[low : high : max]. +If the sliced operand is an array, it must be addressable. +

+ +

+The indices are in range if 0 <= low <= high <= max <= cap(a), +otherwise they are out of range. +A constant index must be non-negative and +representable by a value of type +int; for arrays, constant indices must also be in range. +If multiple indices are constant, the constants that are present must be in range relative to each +other. +If the indices are out of range at run time, a run-time panic occurs. +

+ +

Type assertions

+ +

+For an expression x of interface type +and a type T, the primary expression +

+ +
+x.(T)
+
+ +

+asserts that x is not nil +and that the value stored in x is of type T. +The notation x.(T) is called a type assertion. +

+

+More precisely, if T is not an interface type, x.(T) asserts +that the dynamic type of x is identical +to the type T. +In this case, T must implement the (interface) type of x; +otherwise the type assertion is invalid since it is not possible for x +to store a value of type T. +If T is an interface type, x.(T) asserts that the dynamic type +of x implements the interface T. +

+

+If the type assertion holds, the value of the expression is the value +stored in x and its type is T. If the type assertion is false, +a run-time panic occurs. +In other words, even though the dynamic type of x +is known only at run time, the type of x.(T) is +known to be T in a correct program. +

+ +
+var x interface{} = 7          // x has dynamic type int and value 7
+i := x.(int)                   // i has type int and value 7
+
+type I interface { m() }
+
+func f(y I) {
+	s := y.(string)        // illegal: string does not implement I (missing method m)
+	r := y.(io.Reader)     // r has type io.Reader and the dynamic type of y must implement both I and io.Reader
+	…
+}
+
+ +

+A type assertion used in an assignment or initialization of the special form +

+ +
+v, ok = x.(T)
+v, ok := x.(T)
+var v, ok = x.(T)
+var v, ok interface{} = x.(T) // dynamic types of v and ok are T and bool
+
+ +

+yields an additional untyped boolean value. The value of ok is true +if the assertion holds. Otherwise it is false and the value of v is +the zero value for type T. +No run-time panic occurs in this case. +

+ + +

Calls

+ +

+Given an expression f of function type +F, +

+ +
+f(a1, a2, … an)
+
+ +

+calls f with arguments a1, a2, … an. +Except for one special case, arguments must be single-valued expressions +assignable to the parameter types of +F and are evaluated before the function is called. +The type of the expression is the result type +of F. +A method invocation is similar but the method itself +is specified as a selector upon a value of the receiver type for +the method. +

+ +
+math.Atan2(x, y)  // function call
+var pt *Point
+pt.Scale(3.5)     // method call with receiver pt
+
+ +

+In a function call, the function value and arguments are evaluated in +the usual order. +After they are evaluated, the parameters of the call are passed by value to the function +and the called function begins execution. +The return parameters of the function are passed by value +back to the caller when the function returns. +

+ +

+Calling a nil function value +causes a run-time panic. +

+ +

+As a special case, if the return values of a function or method +g are equal in number and individually +assignable to the parameters of another function or method +f, then the call f(g(parameters_of_g)) +will invoke f after binding the return values of +g to the parameters of f in order. The call +of f must contain no parameters other than the call of g, +and g must have at least one return value. +If f has a final ... parameter, it is +assigned the return values of g that remain after +assignment of regular parameters. +

+ +
+func Split(s string, pos int) (string, string) {
+	return s[0:pos], s[pos:]
+}
+
+func Join(s, t string) string {
+	return s + t
+}
+
+if Join(Split(value, len(value)/2)) != value {
+	log.Panic("test fails")
+}
+
+ +

+A method call x.m() is valid if the method set +of (the type of) x contains m and the +argument list can be assigned to the parameter list of m. +If x is addressable and &x's method +set contains m, x.m() is shorthand +for (&x).m(): +

+ +
+var p Point
+p.Scale(3.5)
+
+ +

+There is no distinct method type and there are no method literals. +

+ +

Passing arguments to ... parameters

+ +

+If f is variadic with a final +parameter p of type ...T, then within f +the type of p is equivalent to type []T. +If f is invoked with no actual arguments for p, +the value passed to p is nil. +Otherwise, the value passed is a new slice +of type []T with a new underlying array whose successive elements +are the actual arguments, which all must be assignable +to T. The length and capacity of the slice is therefore +the number of arguments bound to p and may differ for each +call site. +

+ +

+Given the function and calls +

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

+within Greeting, who will have the value +nil in the first call, and +[]string{"Joe", "Anna", "Eileen"} in the second. +

+ +

+If the final argument is assignable to a slice type []T and +is followed by ..., it is passed unchanged as the value +for a ...T parameter. In this case no new slice is created. +

+ +

+Given the slice s and call +

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

+within Greeting, who will have the same value as s +with the same underlying array. +

+ + +

Operators

+ +

+Operators combine operands into expressions. +

+ +
+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   = "+" | "-" | "!" | "^" | "*" | "&" | "<-" .
+
+ +

+Comparisons are discussed elsewhere. +For other binary operators, the operand types must be identical +unless the operation involves shifts or untyped constants. +For operations involving constants only, see the section on +constant expressions. +

+ +

+Except for shift operations, if one operand is an untyped constant +and the other operand is not, the constant is implicitly converted +to the type of the other operand. +

+ +

+The right operand in a shift expression must have integer type +or be an untyped constant representable by a +value of type uint. +If the left operand of a non-constant shift expression is an untyped constant, +it is first implicitly converted to the type it would assume if the shift expression were +replaced by its left operand alone. +

+ +
+var a [1024]byte
+var s uint = 33
+
+// The results of the following examples are given for 64-bit ints.
+var i = 1<<s                   // 1 has type int
+var j int32 = 1<<s             // 1 has type int32; j == 0
+var k = uint64(1<<s)           // 1 has type uint64; k == 1<<33
+var m int = 1.0<<s             // 1.0 has type int; m == 1<<33
+var n = 1.0<<s == j            // 1.0 has type int32; n == true
+var o = 1<<s == 2<<s           // 1 and 2 have type int; o == false
+var p = 1<<s == 1<<33          // 1 has type int; p == true
+var u = 1.0<<s                 // illegal: 1.0 has type float64, cannot shift
+var u1 = 1.0<<s != 0           // illegal: 1.0 has type float64, cannot shift
+var u2 = 1<<s != 1.0           // illegal: 1 has type float64, cannot shift
+var v float32 = 1<<s           // illegal: 1 has type float32, cannot shift
+var w int64 = 1.0<<33          // 1.0<<33 is a constant shift expression; w == 1<<33
+var x = a[1.0<<s]              // panics: 1.0 has type int, but 1<<33 overflows array bounds
+var b = make([]byte, 1.0<<s)   // 1.0 has type int; len(b) == 1<<33
+
+// The results of the following examples are given for 32-bit ints,
+// which means the shifts will overflow.
+var mm int = 1.0<<s            // 1.0 has type int; mm == 0
+var oo = 1<<s == 2<<s          // 1 and 2 have type int; oo == true
+var pp = 1<<s == 1<<33         // illegal: 1 has type int, but 1<<33 overflows int
+var xx = a[1.0<<s]             // 1.0 has type int; xx == a[0]
+var bb = make([]byte, 1.0<<s)  // 1.0 has type int; len(bb) == 0
+
+ +

Operator precedence

+

+Unary operators have the highest precedence. +As the ++ and -- operators form +statements, not expressions, they fall +outside the operator hierarchy. +As a consequence, statement *p++ is the same as (*p)++. +

+There are five precedence levels for binary operators. +Multiplication operators bind strongest, followed by addition +operators, comparison operators, && (logical AND), +and finally || (logical OR): +

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

+Binary operators of the same precedence associate from left to right. +For instance, x / y * z is the same as (x / y) * z. +

+ +
++x
+23 + 3*x[i]
+x <= f()
+^a >> b
+f() || g()
+x == y+1 && <-chanInt > 0
+
+ + +

Arithmetic operators

+

+Arithmetic operators apply to numeric values and yield a result of the same +type as the first operand. The four standard arithmetic operators (+, +-, *, /) apply to integer, +floating-point, and complex types; + also applies to strings. +The bitwise logical and shift operators apply to integers only. +

+ +
++    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 << integer >= 0
+>>   right shift            integer >> integer >= 0
+
+ + +

Integer operators

+ +

+For two integer values x and y, the integer quotient +q = x / y and remainder r = x % y satisfy the following +relationships: +

+ +
+x = q*y + r  and  |r| < |y|
+
+ +

+with x / y truncated towards zero +("truncated division"). +

+ +
+ x     y     x / y     x % y
+ 5     3       1         2
+-5     3      -1        -2
+ 5    -3      -1         2
+-5    -3       1        -2
+
+ +

+The one exception to this rule is that if the dividend x is +the most negative value for the int type of x, the quotient +q = x / -1 is equal to x (and r = 0) +due to two's-complement integer overflow: +

+ +
+			 x, q
+int8                     -128
+int16                  -32768
+int32             -2147483648
+int64    -9223372036854775808
+
+ +

+If the divisor is a constant, it must not be zero. +If the divisor is zero at run time, a run-time panic occurs. +If the dividend is non-negative and the divisor is a constant power of 2, +the division may be replaced by a right shift, and computing the remainder may +be replaced by a bitwise AND operation: +

+ +
+ x     x / 4     x % 4     x >> 2     x & 3
+ 11      2         3         2          3
+-11     -2        -3        -3          1
+
+ +

+The shift operators shift the left operand by the shift count specified by the +right operand, which must be non-negative. If the shift count is negative at run time, +a run-time panic occurs. +The shift operators implement arithmetic shifts if the left operand is a signed +integer and logical shifts if it is an unsigned integer. +There is no upper limit on the shift count. Shifts behave +as if the left operand is shifted n times by 1 for a shift +count of n. +As a result, x << 1 is the same as x*2 +and x >> 1 is the same as +x/2 but truncated towards negative infinity. +

+ +

+For integer operands, the unary operators ++, -, and ^ are defined as +follows: +

+ +
++x                          is 0 + x
+-x    negation              is 0 - x
+^x    bitwise complement    is m ^ x  with m = "all bits set to 1" for unsigned x
+                                      and  m = -1 for signed x
+
+ + +

Integer overflow

+ +

+For unsigned integer values, the operations +, +-, *, and << are +computed modulo 2n, where n is the bit width of +the unsigned integer's type. +Loosely speaking, these unsigned integer operations +discard high bits upon overflow, and programs may rely on "wrap around". +

+

+For signed integers, the operations +, +-, *, /, and << may legally +overflow and the resulting value exists and is deterministically defined +by the signed integer representation, the operation, and its operands. +Overflow does not cause a run-time panic. +A compiler may not optimize code under the assumption that overflow does +not occur. For instance, it may not assume that x < x + 1 is always true. +

+ + +

Floating-point operators

+ +

+For floating-point and complex numbers, ++x is the same as x, +while -x is the negation of x. +The result of a floating-point or complex division by zero is not specified beyond the +IEEE-754 standard; whether a run-time panic +occurs is implementation-specific. +

+ +

+An implementation may combine multiple floating-point operations into a single +fused operation, possibly across statements, and produce a result that differs +from the value obtained by executing and rounding the instructions individually. +An explicit floating-point type conversion rounds to +the precision of the target type, preventing fusion that would discard that rounding. +

+ +

+For instance, some architectures provide a "fused multiply and add" (FMA) instruction +that computes x*y + z without rounding the intermediate result x*y. +These examples show when a Go implementation can use that instruction: +

+ +
+// FMA allowed for computing r, because x*y is not explicitly rounded:
+r  = x*y + z
+r  = z;   r += x*y
+t  = x*y; r = t + z
+*p = x*y; r = *p + z
+r  = x*y + float64(z)
+
+// FMA disallowed for computing r, because it would omit rounding of x*y:
+r  = float64(x*y) + z
+r  = z; r += float64(x*y)
+t  = float64(x*y); r = t + z
+
+ +

String concatenation

+ +

+Strings can be concatenated using the + operator +or the += assignment operator: +

+ +
+s := "hi" + string(c)
+s += " and good bye"
+
+ +

+String addition creates a new string by concatenating the operands. +

+ + +

Comparison operators

+ +

+Comparison operators compare two operands and yield an untyped boolean value. +

+ +
+==    equal
+!=    not equal
+<     less
+<=    less or equal
+>     greater
+>=    greater or equal
+
+ +

+In any comparison, the first operand +must be assignable +to the type of the second operand, or vice versa. +

+

+The equality operators == and != apply +to operands that are comparable. +The ordering operators <, <=, >, and >= +apply to operands that are ordered. +These terms and the result of the comparisons are defined as follows: +

+ + + +

+A comparison of two interface values with identical dynamic types +causes a run-time panic if values +of that type are not comparable. This behavior applies not only to direct interface +value comparisons but also when comparing arrays of interface values +or structs with interface-valued fields. +

+ +

+Slice, map, and function values are not comparable. +However, as a special case, a slice, map, or function value may +be compared to the predeclared identifier nil. +Comparison of pointer, channel, and interface values to nil +is also allowed and follows from the general rules above. +

+ +
+const c = 3 < 4            // c is the untyped boolean constant true
+
+type MyBool bool
+var x, y int
+var (
+	// The result of a comparison is an untyped boolean.
+	// The usual assignment rules apply.
+	b3        = x == y // b3 has type bool
+	b4 bool   = x == y // b4 has type bool
+	b5 MyBool = x == y // b5 has type MyBool
+)
+
+ +

Logical operators

+ +

+Logical operators apply to boolean values +and yield a result of the same type as the operands. +The right operand is evaluated conditionally. +

+ +
+&&    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

+ +

+For an operand x of type T, the address operation +&x generates a pointer of type *T to x. +The operand must be addressable, +that is, either a variable, pointer indirection, or slice indexing +operation; or a field selector of an addressable struct operand; +or an array indexing operation of an addressable array. +As an exception to the addressability requirement, x may also be a +(possibly parenthesized) +composite literal. +If the evaluation of x would cause a run-time panic, +then the evaluation of &x does too. +

+ +

+For an operand x of pointer type *T, the pointer +indirection *x denotes the variable of type T pointed +to by x. +If x is nil, an attempt to evaluate *x +will cause a run-time panic. +

+ +
+&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

+ +

+For an operand ch of channel type, +the value of the receive operation <-ch is the value received +from the channel ch. The channel direction must permit receive operations, +and the type of the receive operation is the element type of the channel. +The expression blocks until a value is available. +Receiving from a nil channel blocks forever. +A receive operation on a closed channel can always proceed +immediately, yielding the element type's zero value +after any previously sent values have been received. +

+ +
+v1 := <-ch
+v2 = <-ch
+f(<-ch)
+<-strobe  // wait until clock pulse and discard received value
+
+ +

+A receive expression used in an assignment or initialization of the special form +

+ +
+x, ok = <-ch
+x, ok := <-ch
+var x, ok = <-ch
+var x, ok T = <-ch
+
+ +

+yields an additional untyped boolean result reporting whether the +communication succeeded. The value of ok is true +if the value received was delivered by a successful send operation to the +channel, or false if it is a zero value generated because the +channel is closed and empty. +

+ + +

Conversions

+ +

+A conversion changes the type of an expression +to the type specified by the conversion. +A conversion may appear literally in the source, or it may be implied +by the context in which an expression appears. +

+ +

+An explicit conversion is an expression of the form T(x) +where T is a type and x is an expression +that can be converted to type T. +

+ +
+Conversion = Type "(" Expression [ "," ] ")" .
+
+ +

+If the type starts with the operator * or <-, +or if the type starts with the keyword func +and has no result list, it must be parenthesized when +necessary to avoid ambiguity: +

+ +
+*Point(p)        // same as *(Point(p))
+(*Point)(p)      // p is converted to *Point
+<-chan int(c)    // same as <-(chan int(c))
+(<-chan int)(c)  // c is converted to <-chan int
+func()(x)        // function signature func() x
+(func())(x)      // x is converted to func()
+(func() int)(x)  // x is converted to func() int
+func() int(x)    // x is converted to func() int (unambiguous)
+
+ +

+A constant value x can be converted to +type T if x is representable +by a value of T. +As a special case, an integer constant x can be explicitly converted to a +string type using the +same rule +as for non-constant x. +

+ +

+Converting a constant yields a typed constant as result. +

+ +
+uint(iota)               // iota value of type uint
+float32(2.718281828)     // 2.718281828 of type float32
+complex128(1)            // 1.0 + 0.0i of type complex128
+float32(0.49999999)      // 0.5 of type float32
+float64(-1e-1000)        // 0.0 of type float64
+string('x')              // "x" of type string
+string(0x266c)           // "♬" of type string
+MyString("foo" + "bar")  // "foobar" of type MyString
+string([]byte{'a'})      // not a constant: []byte{'a'} is not a constant
+(*int)(nil)              // not a constant: nil is not a constant, *int is not a boolean, numeric, or string type
+int(1.2)                 // illegal: 1.2 cannot be represented as an int
+string(65.0)             // illegal: 65.0 is not an integer constant
+
+ +

+A non-constant value x can be converted to type T +in any of these cases: +

+ + + +

+Struct tags are ignored when comparing struct types +for identity for the purpose of conversion: +

+ +
+type Person struct {
+	Name    string
+	Address *struct {
+		Street string
+		City   string
+	}
+}
+
+var data *struct {
+	Name    string `json:"name"`
+	Address *struct {
+		Street string `json:"street"`
+		City   string `json:"city"`
+	} `json:"address"`
+}
+
+var person = (*Person)(data)  // ignoring tags, the underlying types are identical
+
+ +

+Specific rules apply to (non-constant) conversions between numeric types or +to and from a string type. +These conversions may change the representation of x +and incur a run-time cost. +All other conversions only change the type but not the representation +of x. +

+ +

+There is no linguistic mechanism to convert between pointers and integers. +The package unsafe +implements this functionality under +restricted circumstances. +

+ +

Conversions between numeric types

+ +

+For the conversion of non-constant numeric values, the following rules apply: +

+ +
    +
  1. +When converting between integer types, if the value is a signed integer, it is +sign extended to implicit infinite precision; otherwise it is zero extended. +It is then truncated to fit in the result type's size. +For example, if v := uint16(0x10F0), then uint32(int8(v)) == 0xFFFFFFF0. +The conversion always yields a valid value; there is no indication of overflow. +
  2. +
  3. +When converting a floating-point number to an integer, the fraction is discarded +(truncation towards zero). +
  4. +
  5. +When converting an integer or floating-point number to a floating-point type, +or a complex number to another complex type, the result value is rounded +to the precision specified by the destination type. +For instance, the value of a variable x of type float32 +may be stored using additional precision beyond that of an IEEE-754 32-bit number, +but float32(x) represents the result of rounding x's value to +32-bit precision. Similarly, x + 0.1 may use more than 32 bits +of precision, but float32(x + 0.1) does not. +
  6. +
+ +

+In all non-constant conversions involving floating-point or complex values, +if the result type cannot represent the value the conversion +succeeds but the result value is implementation-dependent. +

+ +

Conversions to and from a string type

+ +
    +
  1. +Converting a signed or unsigned integer value to a string type yields a +string containing the UTF-8 representation of the integer. Values outside +the range of valid Unicode code points are converted to "\uFFFD". + +
    +string('a')       // "a"
    +string(-1)        // "\ufffd" == "\xef\xbf\xbd"
    +string(0xf8)      // "\u00f8" == "ø" == "\xc3\xb8"
    +type MyString string
    +MyString(0x65e5)  // "\u65e5" == "日" == "\xe6\x97\xa5"
    +
    +
  2. + +
  3. +Converting a slice of bytes to a string type yields +a string whose successive bytes are the elements of the slice. + +
    +string([]byte{'h', 'e', 'l', 'l', '\xc3', '\xb8'})   // "hellø"
    +string([]byte{})                                     // ""
    +string([]byte(nil))                                  // ""
    +
    +type MyBytes []byte
    +string(MyBytes{'h', 'e', 'l', 'l', '\xc3', '\xb8'})  // "hellø"
    +
    +
  4. + +
  5. +Converting a slice of runes to a string type yields +a string that is the concatenation of the individual rune values +converted to strings. + +
    +string([]rune{0x767d, 0x9d6c, 0x7fd4})   // "\u767d\u9d6c\u7fd4" == "白鵬翔"
    +string([]rune{})                         // ""
    +string([]rune(nil))                      // ""
    +
    +type MyRunes []rune
    +string(MyRunes{0x767d, 0x9d6c, 0x7fd4})  // "\u767d\u9d6c\u7fd4" == "白鵬翔"
    +
    +
  6. + +
  7. +Converting a value of a string type to a slice of bytes type +yields a slice whose successive elements are the bytes of the string. + +
    +[]byte("hellø")   // []byte{'h', 'e', 'l', 'l', '\xc3', '\xb8'}
    +[]byte("")        // []byte{}
    +
    +MyBytes("hellø")  // []byte{'h', 'e', 'l', 'l', '\xc3', '\xb8'}
    +
    +
  8. + +
  9. +Converting a value of a string type to a slice of runes type +yields a slice containing the individual Unicode code points of the string. + +
    +[]rune(MyString("白鵬翔"))  // []rune{0x767d, 0x9d6c, 0x7fd4}
    +[]rune("")                 // []rune{}
    +
    +MyRunes("白鵬翔")           // []rune{0x767d, 0x9d6c, 0x7fd4}
    +
    +
  10. +
+ +

Conversions from slice to array pointer

+ +

+Converting a slice to an array pointer yields a pointer to the underlying array of the slice. +If the length of the slice is less than the length of the array, +a run-time panic occurs. +

+ +
+s := make([]byte, 2, 4)
+s0 := (*[0]byte)(s)      // s0 != nil
+s1 := (*[1]byte)(s[1:])  // &s1[0] == &s[1]
+s2 := (*[2]byte)(s)      // &s2[0] == &s[0]
+s4 := (*[4]byte)(s)      // panics: len([4]byte) > len(s)
+
+var t []string
+t0 := (*[0]string)(t)    // t0 == nil
+t1 := (*[1]string)(t)    // panics: len([1]string) > len(t)
+
+u := make([]byte, 0)
+u0 := (*[0]byte)(u)      // u0 != nil
+
+ +

Constant expressions

+ +

+Constant expressions may contain only constant +operands and are evaluated at compile time. +

+ +

+Untyped boolean, numeric, and string constants may be used as operands +wherever it is legal to use an operand of boolean, numeric, or string type, +respectively. +

+ +

+A constant comparison always yields +an untyped boolean constant. If the left operand of a constant +shift expression is an untyped constant, the +result is an integer constant; otherwise it is a constant of the same +type as the left operand, which must be of +integer type. +

+ +

+Any other operation on untyped constants results in an untyped constant of the +same kind; that is, a boolean, integer, floating-point, complex, or string +constant. +If the untyped operands of a binary operation (other than a shift) are of +different kinds, the result is of the operand's kind that appears later in this +list: integer, rune, floating-point, complex. +For example, an untyped integer constant divided by an +untyped complex constant yields an untyped complex constant. +

+ +
+const a = 2 + 3.0          // a == 5.0   (untyped floating-point constant)
+const b = 15 / 4           // b == 3     (untyped integer constant)
+const c = 15 / 4.0         // c == 3.75  (untyped floating-point constant)
+const Θ float64 = 3/2      // Θ == 1.0   (type float64, 3/2 is integer division)
+const Π float64 = 3/2.     // Π == 1.5   (type float64, 3/2. is float division)
+const d = 1 << 3.0         // d == 8     (untyped integer constant)
+const e = 1.0 << 3         // e == 8     (untyped integer constant)
+const f = int32(1) << 33   // illegal    (constant 8589934592 overflows int32)
+const g = float64(2) >> 1  // illegal    (float64(2) is a typed floating-point constant)
+const h = "foo" > "bar"    // h == true  (untyped boolean constant)
+const j = true             // j == true  (untyped boolean constant)
+const k = 'w' + 1          // k == 'x'   (untyped rune constant)
+const l = "hi"             // l == "hi"  (untyped string constant)
+const m = string(k)        // m == "x"   (type string)
+const Σ = 1 - 0.707i       //            (untyped complex constant)
+const Δ = Σ + 2.0e-4       //            (untyped complex constant)
+const Φ = iota*1i - 1/1i   //            (untyped complex constant)
+
+ +

+Applying the built-in function complex to untyped +integer, rune, or floating-point constants yields +an untyped complex constant. +

+ +
+const ic = complex(0, c)   // ic == 3.75i  (untyped complex constant)
+const iΘ = complex(0, Θ)   // iΘ == 1i     (type complex128)
+
+ +

+Constant expressions are always evaluated exactly; intermediate values and the +constants themselves may require precision significantly larger than supported +by any predeclared type in the language. The following are legal declarations: +

+ +
+const Huge = 1 << 100         // Huge == 1267650600228229401496703205376  (untyped integer constant)
+const Four int8 = Huge >> 98  // Four == 4                                (type int8)
+
+ +

+The divisor of a constant division or remainder operation must not be zero: +

+ +
+3.14 / 0.0   // illegal: division by zero
+
+ +

+The values of typed constants must always be accurately +representable by values +of the constant type. The following constant expressions are illegal: +

+ +
+uint(-1)     // -1 cannot be represented as a uint
+int(3.14)    // 3.14 cannot be represented as an int
+int64(Huge)  // 1267650600228229401496703205376 cannot be represented as an int64
+Four * 300   // operand 300 cannot be represented as an int8 (type of Four)
+Four * 100   // product 400 cannot be represented as an int8 (type of Four)
+
+ +

+The mask used by the unary bitwise complement operator ^ matches +the rule for non-constants: the mask is all 1s for unsigned constants +and -1 for signed and untyped constants. +

+ +
+^1         // untyped integer constant, equal to -2
+uint8(^1)  // illegal: same as uint8(-2), -2 cannot be represented as a uint8
+^uint8(1)  // typed uint8 constant, same as 0xFF ^ uint8(1) = uint8(0xFE)
+int8(^1)   // same as int8(-2)
+^int8(1)   // same as -1 ^ int8(1) = -2
+
+ +

+Implementation restriction: A compiler may use rounding while +computing untyped floating-point or complex constant expressions; see +the implementation restriction in the section +on constants. This rounding may cause a +floating-point constant expression to be invalid in an integer +context, even if it would be integral when calculated using infinite +precision, and vice versa. +

+ + +

Order of evaluation

+ +

+At package level, initialization dependencies +determine the evaluation order of individual initialization expressions in +variable declarations. +Otherwise, when evaluating the operands of an +expression, assignment, or +return statement, +all function calls, method calls, and +communication operations are evaluated in lexical left-to-right +order. +

+ +

+For example, in the (function-local) assignment +

+
+y[f()], ok = g(h(), i()+x[j()], <-c), k()
+
+

+the function calls and communication happen in the order +f(), h(), i(), j(), +<-c, g(), and k(). +However, the order of those events compared to the evaluation +and indexing of x and the evaluation +of y is not specified. +

+ +
+a := 1
+f := func() int { a++; return a }
+x := []int{a, f()}            // x may be [1, 2] or [2, 2]: evaluation order between a and f() is not specified
+m := map[int]int{a: 1, a: 2}  // m may be {2: 1} or {2: 2}: evaluation order between the two map assignments is not specified
+n := map[int]int{a: f()}      // n may be {2: 3} or {3: 3}: evaluation order between the key and the value is not specified
+
+ +

+At package level, initialization dependencies override the left-to-right rule +for individual initialization expressions, but not for operands within each +expression: +

+ +
+var a, b, c = f() + v(), g(), sqr(u()) + v()
+
+func f() int        { return c }
+func g() int        { return a }
+func sqr(x int) int { return x*x }
+
+// functions u and v are independent of all other variables and functions
+
+ +

+The function calls happen in the order +u(), sqr(), v(), +f(), v(), and g(). +

+ +

+Floating-point operations within a single expression are evaluated according to +the associativity of the operators. Explicit parentheses affect the evaluation +by overriding the default associativity. +In the expression x + (y + z) the addition y + z +is performed before adding x. +

+ +

Statements

+ +

+Statements control execution. +

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

Terminating statements

+ +

+A terminating statement interrupts the regular flow of control in +a block. The following statements are terminating: +

+ +
    +
  1. + A "return" or + "goto" statement. + +
    +
  2. + +
  3. + A call to the built-in function + panic. + +
    +
  4. + +
  5. + A block in which the statement list ends in a terminating statement. + +
    +
  6. + +
  7. + An "if" statement in which: +
      +
    • the "else" branch is present, and
    • +
    • both branches are terminating statements.
    • +
    +
  8. + +
  9. + A "for" statement in which: +
      +
    • there are no "break" statements referring to the "for" statement, and
    • +
    • the loop condition is absent, and
    • +
    • the "for" statement does not use a range clause.
    • +
    +
  10. + +
  11. + A "switch" statement in which: +
      +
    • there are no "break" statements referring to the "switch" statement,
    • +
    • there is a default case, and
    • +
    • the statement lists in each case, including the default, end in a terminating + statement, or a possibly labeled "fallthrough" + statement.
    • +
    +
  12. + +
  13. + A "select" statement in which: +
      +
    • there are no "break" statements referring to the "select" statement, and
    • +
    • the statement lists in each case, including the default if present, + end in a terminating statement.
    • +
    +
  14. + +
  15. + A labeled statement labeling + a terminating statement. +
  16. +
+ +

+All other statements are not terminating. +

+ +

+A statement list ends in a terminating statement if the list +is not empty and its final non-empty statement is terminating. +

+ + +

Empty statements

+ +

+The empty statement does nothing. +

+ +
+EmptyStmt = .
+
+ + +

Labeled statements

+ +

+A labeled statement may be the target of a goto, +break or continue statement. +

+ +
+LabeledStmt = Label ":" Statement .
+Label       = identifier .
+
+ +
+Error: log.Panic("error encountered")
+
+ + +

Expression statements

+ +

+With the exception of specific built-in functions, +function and method calls and +receive operations +can appear in statement context. Such statements may be parenthesized. +

+ +
+ExpressionStmt = Expression .
+
+ +

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

+ +
+append cap complex imag len make new real
+unsafe.Add unsafe.Alignof unsafe.Offsetof unsafe.Sizeof unsafe.Slice
+
+ +
+h(x+y)
+f.Close()
+<-ch
+(<-ch)
+len("foo")  // illegal if len is the built-in function
+
+ + +

Send statements

+ +

+A send statement sends a value on a channel. +The channel expression must be of channel type, +the channel direction must permit send operations, +and the type of the value to be sent must be assignable +to the channel's element type. +

+ +
+SendStmt = Channel "<-" Expression .
+Channel  = Expression .
+
+ +

+Both the channel and the value expression are evaluated before communication +begins. Communication blocks until the send can proceed. +A send on an unbuffered channel can proceed if a receiver is ready. +A send on a buffered channel can proceed if there is room in the buffer. +A send on a closed channel proceeds by causing a run-time panic. +A send on a nil channel blocks forever. +

+ +
+ch <- 3  // send value 3 to channel ch
+
+ + +

IncDec statements

+ +

+The "++" and "--" statements increment or decrement their operands +by the untyped constant 1. +As with an assignment, the operand must be addressable +or a map index expression. +

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

+The following assignment statements are semantically +equivalent: +

+ +
+IncDec statement    Assignment
+x++                 x += 1
+x--                 x -= 1
+
+ + +

Assignments

+ +
+Assignment = ExpressionList assign_op ExpressionList .
+
+assign_op = [ add_op | mul_op ] "=" .
+
+ +

+Each left-hand side operand must be addressable, +a map index expression, or (for = assignments only) the +blank identifier. +Operands may be parenthesized. +

+ +
+x = 1
+*p = f()
+a[i] = 23
+(k) = <-ch  // same as: k = <-ch
+
+ +

+An assignment operation x op= +y where op is a binary arithmetic operator +is equivalent to x = x op +(y) but evaluates x +only once. The op= construct is a single token. +In assignment operations, both the left- and right-hand expression lists +must contain exactly one single-valued expression, and the left-hand +expression must not be the blank identifier. +

+ +
+a[i] <<= 2
+i &^= 1<<n
+
+ +

+A tuple assignment assigns the individual elements of a multi-valued +operation to a list of variables. There are two forms. In the +first, the right hand operand is a single multi-valued expression +such as a function call, a channel or +map operation, or a type assertion. +The number of operands on the left +hand side must match the number of values. For instance, if +f is a function returning two values, +

+ +
+x, y = f()
+
+ +

+assigns the first value to x and the second to y. +In the second form, the number of operands on the left must equal the number +of expressions on the right, each of which must be single-valued, and the +nth expression on the right is assigned to the nth +operand on the left: +

+ +
+one, two, three = '一', '二', '三'
+
+ +

+The blank identifier provides a way to +ignore right-hand side values in an assignment: +

+ +
+_ = x       // evaluate x but ignore it
+x, _ = f()  // evaluate f() but ignore second result value
+
+ +

+The assignment proceeds in two phases. +First, the operands of index expressions +and pointer indirections +(including implicit pointer indirections in selectors) +on the left and the expressions on the right are all +evaluated in the usual order. +Second, the assignments are carried out in left-to-right order. +

+ +
+a, b = b, a  // exchange a and b
+
+x := []int{1, 2, 3}
+i := 0
+i, x[i] = 1, 2  // set i = 1, x[0] = 2
+
+i = 0
+x[i], i = 2, 1  // set x[0] = 2, i = 1
+
+x[0], x[0] = 1, 2  // set x[0] = 1, then x[0] = 2 (so x[0] == 2 at end)
+
+x[1], x[3] = 4, 5  // set x[1] = 4, then panic setting x[3] = 5.
+
+type Point struct { x, y int }
+var p *Point
+x[2], p.x = 6, 7  // set x[2] = 6, then panic setting p.x = 7
+
+i = 2
+x = []int{3, 5, 7}
+for i, x[i] = range x {  // set i, x[2] = 0, x[0]
+	break
+}
+// after this loop, i == 0 and x == []int{3, 5, 3}
+
+ +

+In assignments, each value must be assignable +to the type of the operand to which it is assigned, with the following special cases: +

+ +
    +
  1. + Any typed value may be assigned to the blank identifier. +
  2. + +
  3. + If an untyped constant + is assigned to a variable of interface type or the blank identifier, + the constant is first implicitly converted to its + default type. +
  4. + +
  5. + If an untyped boolean value is assigned to a variable of interface type or + the blank identifier, it is first implicitly converted to type bool. +
  6. +
+ +

If statements

+ +

+"If" statements specify the conditional execution of two branches +according to the value of a boolean expression. If the expression +evaluates to true, the "if" branch is executed, otherwise, if +present, the "else" branch is executed. +

+ +
+IfStmt = "if" [ SimpleStmt ";" ] Expression Block [ "else" ( IfStmt | Block ) ] .
+
+ +
+if x > max {
+	x = max
+}
+
+ +

+The expression may be preceded by a simple statement, which +executes before the expression is evaluated. +

+ +
+if x := f(); x < y {
+	return x
+} else if x > z {
+	return z
+} else {
+	return y
+}
+
+ + +

Switch statements

+ +

+"Switch" statements provide multi-way execution. +An expression or type is compared to the "cases" +inside the "switch" to determine which branch +to execute. +

+ +
+SwitchStmt = ExprSwitchStmt | TypeSwitchStmt .
+
+ +

+There are two forms: expression switches and type switches. +In an expression switch, the cases contain expressions that are compared +against the value of the switch expression. +In a type switch, the cases contain types that are compared against the +type of a specially annotated switch expression. +The switch expression is evaluated exactly once in a switch statement. +

+ +

Expression switches

+ +

+In an expression switch, +the switch expression is evaluated and +the case expressions, which need not be constants, +are evaluated left-to-right and top-to-bottom; the first one that equals the +switch expression +triggers execution of the statements of the associated case; +the other cases are skipped. +If no case matches and there is a "default" case, +its statements are executed. +There can be at most one default case and it may appear anywhere in the +"switch" statement. +A missing switch expression is equivalent to the boolean value +true. +

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

+If the switch expression evaluates to an untyped constant, it is first implicitly +converted to its default type. +The predeclared untyped value nil cannot be used as a switch expression. +The switch expression type must be comparable. +

+ +

+If a case expression is untyped, it is first implicitly converted +to the type of the switch expression. +For each (possibly converted) case expression x and the value t +of the switch expression, x == t must be a valid comparison. +

+ +

+In other words, the switch expression is treated as if it were used to declare and +initialize a temporary variable t without explicit type; it is that +value of t against which each case expression x is tested +for equality. +

+ +

+In a case or default clause, the last non-empty statement +may be a (possibly labeled) +"fallthrough" statement to +indicate that control should flow from the end of this clause to +the first statement of the next clause. +Otherwise control flows to the end of the "switch" statement. +A "fallthrough" statement may appear as the last statement of all +but the last clause of an expression switch. +

+ +

+The switch expression may be preceded by a simple statement, which +executes before the expression is evaluated. +

+ +
+switch tag {
+default: s3()
+case 0, 1, 2, 3: s1()
+case 4, 5, 6, 7: s2()
+}
+
+switch x := f(); {  // missing switch expression means "true"
+case x < 0: return -x
+default: return x
+}
+
+switch {
+case x < y: f1()
+case x < z: f2()
+case x == 4: f3()
+}
+
+ +

+Implementation restriction: A compiler may disallow multiple case +expressions evaluating to the same constant. +For instance, the current compilers disallow duplicate integer, +floating point, or string constants in case expressions. +

+ +

Type switches

+ +

+A type switch compares types rather than values. It is otherwise similar +to an expression switch. It is marked by a special switch expression that +has the form of a type assertion +using the keyword type rather than an actual type: +

+ +
+switch x.(type) {
+// cases
+}
+
+ +

+Cases then match actual types T against the dynamic type of the +expression x. As with type assertions, x must be of +interface type, and each non-interface type +T listed in a case must implement the type of x. +The types listed in the cases of a type switch must all be +different. +

+ +
+TypeSwitchStmt  = "switch" [ SimpleStmt ";" ] TypeSwitchGuard "{" { TypeCaseClause } "}" .
+TypeSwitchGuard = [ identifier ":=" ] PrimaryExpr "." "(" "type" ")" .
+TypeCaseClause  = TypeSwitchCase ":" StatementList .
+TypeSwitchCase  = "case" TypeList | "default" .
+TypeList        = Type { "," Type } .
+
+ +

+The TypeSwitchGuard may include a +short variable declaration. +When that form is used, the variable is declared at the end of the +TypeSwitchCase in the implicit block of each clause. +In clauses with a case listing exactly one type, the variable +has that type; otherwise, the variable has the type of the expression +in the TypeSwitchGuard. +

+ +

+Instead of a type, a case may use the predeclared identifier +nil; +that case is selected when the expression in the TypeSwitchGuard +is a nil interface value. +There may be at most one nil case. +

+ +

+Given an expression x of type interface{}, +the following type switch: +

+ +
+switch i := x.(type) {
+case nil:
+	printString("x is nil")                // type of i is type of x (interface{})
+case int:
+	printInt(i)                            // type of i is int
+case float64:
+	printFloat64(i)                        // type of i is float64
+case func(int) float64:
+	printFunction(i)                       // type of i is func(int) float64
+case bool, string:
+	printString("type is bool or string")  // type of i is type of x (interface{})
+default:
+	printString("don't know the type")     // type of i is type of x (interface{})
+}
+
+ +

+could be rewritten: +

+ +
+v := x  // x is evaluated exactly once
+if v == nil {
+	i := v                                 // type of i is type of x (interface{})
+	printString("x is nil")
+} else if i, isInt := v.(int); isInt {
+	printInt(i)                            // type of i is int
+} else if i, isFloat64 := v.(float64); isFloat64 {
+	printFloat64(i)                        // type of i is float64
+} else if i, isFunc := v.(func(int) float64); isFunc {
+	printFunction(i)                       // type of i is func(int) float64
+} else {
+	_, isBool := v.(bool)
+	_, isString := v.(string)
+	if isBool || isString {
+		i := v                         // type of i is type of x (interface{})
+		printString("type is bool or string")
+	} else {
+		i := v                         // type of i is type of x (interface{})
+		printString("don't know the type")
+	}
+}
+
+ +

+The type switch guard may be preceded by a simple statement, which +executes before the guard is evaluated. +

+ +

+The "fallthrough" statement is not permitted in a type switch. +

+ +

For statements

+ +

+A "for" statement specifies repeated execution of a block. There are three forms: +The iteration may be controlled by a single condition, a "for" clause, or a "range" clause. +

+ +
+ForStmt = "for" [ Condition | ForClause | RangeClause ] Block .
+Condition = Expression .
+
+ +

For statements with single condition

+ +

+In its simplest form, a "for" statement specifies the repeated execution of +a block as long as a boolean condition evaluates to true. +The condition is evaluated before each iteration. +If the condition is absent, it is equivalent to the boolean value +true. +

+ +
+for a < b {
+	a *= 2
+}
+
+ +

For statements with for clause

+ +

+A "for" statement with a ForClause is also controlled by its condition, but +additionally it may specify an init +and a post statement, such as an assignment, +an increment or decrement statement. The init statement may be a +short variable declaration, but the post statement must not. +Variables declared by the init statement are re-used in each iteration. +

+ +
+ForClause = [ InitStmt ] ";" [ Condition ] ";" [ PostStmt ] .
+InitStmt = SimpleStmt .
+PostStmt = SimpleStmt .
+
+ +
+for i := 0; i < 10; i++ {
+	f(i)
+}
+
+ +

+If non-empty, the init statement is executed once before evaluating the +condition for the first iteration; +the post statement is executed after each execution of the block (and +only if the block was executed). +Any element of the ForClause may be empty but the +semicolons are +required unless there is only a condition. +If the condition is absent, it is equivalent to the boolean value +true. +

+ +
+for cond { S() }    is the same as    for ; cond ; { S() }
+for      { S() }    is the same as    for true     { S() }
+
+ +

For statements with range clause

+ +

+A "for" statement with a "range" clause +iterates through all entries of an array, slice, string or map, +or values received on a channel. For each entry it assigns iteration values +to corresponding iteration variables if present and then executes the block. +

+ +
+RangeClause = [ ExpressionList "=" | IdentifierList ":=" ] "range" Expression .
+
+ +

+The expression on the right in the "range" clause is called the range expression, +which may be an array, pointer to an array, slice, string, map, or channel permitting +receive operations. +As with an assignment, if present the operands on the left must be +addressable or map index expressions; they +denote the iteration variables. If the range expression is a channel, at most +one iteration variable is permitted, otherwise there may be up to two. +If the last iteration variable is the blank identifier, +the range clause is equivalent to the same clause without that identifier. +

+ +

+The range expression x is evaluated once before beginning the loop, +with one exception: if at most one iteration variable is present and +len(x) is constant, +the range expression is not evaluated. +

+ +

+Function calls on the left are evaluated once per iteration. +For each iteration, iteration values are produced as follows +if the respective iteration variables are present: +

+ +
+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
+
+ +
    +
  1. +For an array, pointer to array, or slice value a, the index iteration +values are produced in increasing order, starting at element index 0. +If at most one iteration variable is present, the range loop produces +iteration values from 0 up to len(a)-1 and does not index into the array +or slice itself. For a nil slice, the number of iterations is 0. +
  2. + +
  3. +For a string value, the "range" clause iterates over the Unicode code points +in the string starting at byte index 0. On successive iterations, the index value will be the +index of the first byte of successive UTF-8-encoded code points in the string, +and the second value, of type rune, will be the value of +the corresponding code point. If the iteration encounters an invalid +UTF-8 sequence, the second value will be 0xFFFD, +the Unicode replacement character, and the next iteration will advance +a single byte in the string. +
  4. + +
  5. +The iteration order over maps is not specified +and is not guaranteed to be the same from one iteration to the next. +If a map entry that has not yet been reached is removed during iteration, +the corresponding iteration value will not be produced. If a map entry is +created during iteration, that entry may be produced during the iteration or +may be skipped. The choice may vary for each entry created and from one +iteration to the next. +If the map is nil, the number of iterations is 0. +
  6. + +
  7. +For channels, the iteration values produced are the successive values sent on +the channel until the channel is closed. If the channel +is nil, the range expression blocks forever. +
  8. +
+ +

+The iteration values are assigned to the respective +iteration variables as in an assignment statement. +

+ +

+The iteration variables may be declared by the "range" clause using a form of +short variable declaration +(:=). +In this case their types are set to the types of the respective iteration values +and their scope is the block of the "for" +statement; they are re-used in each iteration. +If the iteration variables are declared outside the "for" statement, +after execution their values will be those of the last iteration. +

+ +
+var testdata *struct {
+	a *[7]int
+}
+for i, _ := range testdata.a {
+	// testdata.a is never evaluated; len(testdata.a) is constant
+	// i ranges from 0 to 6
+	f(i)
+}
+
+var a [10]string
+for i, s := range a {
+	// type of i is int
+	// type of s is string
+	// s == a[i]
+	g(i, s)
+}
+
+var key string
+var val interface{}  // element type of m is assignable to val
+m := map[string]int{"mon":0, "tue":1, "wed":2, "thu":3, "fri":4, "sat":5, "sun":6}
+for key, val = range m {
+	h(key, val)
+}
+// key == last map key encountered in iteration
+// val == map[key]
+
+var ch chan Work = producer()
+for w := range ch {
+	doWork(w)
+}
+
+// empty a channel
+for range ch {}
+
+ + +

Go statements

+ +

+A "go" statement starts the execution of a function call +as an independent concurrent thread of control, or goroutine, +within the same address space. +

+ +
+GoStmt = "go" Expression .
+
+ +

+The expression must be a function or method call; it cannot be parenthesized. +Calls of built-in functions are restricted as for +expression statements. +

+ +

+The function value and parameters are +evaluated as usual +in the calling goroutine, but +unlike with a regular call, program execution does not wait +for the invoked function to complete. +Instead, the function begins executing independently +in a new goroutine. +When the function terminates, its goroutine also terminates. +If the function has any return values, they are discarded when the +function completes. +

+ +
+go Server()
+go func(ch chan<- bool) { for { sleep(10); ch <- true }} (c)
+
+ + +

Select statements

+ +

+A "select" statement chooses which of a set of possible +send or +receive +operations will proceed. +It looks similar to a +"switch" statement but with the +cases all referring to communication operations. +

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

+A case with a RecvStmt may assign the result of a RecvExpr to one or +two variables, which may be declared using a +short variable declaration. +The RecvExpr must be a (possibly parenthesized) receive operation. +There can be at most one default case and it may appear anywhere +in the list of cases. +

+ +

+Execution of a "select" statement proceeds in several steps: +

+ +
    +
  1. +For all the cases in the statement, the channel operands of receive operations +and the channel and right-hand-side expressions of send statements are +evaluated exactly once, in source order, upon entering the "select" statement. +The result is a set of channels to receive from or send to, +and the corresponding values to send. +Any side effects in that evaluation will occur irrespective of which (if any) +communication operation is selected to proceed. +Expressions on the left-hand side of a RecvStmt with a short variable declaration +or assignment are not yet evaluated. +
  2. + +
  3. +If one or more of the communications can proceed, +a single one that can proceed is chosen via a uniform pseudo-random selection. +Otherwise, if there is a default case, that case is chosen. +If there is no default case, the "select" statement blocks until +at least one of the communications can proceed. +
  4. + +
  5. +Unless the selected case is the default case, the respective communication +operation is executed. +
  6. + +
  7. +If the selected case is a RecvStmt with a short variable declaration or +an assignment, the left-hand side expressions are evaluated and the +received value (or values) are assigned. +
  8. + +
  9. +The statement list of the selected case is executed. +
  10. +
+ +

+Since communication on nil channels can never proceed, +a select with only nil channels and no default case blocks forever. +

+ +
+var a []int
+var c, c1, c2, c3, c4 chan int
+var i1, i2 int
+select {
+case i1 = <-c1:
+	print("received ", i1, " from c1\n")
+case c2 <- i2:
+	print("sent ", i2, " to c2\n")
+case i3, ok := (<-c3):  // same as: i3, ok := <-c3
+	if ok {
+		print("received ", i3, " from c3\n")
+	} else {
+		print("c3 is closed\n")
+	}
+case a[f()] = <-c4:
+	// same as:
+	// case t := <-c4
+	//	a[f()] = t
+default:
+	print("no communication\n")
+}
+
+for {  // send random sequence of bits to c
+	select {
+	case c <- 0:  // note: no statement, no fallthrough, no folding of cases
+	case c <- 1:
+	}
+}
+
+select {}  // block forever
+
+ + +

Return statements

+ +

+A "return" statement in a function F terminates the execution +of F, and optionally provides one or more result values. +Any functions deferred by F +are executed before F returns to its caller. +

+ +
+ReturnStmt = "return" [ ExpressionList ] .
+
+ +

+In a function without a result type, a "return" statement must not +specify any result values. +

+
+func noResult() {
+	return
+}
+
+ +

+There are three ways to return values from a function with a result +type: +

+ +
    +
  1. The return value or values may be explicitly listed + in the "return" statement. Each expression must be single-valued + and assignable + to the corresponding element of the function's result type. +
    +func simpleF() int {
    +	return 2
    +}
    +
    +func complexF1() (re float64, im float64) {
    +	return -7.0, -4.0
    +}
    +
    +
  2. +
  3. The expression list in the "return" statement may be a single + call to a multi-valued function. The effect is as if each value + returned from that function were assigned to a temporary + variable with the type of the respective value, followed by a + "return" statement listing these variables, at which point the + rules of the previous case apply. +
    +func complexF2() (re float64, im float64) {
    +	return complexF1()
    +}
    +
    +
  4. +
  5. The expression list may be empty if the function's result + type specifies names for its result parameters. + The result parameters act as ordinary local variables + and the function may assign values to them as necessary. + The "return" statement returns the values of these variables. +
    +func complexF3() (re float64, im float64) {
    +	re = 7.0
    +	im = 4.0
    +	return
    +}
    +
    +func (devnull) Write(p []byte) (n int, _ error) {
    +	n = len(p)
    +	return
    +}
    +
    +
  6. +
+ +

+Regardless of how they are declared, all the result values are initialized to +the zero values for their type upon entry to the +function. A "return" statement that specifies results sets the result parameters before +any deferred functions are executed. +

+ +

+Implementation restriction: A compiler may disallow an empty expression list +in a "return" statement if a different entity (constant, type, or variable) +with the same name as a result parameter is in +scope at the place of the return. +

+ +
+func f(n int) (res int, err error) {
+	if _, err := f(n-1); err != nil {
+		return  // invalid return statement: err is shadowed
+	}
+	return
+}
+
+ +

Break statements

+ +

+A "break" statement terminates execution of the innermost +"for", +"switch", or +"select" statement +within the same function. +

+ +
+BreakStmt = "break" [ Label ] .
+
+ +

+If there is a label, it must be that of an enclosing +"for", "switch", or "select" statement, +and that is the one whose execution terminates. +

+ +
+OuterLoop:
+	for i = 0; i < n; i++ {
+		for j = 0; j < m; j++ {
+			switch a[i][j] {
+			case nil:
+				state = Error
+				break OuterLoop
+			case item:
+				state = Found
+				break OuterLoop
+			}
+		}
+	}
+
+ +

Continue statements

+ +

+A "continue" statement begins the next iteration of the +innermost "for" loop at its post statement. +The "for" loop must be within the same function. +

+ +
+ContinueStmt = "continue" [ Label ] .
+
+ +

+If there is a label, it must be that of an enclosing +"for" statement, and that is the one whose execution +advances. +

+ +
+RowLoop:
+	for y, row := range rows {
+		for x, data := range row {
+			if data == endOfRow {
+				continue RowLoop
+			}
+			row[x] = data + bias(x, y)
+		}
+	}
+
+ +

Goto statements

+ +

+A "goto" statement transfers control to the statement with the corresponding label +within the same function. +

+ +
+GotoStmt = "goto" Label .
+
+ +
+goto Error
+
+ +

+Executing the "goto" statement must not cause any variables to come into +scope that were not already in scope at the point of the goto. +For instance, this example: +

+ +
+	goto L  // BAD
+	v := 3
+L:
+
+ +

+is erroneous because the jump to label L skips +the creation of v. +

+ +

+A "goto" statement outside a block cannot jump to a label inside that block. +For instance, this example: +

+ +
+if n%2 == 1 {
+	goto L1
+}
+for n > 0 {
+	f()
+	n--
+L1:
+	f()
+	n--
+}
+
+ +

+is erroneous because the label L1 is inside +the "for" statement's block but the goto is not. +

+ +

Fallthrough statements

+ +

+A "fallthrough" statement transfers control to the first statement of the +next case clause in an expression "switch" statement. +It may be used only as the final non-empty statement in such a clause. +

+ +
+FallthroughStmt = "fallthrough" .
+
+ + +

Defer statements

+ +

+A "defer" statement invokes a function whose execution is deferred +to the moment the surrounding function returns, either because the +surrounding function executed a return statement, +reached the end of its function body, +or because the corresponding goroutine is panicking. +

+ +
+DeferStmt = "defer" Expression .
+
+ +

+The expression must be a function or method call; it cannot be parenthesized. +Calls of built-in functions are restricted as for +expression statements. +

+ +

+Each time a "defer" statement +executes, the function value and parameters to the call are +evaluated as usual +and saved anew but the actual function is not invoked. +Instead, deferred functions are invoked immediately before +the surrounding function returns, in the reverse order +they were deferred. That is, if the surrounding function +returns through an explicit return statement, +deferred functions are executed after any result parameters are set +by that return statement but before the function returns to its caller. +If a deferred function value evaluates +to nil, execution panics +when the function is invoked, not when the "defer" statement is executed. +

+ +

+For instance, if the deferred function is +a function literal and the surrounding +function has named result parameters that +are in scope within the literal, the deferred function may access and modify +the result parameters before they are returned. +If the deferred function has any return values, they are discarded when +the function completes. +(See also the section on handling panics.) +

+ +
+lock(l)
+defer unlock(l)  // unlocking happens before surrounding function returns
+
+// prints 3 2 1 0 before surrounding function returns
+for i := 0; i <= 3; i++ {
+	defer fmt.Print(i)
+}
+
+// f returns 42
+func f() (result int) {
+	defer func() {
+		// result is accessed after it was set to 6 by the return statement
+		result *= 7
+	}()
+	return 6
+}
+
+ +

Built-in functions

+ +

+Built-in functions are +predeclared. +They are called like any other function but some of them +accept a type instead of an expression as the first argument. +

+ +

+The built-in functions do not have standard Go types, +so they can only appear in call expressions; +they cannot be used as function values. +

+ +

Close

+ +

+For a channel c, the built-in function close(c) +records that no more values will be sent on the channel. +It is an error if c is a receive-only channel. +Sending to or closing a closed channel causes a run-time panic. +Closing the nil channel also causes a run-time panic. +After calling close, and after any previously +sent values have been received, receive operations will return +the zero value for the channel's type without blocking. +The multi-valued receive operation +returns a received value along with an indication of whether the channel is closed. +

+ + +

Length and capacity

+ +

+The built-in functions len and cap take arguments +of various types and return a result of type int. +The implementation guarantees that the result always fits into an int. +

+ +
+Call      Argument type    Result
+
+len(s)    string type      string length in bytes
+          [n]T, *[n]T      array length (== n)
+          []T              slice length
+          map[K]T          map length (number of defined keys)
+          chan T           number of elements queued in channel buffer
+
+cap(s)    [n]T, *[n]T      array length (== n)
+          []T              slice capacity
+          chan T           channel buffer capacity
+
+ +

+The capacity of a slice is the number of elements for which there is +space allocated in the underlying array. +At any time the following relationship holds: +

+ +
+0 <= len(s) <= cap(s)
+
+ +

+The length of a nil slice, map or channel is 0. +The capacity of a nil slice or channel is 0. +

+ +

+The expression len(s) is constant if +s is a string constant. The expressions len(s) and +cap(s) are constants if the type of s is an array +or pointer to an array and the expression s does not contain +channel receives or (non-constant) +function calls; in this case s is not evaluated. +Otherwise, invocations of len and cap are not +constant and s is evaluated. +

+ +
+const (
+	c1 = imag(2i)                    // imag(2i) = 2.0 is a constant
+	c2 = len([10]float64{2})         // [10]float64{2} contains no function calls
+	c3 = len([10]float64{c1})        // [10]float64{c1} contains no function calls
+	c4 = len([10]float64{imag(2i)})  // imag(2i) is a constant and no function call is issued
+	c5 = len([10]float64{imag(z)})   // invalid: imag(z) is a (non-constant) function call
+)
+var z complex128
+
+ +

Allocation

+ +

+The built-in function new takes a type T, +allocates storage for a variable of that type +at run time, and returns a value of type *T +pointing to it. +The variable is initialized as described in the section on +initial values. +

+ +
+new(T)
+
+ +

+For instance +

+ +
+type S struct { a int; b float64 }
+new(S)
+
+ +

+allocates storage for a variable of type S, +initializes it (a=0, b=0.0), +and returns a value of type *S containing the address +of the location. +

+ +

Making slices, maps and channels

+ +

+The built-in function make takes a type T, +which must be a slice, map or channel type, +optionally followed by a type-specific list of expressions. +It returns a value of type T (not *T). +The memory is initialized as described in the section on +initial values. +

+ +
+Call             Type T     Result
+
+make(T, n)       slice      slice of type T with length n and capacity n
+make(T, n, m)    slice      slice of type T with length n and capacity m
+
+make(T)          map        map of type T
+make(T, n)       map        map of type T with initial space for approximately n elements
+
+make(T)          channel    unbuffered channel of type T
+make(T, n)       channel    buffered channel of type T, buffer size n
+
+ + +

+Each of the size arguments n and m must be of integer type +or an untyped constant. +A constant size argument must be non-negative and representable +by a value of type int; if it is an untyped constant it is given type int. +If both n and m are provided and are constant, then +n must be no larger than m. +If n is negative or larger than m at run time, +a run-time panic occurs. +

+ +
+s := make([]int, 10, 100)       // slice with len(s) == 10, cap(s) == 100
+s := make([]int, 1e3)           // slice with len(s) == cap(s) == 1000
+s := make([]int, 1<<63)         // illegal: len(s) is not representable by a value of type int
+s := make([]int, 10, 0)         // illegal: len(s) > cap(s)
+c := make(chan int, 10)         // channel with a buffer size of 10
+m := make(map[string]int, 100)  // map with initial space for approximately 100 elements
+
+ +

+Calling make with a map type and size hint n will +create a map with initial space to hold n map elements. +The precise behavior is implementation-dependent. +

+ + +

Appending to and copying slices

+ +

+The built-in functions append and copy assist in +common slice operations. +For both functions, the result is independent of whether the memory referenced +by the arguments overlaps. +

+ +

+The variadic function append +appends zero or more values x +to s of type S, which must be a slice type, and +returns the resulting slice, also of type S. +The values x are passed to a parameter of type ...T +where T is the element type of +S and the respective +parameter passing rules apply. +As a special case, append also accepts a first argument +assignable to type []byte with a second argument of +string type followed by .... This form appends the +bytes of the string. +

+ +
+append(s S, x ...T) S  // T is the element type of S
+
+ +

+If the capacity of s is not large enough to fit the additional +values, append allocates a new, sufficiently large underlying +array that fits both the existing slice elements and the additional values. +Otherwise, append re-uses the underlying array. +

+ +
+s0 := []int{0, 0}
+s1 := append(s0, 2)                // append a single element     s1 == []int{0, 0, 2}
+s2 := append(s1, 3, 5, 7)          // append multiple elements    s2 == []int{0, 0, 2, 3, 5, 7}
+s3 := append(s2, s0...)            // append a slice              s3 == []int{0, 0, 2, 3, 5, 7, 0, 0}
+s4 := append(s3[3:6], s3[2:]...)   // append overlapping slice    s4 == []int{3, 5, 7, 2, 3, 5, 7, 0, 0}
+
+var t []interface{}
+t = append(t, 42, 3.1415, "foo")   //                             t == []interface{}{42, 3.1415, "foo"}
+
+var b []byte
+b = append(b, "bar"...)            // append string contents      b == []byte{'b', 'a', 'r' }
+
+ +

+The function copy copies slice elements from +a source src to a destination dst and returns the +number of elements copied. +Both arguments must have identical element type T and must be +assignable to a slice of type []T. +The number of elements copied is the minimum of +len(src) and len(dst). +As a special case, copy also accepts a destination argument assignable +to type []byte with a source argument of a string type. +This form copies the bytes from the string into the byte slice. +

+ +
+copy(dst, src []T) int
+copy(dst []byte, src string) int
+
+ +

+Examples: +

+ +
+var a = [...]int{0, 1, 2, 3, 4, 5, 6, 7}
+var s = make([]int, 6)
+var b = make([]byte, 5)
+n1 := copy(s, a[0:])            // n1 == 6, s == []int{0, 1, 2, 3, 4, 5}
+n2 := copy(s, s[2:])            // n2 == 4, s == []int{2, 3, 4, 5, 4, 5}
+n3 := copy(b, "Hello, World!")  // n3 == 5, b == []byte("Hello")
+
+ + +

Deletion of map elements

+ +

+The built-in function delete removes the element with key +k from a map m. The +type of k must be assignable +to the key type of m. +

+ +
+delete(m, k)  // remove element m[k] from map m
+
+ +

+If the map m is nil or the element m[k] +does not exist, delete is a no-op. +

+ + +

Manipulating complex numbers

+ +

+Three functions assemble and disassemble complex numbers. +The built-in function complex constructs a complex +value from a floating-point real and imaginary part, while +real and imag +extract the real and imaginary parts of a complex value. +

+ +
+complex(realPart, imaginaryPart floatT) complexT
+real(complexT) floatT
+imag(complexT) floatT
+
+ +

+The type of the arguments and return value correspond. +For complex, the two arguments must be of the same +floating-point type and the return type is the complex type +with the corresponding floating-point constituents: +complex64 for float32 arguments, and +complex128 for float64 arguments. +If one of the arguments evaluates to an untyped constant, it is first implicitly +converted to the type of the other argument. +If both arguments evaluate to untyped constants, they must be non-complex +numbers or their imaginary parts must be zero, and the return value of +the function is an untyped complex constant. +

+ +

+For real and imag, the argument must be +of complex type, and the return type is the corresponding floating-point +type: float32 for a complex64 argument, and +float64 for a complex128 argument. +If the argument evaluates to an untyped constant, it must be a number, +and the return value of the function is an untyped floating-point constant. +

+ +

+The real and imag functions together form the inverse of +complex, so for a value z of a complex type Z, +z == Z(complex(real(z), imag(z))). +

+ +

+If the operands of these functions are all constants, the return +value is a constant. +

+ +
+var a = complex(2, -2)             // complex128
+const b = complex(1.0, -1.4)       // untyped complex constant 1 - 1.4i
+x := float32(math.Cos(math.Pi/2))  // float32
+var c64 = complex(5, -x)           // complex64
+var s int = complex(1, 0)          // untyped complex constant 1 + 0i can be converted to int
+_ = complex(1, 2<<s)               // illegal: 2 assumes floating-point type, cannot shift
+var rl = real(c64)                 // float32
+var im = imag(a)                   // float64
+const c = imag(b)                  // untyped constant -1.4
+_ = imag(3 << s)                   // illegal: 3 assumes complex type, cannot shift
+
+ +

Handling panics

+ +

Two built-in functions, panic and recover, +assist in reporting and handling run-time panics +and program-defined error conditions. +

+ +
+func panic(interface{})
+func recover() interface{}
+
+ +

+While executing a function F, +an explicit call to panic or a run-time panic +terminates the execution of F. +Any functions deferred by F +are then executed as usual. +Next, any deferred functions run by F's caller are run, +and so on up to any deferred by the top-level function in the executing goroutine. +At that point, the program is terminated and the error +condition is reported, including the value of the argument to panic. +This termination sequence is called panicking. +

+ +
+panic(42)
+panic("unreachable")
+panic(Error("cannot parse"))
+
+ +

+The recover function allows a program to manage behavior +of a panicking goroutine. +Suppose a function G defers a function D that calls +recover and a panic occurs in a function on the same goroutine in which G +is executing. +When the running of deferred functions reaches D, +the return value of D's call to recover will be the value passed to the call of panic. +If D returns normally, without starting a new +panic, the panicking sequence stops. In that case, +the state of functions called between G and the call to panic +is discarded, and normal execution resumes. +Any functions deferred by G before D are then run and G's +execution terminates by returning to its caller. +

+ +

+The return value of recover is nil if any of the following conditions holds: +

+ + +

+The protect function in the example below invokes +the function argument g and protects callers from +run-time panics raised by g. +

+ +
+func protect(g func()) {
+	defer func() {
+		log.Println("done")  // Println executes normally even if there is a panic
+		if x := recover(); x != nil {
+			log.Printf("run time panic: %v", x)
+		}
+	}()
+	log.Println("start")
+	g()
+}
+
+ + +

Bootstrapping

+ +

+Current implementations provide several built-in functions useful during +bootstrapping. These functions are documented for completeness but are not +guaranteed to stay in the language. They do not return a result. +

+ +
+Function   Behavior
+
+print      prints all arguments; formatting of arguments is implementation-specific
+println    like print but prints spaces between arguments and a newline at the end
+
+ +

+Implementation restriction: print and println need not +accept arbitrary argument types, but printing of boolean, numeric, and string +types must be supported. +

+ +

Packages

+ +

+Go programs are constructed by linking together packages. +A package in turn is constructed from one or more source files +that together declare constants, types, variables and functions +belonging to the package and which are accessible in all files +of the same package. Those elements may be +exported and used in another package. +

+ +

Source file organization

+ +

+Each source file consists of a package clause defining the package +to which it belongs, followed by a possibly empty set of import +declarations that declare packages whose contents it wishes to use, +followed by a possibly empty set of declarations of functions, +types, variables, and constants. +

+ +
+SourceFile       = PackageClause ";" { ImportDecl ";" } { TopLevelDecl ";" } .
+
+ +

Package clause

+ +

+A package clause begins each source file and defines the package +to which the file belongs. +

+ +
+PackageClause  = "package" PackageName .
+PackageName    = identifier .
+
+ +

+The PackageName must not be the blank identifier. +

+ +
+package math
+
+ +

+A set of files sharing the same PackageName form the implementation of a package. +An implementation may require that all source files for a package inhabit the same directory. +

+ +

Import declarations

+ +

+An import declaration states that the source file containing the declaration +depends on functionality of the imported package +(§Program initialization and execution) +and enables access to exported identifiers +of that package. +The import names an identifier (PackageName) to be used for access and an ImportPath +that specifies the package to be imported. +

+ +
+ImportDecl       = "import" ( ImportSpec | "(" { ImportSpec ";" } ")" ) .
+ImportSpec       = [ "." | PackageName ] ImportPath .
+ImportPath       = string_lit .
+
+ +

+The PackageName is used in qualified identifiers +to access exported identifiers of the package within the importing source file. +It is declared in the file block. +If the PackageName is omitted, it defaults to the identifier specified in the +package clause of the imported package. +If an explicit period (.) appears instead of a name, all the +package's exported identifiers declared in that package's +package block will be declared in the importing source +file's file block and must be accessed without a qualifier. +

+ +

+The interpretation of the ImportPath is implementation-dependent but +it is typically a substring of the full file name of the compiled +package and may be relative to a repository of installed packages. +

+ +

+Implementation restriction: A compiler may restrict ImportPaths to +non-empty strings using only characters belonging to +Unicode's +L, M, N, P, and S general categories (the Graphic characters without +spaces) and may also exclude the characters +!"#$%&'()*,:;<=>?[\]^`{|} +and the Unicode replacement character U+FFFD. +

+ +

+Assume we have compiled a package containing the package clause +package math, which exports function Sin, and +installed the compiled package in the file identified by +"lib/math". +This table illustrates how Sin is accessed in files +that import the package after the +various types of import declaration. +

+ +
+Import declaration          Local name of Sin
+
+import   "lib/math"         math.Sin
+import m "lib/math"         m.Sin
+import . "lib/math"         Sin
+
+ +

+An import declaration declares a dependency relation between +the importing and imported package. +It is illegal for a package to import itself, directly or indirectly, +or to directly import a package without +referring to any of its exported identifiers. To import a package solely for +its side-effects (initialization), use the blank +identifier as explicit package name: +

+ +
+import _ "lib/math"
+
+ + +

An example package

+ +

+Here is a complete Go package that implements a concurrent prime sieve. +

+ +
+package main
+
+import "fmt"
+
+// Send the sequence 2, 3, 4, … to channel 'ch'.
+func generate(ch chan<- int) {
+	for i := 2; ; i++ {
+		ch <- i  // Send 'i' to channel 'ch'.
+	}
+}
+
+// Copy the values from channel 'src' to channel 'dst',
+// removing those divisible by 'prime'.
+func filter(src <-chan int, dst chan<- int, prime int) {
+	for i := range src {  // Loop over values received from 'src'.
+		if i%prime != 0 {
+			dst <- i  // Send 'i' to channel 'dst'.
+		}
+	}
+}
+
+// The prime sieve: Daisy-chain filter processes together.
+func sieve() {
+	ch := make(chan int)  // Create a new channel.
+	go generate(ch)       // Start generate() as a subprocess.
+	for {
+		prime := <-ch
+		fmt.Print(prime, "\n")
+		ch1 := make(chan int)
+		go filter(ch, ch1, prime)
+		ch = ch1
+	}
+}
+
+func main() {
+	sieve()
+}
+
+ +

Program initialization and execution

+ +

The zero value

+

+When storage is allocated for a variable, +either through a declaration or a call of new, or when +a new value is created, either through a composite literal or a call +of make, +and no explicit initialization is provided, the variable or value is +given a default value. Each element of such a variable or value is +set to the zero value for its type: false for booleans, +0 for numeric types, "" +for strings, and nil for pointers, functions, interfaces, slices, channels, and maps. +This initialization is done recursively, so for instance each element of an +array of structs will have its fields zeroed if no value is specified. +

+

+These two simple declarations are equivalent: +

+ +
+var i int
+var i int = 0
+
+ +

+After +

+ +
+type T struct { i int; f float64; next *T }
+t := new(T)
+
+ +

+the following holds: +

+ +
+t.i == 0
+t.f == 0.0
+t.next == nil
+
+ +

+The same would also be true after +

+ +
+var t T
+
+ +

Package initialization

+ +

+Within a package, package-level variable initialization proceeds stepwise, +with each step selecting the variable earliest in declaration order +which has no dependencies on uninitialized variables. +

+ +

+More precisely, a package-level variable is considered ready for +initialization if it is not yet initialized and either has +no initialization expression or +its initialization expression has no dependencies on uninitialized variables. +Initialization proceeds by repeatedly initializing the next package-level +variable that is earliest in declaration order and ready for initialization, +until there are no variables ready for initialization. +

+ +

+If any variables are still uninitialized when this +process ends, those variables are part of one or more initialization cycles, +and the program is not valid. +

+ +

+Multiple variables on the left-hand side of a variable declaration initialized +by single (multi-valued) expression on the right-hand side are initialized +together: If any of the variables on the left-hand side is initialized, all +those variables are initialized in the same step. +

+ +
+var x = a
+var a, b = f() // a and b are initialized together, before x is initialized
+
+ +

+For the purpose of package initialization, blank +variables are treated like any other variables in declarations. +

+ +

+The declaration order of variables declared in multiple files is determined +by the order in which the files are presented to the compiler: Variables +declared in the first file are declared before any of the variables declared +in the second file, and so on. +

+ +

+Dependency analysis does not rely on the actual values of the +variables, only on lexical references to them in the source, +analyzed transitively. For instance, if a variable x's +initialization expression refers to a function whose body refers to +variable y then x depends on y. +Specifically: +

+ + + +

+For example, given the declarations +

+ +
+var (
+	a = c + b  // == 9
+	b = f()    // == 4
+	c = f()    // == 5
+	d = 3      // == 5 after initialization has finished
+)
+
+func f() int {
+	d++
+	return d
+}
+
+ +

+the initialization order is d, b, c, a. +Note that the order of subexpressions in initialization expressions is irrelevant: +a = c + b and a = b + c result in the same initialization +order in this example. +

+ +

+Dependency analysis is performed per package; only references referring +to variables, functions, and (non-interface) methods declared in the current +package are considered. If other, hidden, data dependencies exists between +variables, the initialization order between those variables is unspecified. +

+ +

+For instance, given the declarations +

+ +
+var x = I(T{}).ab()   // x has an undetected, hidden dependency on a and b
+var _ = sideEffect()  // unrelated to x, a, or b
+var a = b
+var b = 42
+
+type I interface      { ab() []int }
+type T struct{}
+func (T) ab() []int   { return []int{a, b} }
+
+ +

+the variable a will be initialized after b but +whether x is initialized before b, between +b and a, or after a, and +thus also the moment at which sideEffect() is called (before +or after x is initialized) is not specified. +

+ +

+Variables may also be initialized using functions named init +declared in the package block, with no arguments and no result parameters. +

+ +
+func init() { … }
+
+ +

+Multiple such functions may be defined per package, even within a single +source file. In the package block, the init identifier can +be used only to declare init functions, yet the identifier +itself is not declared. Thus +init functions cannot be referred to from anywhere +in a program. +

+ +

+A package with no imports is initialized by assigning initial values +to all its package-level variables followed by calling all init +functions in the order they appear in the source, possibly in multiple files, +as presented to the compiler. +If a package has imports, the imported packages are initialized +before initializing the package itself. If multiple packages import +a package, the imported package will be initialized only once. +The importing of packages, by construction, guarantees that there +can be no cyclic initialization dependencies. +

+ +

+Package initialization—variable initialization and the invocation of +init functions—happens in a single goroutine, +sequentially, one package at a time. +An init function may launch other goroutines, which can run +concurrently with the initialization code. However, initialization +always sequences +the init functions: it will not invoke the next one +until the previous one has returned. +

+ +

+To ensure reproducible initialization behavior, build systems are encouraged +to present multiple files belonging to the same package in lexical file name +order to a compiler. +

+ + +

Program execution

+

+A complete program is created by linking a single, unimported package +called the main package with all the packages it imports, transitively. +The main package must +have package name main and +declare a function main that takes no +arguments and returns no value. +

+ +
+func main() { … }
+
+ +

+Program execution begins by initializing the main package and then +invoking the function main. +When that function invocation returns, the program exits. +It does not wait for other (non-main) goroutines to complete. +

+ +

Errors

+ +

+The predeclared type error is defined as +

+ +
+type error interface {
+	Error() string
+}
+
+ +

+It is the conventional interface for representing an error condition, +with the nil value representing no error. +For instance, a function to read data from a file might be defined: +

+ +
+func Read(f *File, b []byte) (n int, err error)
+
+ +

Run-time panics

+ +

+Execution errors such as attempting to index an array out +of bounds trigger a run-time panic equivalent to a call of +the built-in function panic +with a value of the implementation-defined interface type runtime.Error. +That type satisfies the predeclared interface type +error. +The exact error values that +represent distinct run-time error conditions are unspecified. +

+ +
+package runtime
+
+type Error interface {
+	error
+	// and perhaps other methods
+}
+
+ +

System considerations

+ +

Package unsafe

+ +

+The built-in package unsafe, known to the compiler +and accessible through the import path "unsafe", +provides facilities for low-level programming including operations +that violate the type system. A package using unsafe +must be vetted manually for type safety and may not be portable. +The package provides the following interface: +

+ +
+package unsafe
+
+type ArbitraryType int  // shorthand for an arbitrary Go type; it is not a real type
+type Pointer *ArbitraryType
+
+func Alignof(variable ArbitraryType) uintptr
+func Offsetof(selector ArbitraryType) uintptr
+func Sizeof(variable ArbitraryType) uintptr
+
+type IntegerType int  // shorthand for an integer type; it is not a real type
+func Add(ptr Pointer, len IntegerType) Pointer
+func Slice(ptr *ArbitraryType, len IntegerType) []ArbitraryType
+
+ +

+A Pointer is a pointer type but a Pointer +value may not be dereferenced. +Any pointer or value of underlying type uintptr can be converted to +a type of underlying type Pointer and vice versa. +The effect of converting between Pointer and uintptr is implementation-defined. +

+ +
+var f float64
+bits = *(*uint64)(unsafe.Pointer(&f))
+
+type ptr unsafe.Pointer
+bits = *(*uint64)(ptr(&f))
+
+var p ptr = nil
+
+ +

+The functions Alignof and Sizeof take an expression x +of any type and return the alignment or size, respectively, of a hypothetical variable v +as if v was declared via var v = x. +

+

+The function Offsetof takes a (possibly parenthesized) selector +s.f, denoting a field f of the struct denoted by s +or *s, and returns the field offset in bytes relative to the struct's address. +If f is an embedded field, it must be reachable +without pointer indirections through fields of the struct. +For a struct s with field f: +

+ +
+uintptr(unsafe.Pointer(&s)) + unsafe.Offsetof(s.f) == uintptr(unsafe.Pointer(&s.f))
+
+ +

+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)) % unsafe.Alignof(x) == 0
+
+ +

+Calls to Alignof, Offsetof, and +Sizeof are compile-time constant expressions of type uintptr. +

+ +

+The function Add adds len to ptr +and returns the updated pointer unsafe.Pointer(uintptr(ptr) + uintptr(len)). +The len argument must be of integer type or an untyped constant. +A constant len argument must be representable by a value of type int; +if it is an untyped constant it is given type int. +The rules for valid uses of Pointer still apply. +

+ +

+The function Slice returns a slice whose underlying array starts at ptr +and whose length and capacity are len. +Slice(ptr, len) is equivalent to +

+ +
+(*[len]ArbitraryType)(unsafe.Pointer(ptr))[:]
+
+ +

+except that, as a special case, if ptr +is nil and len is zero, +Slice returns nil. +

+ +

+The len argument must be of integer type or an untyped constant. +A constant len argument must be non-negative and representable by a value of type int; +if it is an untyped constant it is given type int. +At run time, if len is negative, +or if ptr is nil and len is not zero, +a run-time panic occurs. +

+ +

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: +

+
    +
  1. For a variable x of any type: unsafe.Alignof(x) is at least 1. +
  2. + +
  3. 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. +
  4. + +
  5. For a variable x of array type: unsafe.Alignof(x) is the same as + the alignment of a variable of the array's element type. +
  6. +
+ +

+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. +

diff --git a/doc/go1.20.html b/doc/go1.20.html new file mode 100644 index 0000000..1fef452 --- /dev/null +++ b/doc/go1.20.html @@ -0,0 +1,1246 @@ + + + + + + +

DRAFT RELEASE NOTES — Introduction to Go 1.20

+ +

+ + Go 1.20 is not yet released. These are work-in-progress + release notes. Go 1.20 is expected to be released in February 2023. + +

+ +

Changes to the language

+ +

+ Go 1.20 includes four changes to the language. +

+ +

+ Go 1.17 added conversions from slice to an array pointer. + Go 1.20 extends this to allow conversions from a slice to an array: + given a slice x, [4]byte(x) can now be written + instead of *(*[4]byte)(x). +

+ +

+ The unsafe package defines + three new functions SliceData, String, and StringData. + Along with Go 1.17's Slice, these functions now provide the complete ability to + construct and deconstruct slice and string values, without depending on their exact representation. +

+ +

+ The specification now defines that struct values are compared one field at a time, + considering fields in the order they appear in the struct type definition, + and stopping at the first mismatch. + The specification could previously have been read as if + all fields needed to be compared beyond the first mismatch. + Similarly, the specification now defines that array values are compared + one element at a time, in increasing index order. + In both cases, the difference affects whether certain comparisons must panic. + Existing programs are unchanged: the new spec wording describes + what the implementations have always done. +

+ +

+ Comparable types (such as ordinary interfaces) + may now satisfy comparable constraints, even if the type arguments + are not strictly comparable (comparison may panic at runtime). + This makes it possible to instantiate a type parameter constrained by comparable + (e.g., a type parameter for a user-defined generic map key) with a non-strictly comparable type argument + such as an interface type, or a composite type containing an interface type. +

+ +

Ports

+ +

Windows

+ +

+ Go 1.20 is the last release that will run on any release of Windows 7, 8, Server 2008 and Server 2012. + Go 1.21 will require at least Windows 10 or Server 2016. +

+ +

Darwin and iOS

+ +

+ Go 1.20 is the last release that will run on macOS 10.13 High Sierra or 10.14 Mojave. + Go 1.21 will require macOS 10.15 Catalina or later. +

+ +

FreeBSD/RISC-V

+ +

+ Go 1.20 adds experimental support for FreeBSD on RISC-V (GOOS=freebsd, GOARCH=riscv64). +

+ +

Tools

+ +

Go command

+ +

+ The directory $GOROOT/pkg no longer stores + pre-compiled package archives for the standard library: + go install no longer writes them, + the go build no longer checks for them, + and the Go distribution no longer ships them. + Instead, packages in the standard library are built as needed + and cached in the build cache, just like packages outside GOROOT. + This change reduces the size of the Go distribution and also + avoids C toolchain skew for packages that use cgo. +

+ +

+ The implementation of go test -json + has been improved to make it more robust. + Programs that run go test -json + do not need any updates. + Programs that invoke go tool test2json + directly should now run the test binary with -v=test2json + (for example, go test -v=test2json + or ./pkg.test -test.v=test2json) + instead of plain -v. +

+ +

+ A related change to go test -json + is the addition of an event with Action set to start + at the beginning of each test program's execution. + When running multiple tests using the go command, + these start events are guaranteed to be emitted in the same order as + the packages named on the command line. +

+ +

+ The go command now defines + architecture feature build tags, such as amd64.v2, + to allow selecting a package implementation file based on the presence + or absence of a particular architecture feature. + See go help buildconstraint for details. +

+ +

+ The go subcommands now accept + -C <dir> to change directory to <dir> + before performing the command, which may be useful for scripts that need to + execute commands in multiple different modules. +

+ +

+ The go build and go test + commands no longer accept the -i flag, + which has been deprecated since Go 1.16. +

+ +

+ The go generate command now accepts + -skip <pattern> to skip //go:generate directives + matching <pattern>. +

+ +

+ The go test command now accepts + -skip <pattern> to skip tests, subtests, or examples + matching <pattern>. +

+ +

+ When the main module is located within GOPATH/src, + go install no longer installs libraries for + non-main packages to GOPATH/pkg, + and go list no longer reports a Target + field for such packages. (In module mode, compiled packages are stored in the + build cache + only, but a bug had caused + the GOPATH install targets to unexpectedly remain in effect.) +

+ +

+ The go build, go install, + and other build-related commands now support a -pgo flag that enables + profile-guided optimization, which is described in more detail in the + Compiler section below. + The -pgo flag specifies the file path of the profile. + Specifying -pgo=auto causes the go command to search + for a file named default.pgo in the main package's directory and + use it if present. + This mode currently requires a single main package to be specified on the + command line, but we plan to lift this restriction in a future release. + Specifying -pgo=off turns off profile-guided optimization. +

+ +

+ The go build, go install, + and other build-related commands now support a -cover + flag that builds the specified target with code coverage instrumentation. + This is described in more detail in the + Cover section below. +

+ +

go version

+ +

+ The go version -m command + now supports reading more types of Go binaries, most notably, Windows DLLs + built with go build -buildmode=c-shared + and Linux binaries without execute permission. +

+ +

Cgo

+ +

+ The go command now disables cgo by default + on systems without a C toolchain. + More specifically, when the CGO_ENABLED environment variable is unset, + the CC environment variable is unset, + and the default C compiler (typically clang or gcc) + is not found in the path, + CGO_ENABLED defaults to 0. + As always, you can override the default by setting CGO_ENABLED explicitly. +

+ +

+ The most important effect of the default change is that when Go is installed + on a system without a C compiler, it will now use pure Go builds for packages + in the standard library that use cgo, instead of using pre-distributed package archives + (which have been removed, as noted above) + or attempting to use cgo and failing. + This makes Go work better in some minimal container environments + as well as on macOS, where pre-distributed package archives have + not been used for cgo-based packages since Go 1.16. +

+ +

+ The packages in the standard library that use cgo are net, + os/user, and + plugin. + On macOS, the net and os/user packages have been rewritten not to use cgo: + the same code is now used for cgo and non-cgo builds as well as cross-compiled builds. + On Windows, the net and os/user packages have never used cgo. + On other systems, builds with cgo disabled will use a pure Go version of these packages. +

+ +

+ On macOS, the race detector has been rewritten not to use cgo: + race-detector-enabled programs can be built and run without Xcode. + On Linux and other Unix systems, and on Windows, a host C toolchain + is required to use the race detector. +

+ +

Cover

+ +

+ Go 1.20 supports collecting code coverage profiles for programs + (applications and integration tests), as opposed to just unit tests. +

+ +

+ To collect coverage data for a program, build it with go + build's -cover flag, then run the resulting + binary with the environment variable GOCOVERDIR set + to an output directory for coverage profiles. + See the + 'coverage for integration tests' landing page for more on how to get started. + For details on the design and implementation, see the + proposal. +

+ +

Vet

+ +

Improved detection of loop variable capture by nested functions

+ +

+ The vet tool now reports references to loop variables following + a call to T.Parallel() + within subtest function bodies. Such references may observe the value of the + variable from a different iteration (typically causing test cases to be + skipped) or an invalid state due to unsynchronized concurrent access. +

+ +

+ The tool also detects reference mistakes in more places. Previously it would + only consider the last statement of the loop body, but now it recursively + inspects the last statements within if, switch, and select statements. +

+ +

New diagnostic for incorrect time formats

+ +

+ The vet tool now reports use of the time format 2006-02-01 (yyyy-dd-mm) + with Time.Format and + time.Parse. + This format does not appear in common date standards, but is frequently + used by mistake when attempting to use the ISO 8601 date format + (yyyy-mm-dd). +

+ +

Runtime

+ +

+ Some of the garbage collector's internal data structures were reorganized to + be both more space and CPU efficient. + This change reduces memory overheads and improves overall CPU performance by + up to 2%. +

+ +

+ The garbage collector behaves less erratically with respect to goroutine + assists in some circumstances. +

+ +

+ Go 1.20 adds a new runtime/coverage package + containing APIs for writing coverage profile data at + runtime from long-running and/or server programs that + do not terminate via os.Exit(). +

+ +

Compiler

+ +

+ Go 1.20 adds preview support for profile-guided optimization (PGO). + PGO enables the toolchain to perform application- and workload-specific + optimizations based on run-time profile information. + Currently, the compiler supports pprof CPU profiles, which can be collected + through usual means, such as the runtime/pprof or + net/http/pprof packages. + To enable PGO, pass the path of a pprof profile file via the + -pgo flag to go build, + as mentioned above. + Go 1.20 uses PGO to more aggressively inline functions at hot call sites. + Benchmarks for a representative set of Go programs show enabling + profile-guided inlining optimization improves performance about 3–4%. + We plan to add more profile-guided optimizations in future releases. + Note that profile-guided optimization is a preview, so please use it + with appropriate caution. +

+ +

+ The Go 1.20 compiler upgraded its front-end to use a new way of handling the + compiler's internal data, which fixes several generic-types bugs and enables + local types in generic functions and methods. +

+ +

+ The compiler now disallows anonymous interface cycles. +

+ +

+ Go 1.18 and 1.19 saw regressions in build speed, largely due to the addition + of support for generics and follow-on work. Go 1.20 improves build speeds by + up to 10%, bringing it back in line with Go 1.17. + Relative to Go 1.19, generated code performance is also generally slightly improved. +

+ +

Linker

+ +

+ On Linux, the linker now selects the dynamic interpreter for glibc + or musl at link time. +

+ +

+ On Windows, the Go linker now supports modern LLVM-based C toolchains. +

+ +

+ Go 1.20 uses go: and type: prefixes for compiler-generated + symbols rather than go. and type.. + This avoids confusion for user packages whose name starts with go.. + The debug/gosym package understands + this new naming convention for binaries built with Go 1.20 and newer. +

+ +

Bootstrap

+ +

+ When building a Go release from source and GOROOT_BOOTSTRAP is not set, + previous versions of Go looked for a Go 1.4 or later bootstrap toolchain in the directory + $HOME/go1.4 (%HOMEDRIVE%%HOMEPATH%\go1.4 on Windows). + Go 1.18 and Go 1.19 looked first for $HOME/go1.17 or $HOME/sdk/go1.17 + before falling back to $HOME/go1.4, + in anticipation of requiring Go 1.17 for use when bootstrapping Go 1.20. + Go 1.20 does require a Go 1.17 release for bootstrapping, but we realized that we should + adopt the latest point release of the bootstrap toolchain, so it requires Go 1.17.13. + Go 1.20 looks for $HOME/go1.17.13 or $HOME/sdk/go1.17.13 + before falling back to $HOME/go1.4 + (to support systems that hard-coded the path $HOME/go1.4 but have installed + a newer Go toolchain there). + In the future, we plan to move the bootstrap toolchain forward approximately once a year, + and in particular we expect that Go 1.22 will require the final point release of Go 1.20 for bootstrap. +

+ +

Core library

+ +

New crypto/ecdh package

+ +

+ Go 1.20 adds a new crypto/ecdh package + to provide explicit support for Elliptic Curve Diffie-Hellman key exchanges + over NIST curves and Curve25519. +

+

+ Programs should use crypto/ecdh instead of the lower-level functionality in + crypto/elliptic for ECDH, and + third-party modules for more advanced use cases. +

+ +

Wrapping multiple errors

+ +

+ Go 1.20 expands support for error wrapping to permit an error to + wrap multiple other errors. +

+

+ An error e can wrap more than one error by providing + an Unwrap method that returns a []error. +

+

+ The errors.Is and + errors.As functions + have been updated to inspect multiply wrapped errors. +

+

+ The fmt.Errorf function + now supports multiple occurrences of the %w format verb, + which will cause it to return an error that wraps all of those error operands. +

+

+ The new function errors.Join + returns an error wrapping a list of errors. +

+ +

HTTP ResponseController

+ +

+ The new + "net/http".ResponseController + type provides access to extended per-request functionality not handled by the + "net/http".ResponseWriter interface. +

+ +

+ Previously, we have added new per-request functionality by defining optional + interfaces which a ResponseWriter can implement, such as + Flusher. These interfaces + are not discoverable and clumsy to use. +

+ +

+ The ResponseController type provides a clearer, more discoverable way + to add per-handler controls. Two such controls also added in Go 1.20 are + SetReadDeadline and SetWriteDeadline, which allow setting + per-request read and write deadlines. For example: +

+ +
+func RequestHandler(w ResponseWriter, r *Request) {
+  rc := http.NewResponseController(w)
+  rc.SetWriteDeadline(time.Time{}) // disable Server.WriteTimeout when sending a large response
+  io.Copy(w, bigData)
+}
+
+ +

New ReverseProxy Rewrite hook

+ +

+ The httputil.ReverseProxy + forwarding proxy includes a new + Rewrite + hook function, superseding the + previous Director hook. +

+ +

+ The Rewrite hook accepts a + ProxyRequest parameter, + which includes both the inbound request received by the proxy and the outbound + request that it will send. + Unlike Director hooks, which only operate on the outbound request, + this permits Rewrite hooks to avoid certain scenarios where + a malicious inbound request may cause headers added by the hook + to be removed before forwarding. + See issue #50580. +

+ +

+ The ProxyRequest.SetURL + method routes the outbound request to a provided destination + and supersedes the NewSingleHostReverseProxy function. + Unlike NewSingleHostReverseProxy, SetURL + also sets the Host header of the outbound request. +

+ +

+ The + ProxyRequest.SetXForwarded + method sets the X-Forwarded-For, X-Forwarded-Host, + and X-Forwarded-Proto headers of the outbound request. + When using a Rewrite, these headers are not added by default. +

+ +

+ An example of a Rewrite hook using these features is: +

+ +
+proxyHandler := &httputil.ReverseProxy{
+  Rewrite: func(r *httputil.ProxyRequest) {
+    r.SetURL(outboundURL) // Forward request to outboundURL.
+    r.SetXForwarded()     // Set X-Forwarded-* headers.
+    r.Out.Header.Set("X-Additional-Header", "header set by the proxy")
+  },
+}
+
+ +

+ ReverseProxy no longer adds a User-Agent header + to forwarded requests when the incoming request does not have one. +

+ +

Minor changes to the library

+ +

+ As always, there are various minor changes and updates to the library, + made with the Go 1 promise of compatibility + in mind. + There are also various performance improvements, not enumerated here. +

+ +
archive/tar
+
+

+ When the GODEBUG=tarinsecurepath=0 environment variable is set, + Reader.Next method + will now return the error ErrInsecurePath + for an entry with a file name that is an absolute path, + refers to a location outside the current directory, contains invalid + characters, or (on Windows) is a reserved name such as NUL. + A future version of Go may disable insecure paths by default. +

+
+
+ +
archive/zip
+
+

+ When the GODEBUG=zipinsecurepath=0 environment variable is set, + NewReader will now return the error + ErrInsecurePath + when opening an archive which contains any file name that is an absolute path, + refers to a location outside the current directory, contains invalid + characters, or (on Windows) is a reserved names such as NUL. + A future version of Go may disable insecure paths by default. +

+

+ Reading from a directory file that contains file data will now return an error. + The zip specification does not permit directory files to contain file data, + so this change only affects reading from invalid archives. +

+
+
+ +
bytes
+
+

+ The new + CutPrefix and + CutSuffix functions + are like TrimPrefix + and TrimSuffix + but also report whether the string was trimmed. +

+ +

+ The new Clone function + allocates a copy of a byte slice. +

+
+
+ +
context
+
+

+ The new WithCancelCause function + provides a way to cancel a context with a given error. + That error can be retrieved by calling the new Cause function. +

+
+
+ +
crypto/ecdsa
+
+

+ When using supported curves, all operations are now implemented in constant time. + This led to an increase in CPU time between 5% and 30%, mostly affecting P-384 and P-521. +

+ +

+ The new PrivateKey.ECDH method + converts an ecdsa.PrivateKey to an ecdh.PrivateKey. +

+
+
+ +
crypto/ed25519
+
+

+ The PrivateKey.Sign method + and the + VerifyWithOptions function + now support signing pre-hashed messages with Ed25519ph, + indicated by an + Options.HashFunc + that returns + crypto.SHA512. + They also now support Ed25519ctx and Ed25519ph with context, + indicated by setting the new + Options.Context + field. +

+
+
+ +
crypto/rsa
+
+

+ The new field OAEPOptions.MGFHash + allows configuring the MGF1 hash separately for OAEP decryption. +

+ +

+ crypto/rsa now uses a new, safer, constant-time backend. This causes a CPU + runtime increase for decryption operations between approximately 15% + (RSA-2048 on amd64) and 45% (RSA-4096 on arm64), and more on 32-bit architectures. + Encryption operations are approximately 20x slower than before (but still 5-10x faster than decryption). + Performance is expected to improve in future releases. + Programs must not modify or manually generate the fields of + PrecomputedValues. +

+
+
+ +
crypto/subtle
+
+

+ The new function XORBytes + XORs two byte slices together. +

+
+
+ +
crypto/tls
+
+

+ Parsed certificates are now shared across all clients actively using that certificate. + The memory savings can be significant in programs that make many concurrent connections to a + server or collection of servers sharing any part of their certificate chains. +

+ +

+ For a handshake failure due to a certificate verification failure, + the TLS client and server now return an error of the new type + CertificateVerificationError, + which includes the presented certificates. +

+
+
+ +
crypto/x509
+
+

+ ParsePKCS8PrivateKey + and + MarshalPKCS8PrivateKey + now support keys of type *crypto/ecdh.PrivateKey. + ParsePKIXPublicKey + and + MarshalPKIXPublicKey + now support keys of type *crypto/ecdh.PublicKey. + Parsing NIST curve keys still returns values of type + *ecdsa.PublicKey and *ecdsa.PrivateKey. + Use their new ECDH methods to convert to the crypto/ecdh types. +

+

+ The new SetFallbackRoots + function allows a program to define a set of fallback root certificates in case an + operating system verifier or standard platform root bundle is unavailable at runtime. + It will most commonly be used with a new package, golang.org/x/crypto/x509roots/fallback, + which will provide an up to date root bundle. +

+
+
+ +
debug/elf
+
+

+ Attempts to read from a SHT_NOBITS section using + Section.Data + or the reader returned by Section.Open + now return an error. +

+

+ Additional R_LARCH_* constants are defined for use with LoongArch systems. +

+

+ Additional R_PPC64_* constants are defined for use with PPC64 ELFv2 relocations. +

+

+ The constant value for R_PPC64_SECTOFF_LO_DS is corrected, from 61 to 62. +

+
+
+ +
debug/gosym
+
+

+ Due to a change of Go's symbol naming conventions, tools that + process Go binaries should use Go 1.20's debug/gosym package to + transparently handle both old and new binaries. +

+
+
+ +
debug/pe
+
+

+ Additional IMAGE_FILE_MACHINE_RISCV* constants are defined for use with RISC-V systems. +

+
+
+ +
encoding/binary
+
+

+ The ReadVarint and + ReadUvarint + functions will now return io.ErrUnexpectedEOF after reading a partial value, + rather than io.EOF. +

+
+
+ +
encoding/xml
+
+

+ The new Encoder.Close method + can be used to check for unclosed elements when finished encoding. +

+ +

+ The decoder now rejects element and attribute names with more than one colon, + such as <a:b:c>, + as well as namespaces that resolve to an empty string, such as xmlns:a="". +

+ +

+ The decoder now rejects elements that use different namespace prefixes in the opening and closing tag, + even if those prefixes both denote the same namespace. +

+
+
+ +
errors
+
+

+ The new Join function returns an error wrapping a list of errors. +

+
+
+ +
fmt
+
+

+ The Errorf function supports multiple occurrences of + the %w format verb, returning an error that unwraps to the list of all arguments to %w. +

+

+ The new FormatString function recovers the + formatting directive corresponding to a State, + which can be useful in Formatter. + implementations. +

+
+
+ +
go/ast
+
+

+ The new RangeStmt.Range field + records the position of the range keyword in a range statement. +

+

+ The new File.FileStart + and File.FileEnd fields + record the position of the start and end of the entire source file. +

+
+
+ +
go/token
+
+

+ The new FileSet.RemoveFile method + removes a file from a FileSet. + Long-running programs can use this to release memory associated + with files they no longer need. +

+
+
+ +
go/types
+
+

+ The new Satisfies function reports + whether a type satisfies a constraint. + This change aligns with the new language semantics + that distinguish satisfying a constraint from implementing an interface. +

+
+
+ +
io
+
+

+ The new OffsetWriter wraps an underlying + WriterAt + and provides Seek, Write, and WriteAt methods + that adjust their effective file offset position by a fixed amount. +

+
+
+ +
io/fs
+
+

+ The new error SkipAll + terminates a WalkDir + immediately but successfully. +

+
+
+ +
math/big
+
+

+ The math/big package's wide scope and + input-dependent timing make it ill-suited for implementing cryptography. + The cryptography packages in the standard library no longer call non-trivial + Int methods on attacker-controlled inputs. + In the future, the determination of whether a bug in math/big is + considered a security vulnerability will depend on its wider impact on the + standard library. +

+
+
+ +
math/rand
+
+

+ The math/rand package now automatically seeds + the global random number generator + (used by top-level functions like Float64 and Int) with a random value, + and the top-level Seed function has been deprecated. + Programs that need a reproducible sequence of random numbers + should prefer to allocate their own random source, using rand.New(rand.NewSource(seed)). +

+

+ Programs that need the earlier consistent global seeding behavior can set + GODEBUG=randautoseed=0 in their environment. +

+

+ The top-level Read function has been deprecated. + In almost all cases, crypto/rand.Read is more appropriate. +

+
+
+ +
mime
+
+

+ The ParseMediaType function now allows duplicate parameter names, + so long as the values of the names are the same. +

+
+
+ +
mime/multipart
+
+

+ Methods of the Reader type now wrap errors + returned by the underlying io.Reader. +

+
+
+ +
net
+
+

+ The LookupCNAME + function now consistently returns the contents + of a CNAME record when one exists. Previously on Unix systems and + when using the pure Go resolver, LookupCNAME would return an error + if a CNAME record referred to a name that with no A, + AAAA, or CNAME record. This change modifies + LookupCNAME to match the previous behavior on Windows, + allowing LookupCNAME to succeed whenever a + CNAME exists. +

+ +

+ Interface.Flags now includes the new flag FlagRunning, + indicating an operationally active interface. An interface which is administratively + configured but not active (for example, because the network cable is not connected) + will have FlagUp set but not FlagRunning. +

+ +

+ The new Dialer.ControlContext field contains a callback function + similar to the existing Dialer.Control hook, that additionally + accepts the dial context as a parameter. + Control is ignored when ControlContext is not nil. +

+ +

+ The Go DNS resolver recognizes the trust-ad resolver option. + When options trust-ad is set in resolv.conf, + the Go resolver will set the AD bit in DNS queries. The resolver does not + make use of the AD bit in responses. +

+ +

+ DNS resolution will detect changes to /etc/nsswitch.conf + and reload the file when it changes. Checks are made at most once every + five seconds, matching the previous handling of /etc/hosts + and /etc/resolv.conf. +

+
+
+ +
net/http
+
+

+ The ResponseWriter.WriteHeader function now supports sending + 1xx status codes. +

+ +

+ The new Server.DisableGeneralOptionsHandler configuration setting + allows disabling the default OPTIONS * handler. +

+ +

+ The new Transport.OnProxyConnectResponse hook is called + when a Transport receives an HTTP response from a proxy + for a CONNECT request. +

+ +

+ The HTTP server now accepts HEAD requests containing a body, + rather than rejecting them as invalid. +

+ +

+ HTTP/2 stream errors returned by net/http functions may be converted + to a golang.org/x/net/http2.StreamError using + errors.As. +

+ +

+ Leading and trailing spaces are trimmed from cookie names, + rather than being rejected as invalid. + For example, a cookie setting of "name =value" + is now accepted as setting the cookie "name". +

+
+
+ +
net/netip
+
+

+ The new IPv6LinkLocalAllRouters + and IPv6Loopback functions + are the net/netip equivalents of + net.IPv6loopback and + net.IPv6linklocalallrouters. +

+
+
+ +
os
+
+

+ On Windows, the name NUL is no longer treated as a special case in + Mkdir and + Stat. +

+

+ On Windows, File.Stat + now uses the file handle to retrieve attributes when the file is a directory. + Previously it would use the path passed to + Open, which may no longer be the file + represented by the file handle if the file has been moved or replaced. + This change modifies Open to open directories without the + FILE_SHARE_DELETE access, which match the behavior of regular files. +

+

+ On Windows, File.Seek now supports + seeking to the beginning of a directory. +

+
+
+ +
os/exec
+
+

+ The new Cmd fields + Cancel and + WaitDelay + specify the behavior of the Cmd when its associated + Context is canceled or its process exits with I/O pipes still + held open by a child process. +

+
+
+ +
path/filepath
+
+

+ The new error SkipAll + terminates a Walk + immediately but successfully. +

+

+ The new IsLocal function reports whether a path is + lexically local to a directory. + For example, if IsLocal(p) is true, + then Open(p) will refer to a file that is lexically + within the subtree rooted at the current directory. +

+
+
+ +
reflect
+
+

+ The new Value.Comparable and + Value.Equal methods + can be used to compare two Values for equality. + Comparable reports whether Equal is a valid operation for a given Value receiver. +

+ +

+ The new Value.Grow method + extends a slice to guarantee space for another n elements. +

+ +

+ The new Value.SetZero method + sets a value to be the zero value for its type. +

+ +

+ Go 1.18 introduced Value.SetIterKey + and Value.SetIterValue methods. + These are optimizations: v.SetIterKey(it) is meant to be equivalent to v.Set(it.Key()). + The implementations incorrectly omitted a check for use of unexported fields that was present in the unoptimized forms. + Go 1.20 corrects these methods to include the unexported field check. +

+
+
+ +
regexp
+
+

+ Go 1.19.2 and Go 1.18.7 included a security fix to the regular expression parser, + making it reject very large expressions that would consume too much memory. + Because Go patch releases do not introduce new API, + the parser returned syntax.ErrInternalError in this case. + Go 1.20 adds a more specific error, syntax.ErrLarge, + which the parser now returns instead. +

+
+
+ +
runtime/cgo
+
+

+ Go 1.20 adds new Incomplete marker type. + Code generated by cgo will use cgo.Incomplete to mark an incomplete C type. +

+
+
+ +
runtime/metrics
+
+

+ Go 1.20 adds new supported metrics, + including the current GOMAXPROCS setting (/sched/gomaxprocs:threads), + the number of cgo calls executed (/cgo/go-to-c-calls:calls), + total mutex block time (/sync/mutex/wait/total), and various measures of time + spent in garbage collection. +

+ +

+ Time-based histogram metrics are now less precise, but take up much less memory. +

+
+
+ +
runtime/pprof
+
+

+ Mutex profile samples are now pre-scaled, fixing an issue where old mutex profile + samples would be scaled incorrectly if the sampling rate changed during execution. +

+ +

+ Profiles collected on Windows now include memory mapping information that fixes + symbolization issues for position-independent binaries. +

+
+
+ +
runtime/trace
+
+

+ The garbage collector's background sweeper now yields less frequently, + resulting in many fewer extraneous events in execution traces. +

+
+
+ +
strings
+
+

+ The new + CutPrefix and + CutSuffix functions + are like TrimPrefix + and TrimSuffix + but also report whether the string was trimmed. +

+ +

+ The new Clone function + allocates a copy of a string. +

+
+
+ +
sync
+
+

+ The new Map methods Swap, + CompareAndSwap, and + CompareAndDelete + allow existing map entries to be updated atomically. +

+
+
+ +
syscall
+
+

+ On FreeBSD, compatibility shims needed for FreeBSD 11 and earlier have been removed. +

+

+ On Linux, additional CLONE_* constants + are defined for use with the SysProcAttr.Cloneflags field. +

+

+ On Linux, the new SysProcAttr.CgroupFD + and SysProcAttr.UseCgroupFD fields + provide a way to place a child process into a specific cgroup. +

+
+
+ +
testing
+
+

+ The new method B.Elapsed + reports the current elapsed time of the benchmark, which may be useful for + calculating rates to report with ReportMetric. +

+
+
+ +
time
+
+

+ The new time layout constants DateTime, + DateOnly, and + TimeOnly + provide names for three of the most common layout strings used in a survey of public Go source code. +

+ +

+ The new Time.Compare method + compares two times. +

+ +

+ Parse + now ignores sub-nanosecond precision in its input, + instead of reporting those digits as an error. +

+ +

+ The Time.MarshalJSON method + is now more strict about adherence to RFC 3339. +

+
+
+ +
unicode/utf16
+
+

+ The new AppendRune + function appends the UTF-16 encoding of a given rune to a uint16 slice, + analogous to utf8.AppendRune. +

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/go_mem.html b/doc/go_mem.html new file mode 100644 index 0000000..661e1e7 --- /dev/null +++ b/doc/go_mem.html @@ -0,0 +1,965 @@ + + + + +

Introduction

+ +

+The Go memory model specifies the conditions under which +reads of a variable in one goroutine can be guaranteed to +observe values produced by writes to the same variable in a different goroutine. +

+ + +

Advice

+ +

+Programs that modify data being simultaneously accessed by multiple goroutines +must serialize such access. +

+ +

+To serialize access, protect the data with channel operations or other synchronization primitives +such as those in the sync +and sync/atomic packages. +

+ +

+If you must read the rest of this document to understand the behavior of your program, +you are being too clever. +

+ +

+Don't be clever. +

+ +

Informal Overview

+ +

+Go approaches its memory model in much the same way as the rest of the language, +aiming to keep the semantics simple, understandable, and useful. +This section gives a general overview of the approach and should suffice for most programmers. +The memory model is specified more formally in the next section. +

+ +

+A data race is defined as +a write to a memory location happening concurrently with another read or write to that same location, +unless all the accesses involved are atomic data accesses as provided by the sync/atomic package. +As noted already, programmers are strongly encouraged to use appropriate synchronization +to avoid data races. +In the absence of data races, Go programs behave as if all the goroutines +were multiplexed onto a single processor. +This property is sometimes referred to as DRF-SC: data-race-free programs +execute in a sequentially consistent manner. +

+ +

+While programmers should write Go programs without data races, +there are limitations to what a Go implementation can do in response to a data race. +An implementation may always react to a data race by reporting the race and terminating the program. +Otherwise, each read of a single-word-sized or sub-word-sized memory location +must observe a value actually written to that location (perhaps by a concurrent executing goroutine) +and not yet overwritten. +These implementation constraints make Go more like Java or JavaScript, +in that most races have a limited number of outcomes, +and less like C and C++, where the meaning of any program with a race +is entirely undefined, and the compiler may do anything at all. +Go's approach aims to make errant programs more reliable and easier to debug, +while still insisting that races are errors and that tools can diagnose and report them. +

+ +

Memory Model

+ +

+The following formal definition of Go's memory model closely follows +the approach presented by Hans-J. Boehm and Sarita V. Adve in +“Foundations of the C++ Concurrency Memory Model”, +published in PLDI 2008. +The definition of data-race-free programs and the guarantee of sequential consistency +for race-free programs are equivalent to the ones in that work. +

+ +

+The memory model describes the requirements on program executions, +which are made up of goroutine executions, +which in turn are made up of memory operations. +

+ +

+A memory operation is modeled by four details: +

+ +

+Some memory operations are read-like, including read, atomic read, mutex lock, and channel receive. +Other memory operations are write-like, including write, atomic write, mutex unlock, channel send, and channel close. +Some, such as atomic compare-and-swap, are both read-like and write-like. +

+ +

+A goroutine execution is modeled as a set of memory operations executed by a single goroutine. +

+ +

+Requirement 1: +The memory operations in each goroutine must correspond to a correct sequential execution of that goroutine, +given the values read from and written to memory. +That execution must be consistent with the sequenced before relation, +defined as the partial order requirements set out by the Go language specification +for Go's control flow constructs as well as the order of evaluation for expressions. +

+ +

+A Go program execution is modeled as a set of goroutine executions, +together with a mapping W that specifies the write-like operation that each read-like operation reads from. +(Multiple executions of the same program can have different program executions.) +

+ +

+Requirement 2: +For a given program execution, the mapping W, when limited to synchronizing operations, +must be explainable by some implicit total order of the synchronizing operations +that is consistent with sequencing and the values read and written by those operations. +

+ +

+The synchronized before relation is a partial order on synchronizing memory operations, +derived from W. +If a synchronizing read-like memory operation r +observes a synchronizing write-like memory operation w +(that is, if W(r) = w), +then w is synchronized before r. +Informally, the synchronized before relation is a subset of the implied total order +mentioned in the previous paragraph, +limited to the information that W directly observes. +

+ +

+The happens before relation is defined as the transitive closure of the +union of the sequenced before and synchronized before relations. +

+ +

+Requirement 3: +For an ordinary (non-synchronizing) data read r on a memory location x, +W(r) must be a write w that is visible to r, +where visible means that both of the following hold: + +

    +
  1. w happens before r. +
  2. w does not happen before any other write w' (to x) that happens before r. +
+ +

+A read-write data race on memory location x +consists of a read-like memory operation r on x +and a write-like memory operation w on x, +at least one of which is non-synchronizing, +which are unordered by happens before +(that is, neither r happens before w +nor w happens before r). +

+ +

+A write-write data race on memory location x +consists of two write-like memory operations w and w' on x, +at least one of which is non-synchronizing, +which are unordered by happens before. +

+ +

+Note that if there are no read-write or write-write data races on memory location x, +then any read r on x has only one possible W(r): +the single w that immediately precedes it in the happens before order. +

+ +

+More generally, it can be shown that any Go program that is data-race-free, +meaning it has no program executions with read-write or write-write data races, +can only have outcomes explained by some sequentially consistent interleaving +of the goroutine executions. +(The proof is the same as Section 7 of Boehm and Adve's paper cited above.) +This property is called DRF-SC. +

+ +

+The intent of the formal definition is to match +the DRF-SC guarantee provided to race-free programs +by other languages, including C, C++, Java, JavaScript, Rust, and Swift. +

+ +

+Certain Go language operations such as goroutine creation and memory allocation +act as synchronization operations. +The effect of these operations on the synchronized-before partial order +is documented in the “Synchronization” section below. +Individual packages are responsible for providing similar documentation +for their own operations. +

+ +

Implementation Restrictions for Programs Containing Data Races

+ +

+The preceding section gave a formal definition of data-race-free program execution. +This section informally describes the semantics that implementations must provide +for programs that do contain races. +

+ +

+First, any implementation can, upon detecting a data race, +report the race and halt execution of the program. +Implementations using ThreadSanitizer +(accessed with “go build -race”) +do exactly this. +

+ +

+Otherwise, a read r of a memory location x +that is not larger than a machine word must observe +some write w such that r does not happen before w +and there is no write w' such that w happens before w' +and w' happens before r. +That is, each read must observe a value written by a preceding or concurrent write. +

+ +

+Additionally, observation of acausal and “out of thin air” writes is disallowed. +

+ +

+Reads of memory locations larger than a single machine word +are encouraged but not required to meet the same semantics +as word-sized memory locations, +observing a single allowed write w. +For performance reasons, +implementations may instead treat larger operations +as a set of individual machine-word-sized operations +in an unspecified order. +This means that races on multiword data structures +can lead to inconsistent values not corresponding to a single write. +When the values depend on the consistency +of internal (pointer, length) or (pointer, type) pairs, +as can be the case for interface values, maps, +slices, and strings in most Go implementations, +such races can in turn lead to arbitrary memory corruption. +

+ +

+Examples of incorrect synchronization are given in the +“Incorrect synchronization” section below. +

+ +

+Examples of the limitations on implementations are given in the +“Incorrect compilation” section below. +

+ +

Synchronization

+ +

Initialization

+ +

+Program initialization runs in a single goroutine, +but that goroutine may create other goroutines, +which run concurrently. +

+ +

+If a package p imports package q, the completion of +q's init functions happens before the start of any of p's. +

+ +

+The completion of all init functions is synchronized before +the start of the function main.main. +

+ +

Goroutine creation

+ +

+The go statement that starts a new goroutine +is synchronized before the start of the goroutine's execution. +

+ +

+For example, in this program: +

+ +
+var a string
+
+func f() {
+	print(a)
+}
+
+func hello() {
+	a = "hello, world"
+	go f()
+}
+
+ +

+calling hello will print "hello, world" +at some point in the future (perhaps after hello has returned). +

+ +

Goroutine destruction

+ +

+The exit of a goroutine is not guaranteed to be synchronized before +any event in the program. +For example, in this program: +

+ +
+var a string
+
+func hello() {
+	go func() { a = "hello" }()
+	print(a)
+}
+
+ +

+the assignment to a is not followed by +any synchronization event, so it is not guaranteed to be +observed by any other goroutine. +In fact, an aggressive compiler might delete the entire go statement. +

+ +

+If the effects of a goroutine must be observed by another goroutine, +use a synchronization mechanism such as a lock or channel +communication to establish a relative ordering. +

+ +

Channel communication

+ +

+Channel communication is the main method of synchronization +between goroutines. Each send on a particular channel +is matched to a corresponding receive from that channel, +usually in a different goroutine. +

+ +

+A send on a channel is synchronized before the completion of the +corresponding receive from that channel. +

+ +

+This program: +

+ +
+var c = make(chan int, 10)
+var a string
+
+func f() {
+	a = "hello, world"
+	c <- 0
+}
+
+func main() {
+	go f()
+	<-c
+	print(a)
+}
+
+ +

+is guaranteed to print "hello, world". The write to a +is sequenced before the send on c, which is synchronized before +the corresponding receive on c completes, which is sequenced before +the print. +

+ +

+The closing of a channel is synchronized before a receive that returns a zero value +because the channel is closed. +

+ +

+In the previous example, replacing +c <- 0 with close(c) +yields a program with the same guaranteed behavior. +

+ +

+A receive from an unbuffered channel is synchronized before the completion of +the corresponding send on that channel. +

+ +

+This program (as above, but with the send and receive statements swapped and +using an unbuffered channel): +

+ +
+var c = make(chan int)
+var a string
+
+func f() {
+	a = "hello, world"
+	<-c
+}
+
+func main() {
+	go f()
+	c <- 0
+	print(a)
+}
+
+ +

+is also guaranteed to print "hello, world". The write to a +is sequenced before the receive on c, which is synchronized before +the corresponding send on c completes, which is sequenced +before the print. +

+ +

+If the channel were buffered (e.g., c = make(chan int, 1)) +then the program would not be guaranteed to print +"hello, world". (It might print the empty string, +crash, or do something else.) +

+ +

+The kth receive on a channel with capacity C is synchronized before the completion of the k+Cth send from that channel completes. +

+ +

+This rule generalizes the previous rule to buffered channels. +It allows a counting semaphore to be modeled by a buffered channel: +the number of items in the channel corresponds to the number of active uses, +the capacity of the channel corresponds to the maximum number of simultaneous uses, +sending an item acquires the semaphore, and receiving an item releases +the semaphore. +This is a common idiom for limiting concurrency. +

+ +

+This program starts a goroutine for every entry in the work list, but the +goroutines coordinate using the limit channel to ensure +that at most three are running work functions at a time. +

+ +
+var limit = make(chan int, 3)
+
+func main() {
+	for _, w := range work {
+		go func(w func()) {
+			limit <- 1
+			w()
+			<-limit
+		}(w)
+	}
+	select{}
+}
+
+ +

Locks

+ +

+The sync package implements two lock data types, +sync.Mutex and sync.RWMutex. +

+ +

+For any sync.Mutex or sync.RWMutex variable l and n < m, +call n of l.Unlock() is synchronized before call m of l.Lock() returns. +

+ +

+This program: +

+ +
+var l sync.Mutex
+var a string
+
+func f() {
+	a = "hello, world"
+	l.Unlock()
+}
+
+func main() {
+	l.Lock()
+	go f()
+	l.Lock()
+	print(a)
+}
+
+ +

+is guaranteed to print "hello, world". +The first call to l.Unlock() (in f) is synchronized +before the second call to l.Lock() (in main) returns, +which is sequenced before the print. +

+ +

+For any call to l.RLock on a sync.RWMutex variable l, +there is an n such that the nth call to l.Unlock +is synchronized before the return from l.RLock, +and the matching call to l.RUnlock is synchronized before the return from call n+1 to l.Lock. +

+ +

+A successful call to l.TryLock (or l.TryRLock) +is equivalent to a call to l.Lock (or l.RLock). +An unsuccessful call has no synchronizing effect at all. +As far as the memory model is concerned, +l.TryLock (or l.TryRLock) +may be considered to be able to return false +even when the mutex l is unlocked. +

+ +

Once

+ +

+The sync package provides a safe mechanism for +initialization in the presence of multiple goroutines +through the use of the Once type. +Multiple threads can execute once.Do(f) for a particular f, +but only one will run f(), and the other calls block +until f() has returned. +

+ +

+The completion of a single call of f() from once.Do(f) +is synchronized before the return of any call of once.Do(f). +

+ +

+In this program: +

+ +
+var a string
+var once sync.Once
+
+func setup() {
+	a = "hello, world"
+}
+
+func doprint() {
+	once.Do(setup)
+	print(a)
+}
+
+func twoprint() {
+	go doprint()
+	go doprint()
+}
+
+ +

+calling twoprint will call setup exactly +once. +The setup function will complete before either call +of print. +The result will be that "hello, world" will be printed +twice. +

+ +

Atomic Values

+ +

+The APIs in the sync/atomic +package are collectively “atomic operations” +that can be used to synchronize the execution of different goroutines. +If the effect of an atomic operation A is observed by atomic operation B, +then A is synchronized before B. +All the atomic operations executed in a program behave as though executed +in some sequentially consistent order. +

+ +

+The preceding definition has the same semantics as C++’s sequentially consistent atomics +and Java’s volatile variables. +

+ +

Finalizers

+ +

+The runtime package provides +a SetFinalizer function that adds a finalizer to be called when +a particular object is no longer reachable by the program. +A call to SetFinalizer(x, f) is synchronized before the finalization call f(x). +

+ +

Additional Mechanisms

+ +

+The sync package provides additional synchronization abstractions, +including condition variables, +lock-free maps, +allocation pools, +and +wait groups. +The documentation for each of these specifies the guarantees it +makes concerning synchronization. +

+ +

+Other packages that provide synchronization abstractions +should document the guarantees they make too. +

+ + +

Incorrect synchronization

+ +

+Programs with races are incorrect and +can exhibit non-sequentially consistent executions. +In particular, note that a read r may observe the value written by any write w +that executes concurrently with r. +Even if this occurs, it does not imply that reads happening after r +will observe writes that happened before w. +

+ +

+In this program: +

+ +
+var a, b int
+
+func f() {
+	a = 1
+	b = 2
+}
+
+func g() {
+	print(b)
+	print(a)
+}
+
+func main() {
+	go f()
+	g()
+}
+
+ +

+it can happen that g prints 2 and then 0. +

+ +

+This fact invalidates a few common idioms. +

+ +

+Double-checked locking is an attempt to avoid the overhead of synchronization. +For example, the twoprint program might be +incorrectly written as: +

+ +
+var a string
+var done bool
+
+func setup() {
+	a = "hello, world"
+	done = true
+}
+
+func doprint() {
+	if !done {
+		once.Do(setup)
+	}
+	print(a)
+}
+
+func twoprint() {
+	go doprint()
+	go doprint()
+}
+
+ +

+but there is no guarantee that, in doprint, observing the write to done +implies observing the write to a. This +version can (incorrectly) print an empty string +instead of "hello, world". +

+ +

+Another incorrect idiom is busy waiting for a value, as in: +

+ +
+var a string
+var done bool
+
+func setup() {
+	a = "hello, world"
+	done = true
+}
+
+func main() {
+	go setup()
+	for !done {
+	}
+	print(a)
+}
+
+ +

+As before, there is no guarantee that, in main, +observing the write to done +implies observing the write to a, so this program could +print an empty string too. +Worse, there is no guarantee that the write to done will ever +be observed by main, since there are no synchronization +events between the two threads. The loop in main is not +guaranteed to finish. +

+ +

+There are subtler variants on this theme, such as this program. +

+ +
+type T struct {
+	msg string
+}
+
+var g *T
+
+func setup() {
+	t := new(T)
+	t.msg = "hello, world"
+	g = t
+}
+
+func main() {
+	go setup()
+	for g == nil {
+	}
+	print(g.msg)
+}
+
+ +

+Even if main observes g != nil and exits its loop, +there is no guarantee that it will observe the initialized +value for g.msg. +

+ +

+In all these examples, the solution is the same: +use explicit synchronization. +

+ +

Incorrect compilation

+ +

+The Go memory model restricts compiler optimizations as much as it does Go programs. +Some compiler optimizations that would be valid in single-threaded programs are not valid in all Go programs. +In particular, a compiler must not introduce writes that do not exist in the original program, +it must not allow a single read to observe multiple values, +and it must not allow a single write to write multiple values. +

+ +

+All the following examples assume that `*p` and `*q` refer to +memory locations accessible to multiple goroutines. +

+ +

+Not introducing data races into race-free programs means not moving +writes out of conditional statements in which they appear. +For example, a compiler must not invert the conditional in this program: +

+ +
+*p = 1
+if cond {
+	*p = 2
+}
+
+ +

+That is, the compiler must not rewrite the program into this one: +

+ +
+*p = 2
+if !cond {
+	*p = 1
+}
+
+ +

+If cond is false and another goroutine is reading *p, +then in the original program, the other goroutine can only observe any prior value of *p and 1. +In the rewritten program, the other goroutine can observe 2, which was previously impossible. +

+ +

+Not introducing data races also means not assuming that loops terminate. +For example, a compiler must in general not move the accesses to *p or *q +ahead of the loop in this program: +

+ +
+n := 0
+for e := list; e != nil; e = e.next {
+	n++
+}
+i := *p
+*q = 1
+
+ +

+If list pointed to a cyclic list, +then the original program would never access *p or *q, +but the rewritten program would. +(Moving `*p` ahead would be safe if the compiler can prove `*p` will not panic; +moving `*q` ahead would also require the compiler proving that no other +goroutine can access `*q`.) +

+ +

+Not introducing data races also means not assuming that called functions +always return or are free of synchronization operations. +For example, a compiler must not move the accesses to *p or *q +ahead of the function call in this program +(at least not without direct knowledge of the precise behavior of f): +

+ +
+f()
+i := *p
+*q = 1
+
+ +

+If the call never returned, then once again the original program +would never access *p or *q, but the rewritten program would. +And if the call contained synchronizing operations, then the original program +could establish happens before edges preceding the accesses +to *p and *q, but the rewritten program would not. +

+ +

+Not allowing a single read to observe multiple values means +not reloading local variables from shared memory. +For example, a compiler must not discard i and reload it +a second time from *p in this program: +

+ +
+i := *p
+if i < 0 || i >= len(funcs) {
+	panic("invalid function index")
+}
+... complex code ...
+// compiler must NOT reload i = *p here
+funcs[i]()
+
+ +

+If the complex code needs many registers, a compiler for single-threaded programs +could discard i without saving a copy and then reload +i = *p just before +funcs[i](). +A Go compiler must not, because the value of *p may have changed. +(Instead, the compiler could spill i to the stack.) +

+ +

+Not allowing a single write to write multiple values also means not using +the memory where a local variable will be written as temporary storage before the write. +For example, a compiler must not use *p as temporary storage in this program: +

+ +
+*p = i + *p/2
+
+ +

+That is, it must not rewrite the program into this one: +

+ +
+*p /= 2
+*p += i
+
+ +

+If i and *p start equal to 2, +the original code does *p = 3, +so a racing thread can read only 2 or 3 from *p. +The rewritten code does *p = 1 and then *p = 3, +allowing a racing thread to read 1 as well. +

+ +

+Note that all these optimizations are permitted in C/C++ compilers: +a Go compiler sharing a back end with a C/C++ compiler must take care +to disable optimizations that are invalid for Go. +

+ +

+Note that the prohibition on introducing data races +does not apply if the compiler can prove that the races +do not affect correct execution on the target platform. +For example, on essentially all CPUs, it is valid to rewrite +

+ +
+n := 0
+for i := 0; i < m; i++ {
+	n += *shared
+}
+
+ +into: + +
+n := 0
+local := *shared
+for i := 0; i < m; i++ {
+	n += local
+}
+
+ +

+provided it can be proved that *shared will not fault on access, +because the potential added read will not affect any existing concurrent reads or writes. +On the other hand, the rewrite would not be valid in a source-to-source translator. +

+ +

Conclusion

+ +

+Go programmers writing data-race-free programs can rely on +sequentially consistent execution of those programs, +just as in essentially all other modern programming languages. +

+ +

+When it comes to programs with races, +both programmers and compilers should remember the advice: +don't be clever. +

diff --git a/doc/go_spec.html b/doc/go_spec.html new file mode 100644 index 0000000..f93f2ab --- /dev/null +++ b/doc/go_spec.html @@ -0,0 +1,8296 @@ + + +

Introduction

+ +

+This is the reference manual for the Go programming language. +The pre-Go1.18 version, without generics, can be found +here. +For more information and other documents, see golang.org. +

+ +

+Go is a general-purpose language designed with systems programming +in mind. It is strongly typed and garbage-collected and has explicit +support for concurrent programming. Programs are constructed from +packages, whose properties allow efficient management of +dependencies. +

+ +

+The syntax is compact and simple to parse, allowing for easy analysis +by automatic tools such as integrated development environments. +

+ +

Notation

+

+The syntax is specified using a +variant +of Extended Backus-Naur Form (EBNF): +

+ +
+Syntax      = { Production } .
+Production  = production_name "=" [ Expression ] "." .
+Expression  = Term { "|" Term } .
+Term        = Factor { Factor } .
+Factor      = 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)
+
+ +

+Lowercase production names are used to identify lexical (terminal) 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. +

+ +

Source code representation

+ +

+Source code is Unicode text encoded in +UTF-8. The text is not +canonicalized, so a single accented code point is distinct from the +same character constructed from combining an accent and a letter; +those are treated as two code points. For simplicity, this document +will use the unqualified term character to refer to a Unicode code point +in the source text. +

+

+Each code point is distinct; for instance, uppercase and lowercase letters +are different characters. +

+

+Implementation restriction: For compatibility with other tools, a +compiler may disallow the NUL character (U+0000) in the source text. +

+

+Implementation restriction: For compatibility with other tools, a +compiler may ignore a UTF-8-encoded byte order mark +(U+FEFF) if it is the first Unicode code point in the source text. +A byte order mark may be disallowed anywhere else in the source. +

+ +

Characters

+ +

+The following terms are used to denote specific Unicode character categories: +

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

+In The Unicode Standard 8.0, +Section 4.5 "General Category" defines a set of character categories. +Go treats all characters in any of the Letter categories Lu, Ll, Lt, Lm, or Lo +as Unicode letters, and those in the Number category Nd as Unicode digits. +

+ +

Letters and digits

+ +

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

+
+letter        = unicode_letter | "_" .
+decimal_digit = "0" … "9" .
+binary_digit  = "0" | "1" .
+octal_digit   = "0" … "7" .
+hex_digit     = "0" … "9" | "A" … "F" | "a" … "f" .
+
+ +

Lexical elements

+ +

Comments

+ +

+Comments serve as program documentation. There are two forms: +

+ +
    +
  1. +Line comments start with the character sequence // +and stop at the end of the line. +
  2. +
  3. +General comments start with the character sequence /* +and stop with the first subsequent character sequence */. +
  4. +
+ +

+A comment cannot start inside a rune or +string literal, or inside a comment. +A general comment containing no newlines acts like a space. +Any other comment acts like a newline. +

+ +

Tokens

+ +

+Tokens form the vocabulary of the Go language. +There are four classes: identifiers, keywords, operators +and punctuation, and literals. White space, formed from +spaces (U+0020), horizontal tabs (U+0009), +carriage returns (U+000D), and newlines (U+000A), +is ignored except as it separates tokens +that would otherwise combine into a single token. Also, a newline or end of file +may trigger the insertion of a semicolon. +While breaking the input into tokens, +the next token is the longest sequence of characters that form a +valid token. +

+ +

Semicolons

+ +

+The formal syntax uses semicolons ";" as terminators in +a number of productions. Go programs may omit most of these semicolons +using the following two rules: +

+ +
    +
  1. +When the input is broken into tokens, a semicolon is automatically inserted +into the token stream immediately after a line's final token if that token is + +
  2. + +
  3. +To allow complex statements to occupy a single line, a semicolon +may be omitted before a closing ")" or "}". +
  4. +
+ +

+To reflect idiomatic use, code examples in this document elide semicolons +using these rules. +

+ + +

Identifiers

+ +

+Identifiers name program entities such as variables and types. +An identifier is a sequence of one or more letters and digits. +The first character in an identifier must be a letter. +

+
+identifier = letter { letter | unicode_digit } .
+
+
+a
+_x9
+ThisVariableIsExported
+αβ
+
+ +

+Some identifiers are predeclared. +

+ + +

Keywords

+ +

+The following keywords are reserved and may not be used as identifiers. +

+
+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 punctuation

+ +

+The following character sequences represent operators +(including assignment operators) and punctuation: +

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

Integer literals

+ +

+An integer literal is a sequence of digits representing an +integer constant. +An optional prefix sets a non-decimal base: 0b or 0B +for binary, 0, 0o, or 0O for octal, +and 0x or 0X for hexadecimal. +A single 0 is considered a decimal zero. +In hexadecimal literals, letters a through f +and A through F represent values 10 through 15. +

+ +

+For readability, an underscore character _ may appear after +a base prefix or between successive digits; such underscores do not change +the literal's value. +

+
+int_lit        = decimal_lit | binary_lit | octal_lit | hex_lit .
+decimal_lit    = "0" | ( "1" … "9" ) [ [ "_" ] decimal_digits ] .
+binary_lit     = "0" ( "b" | "B" ) [ "_" ] binary_digits .
+octal_lit      = "0" [ "o" | "O" ] [ "_" ] octal_digits .
+hex_lit        = "0" ( "x" | "X" ) [ "_" ] hex_digits .
+
+decimal_digits = decimal_digit { [ "_" ] decimal_digit } .
+binary_digits  = binary_digit { [ "_" ] binary_digit } .
+octal_digits   = octal_digit { [ "_" ] octal_digit } .
+hex_digits     = hex_digit { [ "_" ] hex_digit } .
+
+ +
+42
+4_2
+0600
+0_600
+0o600
+0O600       // second character is capital letter 'O'
+0xBadFace
+0xBad_Face
+0x_67_7a_2f_cc_40_c6
+170141183460469231731687303715884105727
+170_141183_460469_231731_687303_715884_105727
+
+_42         // an identifier, not an integer literal
+42_         // invalid: _ must separate successive digits
+4__2        // invalid: only one _ at a time
+0_xBadFace  // invalid: _ must separate successive digits
+
+ + +

Floating-point literals

+ +

+A floating-point literal is a decimal or hexadecimal representation of a +floating-point constant. +

+ +

+A decimal floating-point literal consists of an integer part (decimal digits), +a decimal point, a fractional part (decimal digits), and an exponent part +(e or E followed by an optional sign and decimal digits). +One of the integer part or the fractional part may be elided; one of the decimal point +or the exponent part may be elided. +An exponent value exp scales the mantissa (integer and fractional part) by 10exp. +

+ +

+A hexadecimal floating-point literal consists of a 0x or 0X +prefix, an integer part (hexadecimal digits), a radix point, a fractional part (hexadecimal digits), +and an exponent part (p or P followed by an optional sign and decimal digits). +One of the integer part or the fractional part may be elided; the radix point may be elided as well, +but the exponent part is required. (This syntax matches the one given in IEEE 754-2008 §5.12.3.) +An exponent value exp scales the mantissa (integer and fractional part) by 2exp. +

+ +

+For readability, an underscore character _ may appear after +a base prefix or between successive digits; such underscores do not change +the literal value. +

+ +
+float_lit         = decimal_float_lit | hex_float_lit .
+
+decimal_float_lit = decimal_digits "." [ decimal_digits ] [ decimal_exponent ] |
+                    decimal_digits decimal_exponent |
+                    "." decimal_digits [ decimal_exponent ] .
+decimal_exponent  = ( "e" | "E" ) [ "+" | "-" ] decimal_digits .
+
+hex_float_lit     = "0" ( "x" | "X" ) hex_mantissa hex_exponent .
+hex_mantissa      = [ "_" ] hex_digits "." [ hex_digits ] |
+                    [ "_" ] hex_digits |
+                    "." hex_digits .
+hex_exponent      = ( "p" | "P" ) [ "+" | "-" ] decimal_digits .
+
+ +
+0.
+72.40
+072.40       // == 72.40
+2.71828
+1.e+0
+6.67428e-11
+1E6
+.25
+.12345E+5
+1_5.         // == 15.0
+0.15e+0_2    // == 15.0
+
+0x1p-2       // == 0.25
+0x2.p10      // == 2048.0
+0x1.Fp+0     // == 1.9375
+0X.8p-0      // == 0.5
+0X_1FFFP-16  // == 0.1249847412109375
+0x15e-2      // == 0x15e - 2 (integer subtraction)
+
+0x.p1        // invalid: mantissa has no digits
+1p-2         // invalid: p exponent requires hexadecimal mantissa
+0x1.5e-2     // invalid: hexadecimal mantissa requires p exponent
+1_.5         // invalid: _ must separate successive digits
+1._5         // invalid: _ must separate successive digits
+1.5_e1       // invalid: _ must separate successive digits
+1.5e_1       // invalid: _ must separate successive digits
+1.5e1_       // invalid: _ must separate successive digits
+
+ + +

Imaginary literals

+ +

+An imaginary literal represents the imaginary part of a +complex constant. +It consists of an integer or +floating-point literal +followed by the lowercase letter i. +The value of an imaginary literal is the value of the respective +integer or floating-point literal multiplied by the imaginary unit i. +

+ +
+imaginary_lit = (decimal_digits | int_lit | float_lit) "i" .
+
+ +

+For backward compatibility, an imaginary literal's integer part consisting +entirely of decimal digits (and possibly underscores) is considered a decimal +integer, even if it starts with a leading 0. +

+ +
+0i
+0123i         // == 123i for backward-compatibility
+0o123i        // == 0o123 * 1i == 83i
+0xabci        // == 0xabc * 1i == 2748i
+0.i
+2.71828i
+1.e+0i
+6.67428e-11i
+1E6i
+.25i
+.12345E+5i
+0x1p-2i       // == 0x1p-2 * 1i == 0.25i
+
+ + +

Rune literals

+ +

+A rune literal represents a rune constant, +an integer value identifying a Unicode code point. +A rune literal is expressed as one or more characters enclosed in single quotes, +as in 'x' or '\n'. +Within the quotes, any character may appear except newline and unescaped single +quote. A single quoted character represents the Unicode value +of the character itself, +while multi-character sequences beginning with a backslash encode +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. +

+ +

+Several backslash escapes allow arbitrary values to be encoded 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. +In each case the value of the literal is the value represented by +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 escapes \u and \U +represent Unicode code points so within them some values are illegal, +in particular those above 0x10FFFF and surrogate halves. +

+ +

+After a backslash, certain single-character escapes represent special values: +

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

+An unrecognized character following a backslash in a rune literal is illegal. +

+ +
+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" | `\` | "'" | `"` ) .
+
+ +
+'a'
+'ä'
+'本'
+'\t'
+'\000'
+'\007'
+'\377'
+'\x07'
+'\xff'
+'\u12e4'
+'\U00101234'
+'\''         // rune literal containing single quote character
+'aa'         // illegal: too many characters
+'\k'         // illegal: k is not recognized after a backslash
+'\xa'        // illegal: too few hexadecimal digits
+'\0'         // illegal: too few octal digits
+'\400'       // illegal: octal value over 255
+'\uDFFF'     // illegal: surrogate half
+'\U00110000' // illegal: invalid Unicode code point
+
+ + +

String literals

+ +

+A string literal represents a string constant +obtained from concatenating a sequence of characters. There are two forms: +raw string literals and interpreted string literals. +

+ +

+Raw string literals are character sequences between back quotes, as in +`foo`. Within the quotes, any character may appear except +back quote. 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. +Carriage return characters ('\r') inside raw string literals +are discarded from the raw string value. +

+ +

+Interpreted string literals are character sequences between double +quotes, as in "bar". +Within the quotes, any character may appear except newline and unescaped double quote. +The text between the quotes forms the +value of the literal, with backslash escapes interpreted as they +are in rune literals (except that \' is illegal and +\" is legal), with the same restrictions. +The three-digit octal (\nnn) +and two-digit hexadecimal (\xnn) 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 +U+00FF. +

+ +
+string_lit             = raw_string_lit | interpreted_string_lit .
+raw_string_lit         = "`" { unicode_char | newline } "`" .
+interpreted_string_lit = `"` { unicode_value | byte_value } `"` .
+
+ +
+`abc`                // same as "abc"
+`\n
+\n`                  // same as "\\n\n\\n"
+"\n"
+"\""                 // same as `"`
+"Hello, world!\n"
+"日本語"
+"\u65e5本\U00008a9e"
+"\xff\u00FF"
+"\uD800"             // illegal: surrogate half
+"\U00110000"         // illegal: invalid Unicode code point
+
+ +

+These examples all represent the same string: +

+ +
+"日本語"                                 // UTF-8 input text
+`日本語`                                 // UTF-8 input text as a raw literal
+"\u65e5\u672c\u8a9e"                    // the explicit Unicode code points
+"\U000065e5\U0000672c\U00008a9e"        // the explicit Unicode code points
+"\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e"  // the explicit UTF-8 bytes
+
+ +

+If the source code represents a character as two code points, such as +a combining form involving an accent and a letter, the result will be +an error if placed in a rune literal (it is not a single code +point), and will appear as two code points if placed in a string +literal. +

+ + +

Constants

+ +

There are boolean constants, +rune constants, +integer constants, +floating-point constants, complex constants, +and string constants. Rune, integer, floating-point, +and complex constants are +collectively called numeric constants. +

+ +

+A constant value is represented by a +rune, +integer, +floating-point, +imaginary, +or +string literal, +an identifier denoting a constant, +a constant expression, +a conversion with a result that is a constant, or +the result value of some built-in functions such as +unsafe.Sizeof applied to certain values, +cap or len applied to +some expressions, +real and imag applied to a complex constant +and complex applied to numeric constants. +The boolean truth values are represented by the predeclared constants +true and false. The predeclared identifier +iota denotes an integer constant. +

+ +

+In general, complex constants are a form of +constant expression +and are discussed in that section. +

+ +

+Numeric constants represent exact values of arbitrary precision and do not overflow. +Consequently, there are no constants denoting the IEEE-754 negative zero, infinity, +and not-a-number values. +

+ +

+Constants may be typed or untyped. +Literal constants, true, false, iota, +and certain constant expressions +containing only untyped constant operands are untyped. +

+ +

+A constant may be given a type explicitly by a constant declaration +or conversion, or implicitly when used in a +variable declaration or an +assignment statement or as an +operand in an expression. +It is an error if the constant value +cannot be represented as a value of the respective type. +If the type is a type parameter, the constant is converted into a non-constant +value of the type parameter. +

+ +

+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, +for instance, in a short variable declaration +such as i := 0 where there is no explicit type. +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. +

+ +

+Implementation restriction: Although numeric constants have arbitrary +precision in the language, a compiler may implement them using an +internal representation with limited precision. That said, every +implementation must: +

+ + + +

+These requirements apply both to literal constants and to the result +of evaluating constant +expressions. +

+ + +

Variables

+ +

+A variable is a storage location for holding a value. +The set of permissible values is determined by the +variable's type. +

+ +

+A variable declaration +or, for function parameters and results, the signature +of a function declaration +or function literal reserves +storage for a named variable. + +Calling the built-in function new +or taking the address of a composite literal +allocates storage for a variable at run time. +Such an anonymous variable is referred to via a (possibly implicit) +pointer indirection. +

+ +

+Structured variables of array, slice, +and struct types have elements and fields that may +be addressed individually. Each such element +acts like a variable. +

+ +

+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 +(unless the value is the predeclared identifier nil, +which has no type). +The dynamic type may vary during execution but values stored in interface +variables are always assignable +to the static type of the variable. +

+ +
+var x interface{}  // x is nil and has static type interface{}
+var v *T           // v has value nil, static type *T
+x = 42             // x has value 42 and dynamic type int
+x = v              // x has value (*T)(nil) and dynamic type *T
+
+ +

+A variable's value is retrieved by referring to the variable in an +expression; it is the most recent value +assigned to the variable. +If a variable has not yet been assigned a value, its value is the +zero value for its type. +

+ + +

Types

+ +

+A type determines a set of values together with operations and methods specific +to those values. A type may be denoted by a type name, if it has one, which must be +followed by type arguments if the type is generic. +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 .
+
+ +

+The language predeclares certain type names. +Others are introduced with type declarations +or type parameter lists. +Composite types—array, struct, pointer, function, +interface, slice, map, and channel types—may be constructed using +type literals. +

+ +

+Predeclared types, defined types, and type parameters are called named types. +An alias denotes a named type if the type given in the alias declaration is a named type. +

+ +

Boolean types

+ +

+A boolean type represents the set of Boolean truth values +denoted by the predeclared constants true +and false. The predeclared boolean type is bool; +it is a defined type. +

+ +

Numeric types

+ +

+An integer, floating-point, or complex type +represents the set of integer, floating-point, or complex values, respectively. +They are collectively called numeric types. +The predeclared architecture-independent numeric types are: +

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

+The value of an n-bit integer is n bits wide and represented using +two's complement arithmetic. +

+ +

+There is also a set of predeclared integer types with implementation-specific sizes: +

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

+To avoid portability issues all numeric types are defined +types and thus distinct except +byte, which is an alias for uint8, and +rune, which is an alias for int32. +Explicit conversions +are required when different numeric types are mixed in an expression +or assignment. For instance, int32 and int +are not the same type even though they may have the same size on a +particular architecture. + + +

String types

+ +

+A string type represents the set of string values. +A string value is a (possibly empty) sequence of bytes. +The number of bytes is called the length of the string and is never negative. +Strings are immutable: once created, +it is impossible to change the contents of a string. +The predeclared string type is string; +it is a defined type. +

+ +

+The length of a string s can be discovered using +the built-in function len. +The length is a compile-time constant if the string is a constant. +A string's bytes can be accessed by integer indices +0 through len(s)-1. +It is illegal to take the address of such an element; if +s[i] is the i'th byte of a +string, &s[i] is invalid. +

+ + +

Array types

+ +

+An array is a numbered sequence of elements of a single +type, called the element type. +The number of elements is called the length of the array and is never negative. +

+ +
+ArrayType   = "[" ArrayLength "]" ElementType .
+ArrayLength = Expression .
+ElementType = Type .
+
+ +

+The length is part of the array's type; it must evaluate to a +non-negative constant +representable by a value +of type int. +The length of array a can be discovered +using the built-in function len. +The elements can be addressed by integer indices +0 through len(a)-1. +Array types are always one-dimensional but may be composed to form +multi-dimensional types. +

+ +
+[32]byte
+[2*N] struct { x, y int32 }
+[1000]*float64
+[3][5]int
+[2][2][2]float64  // same as [2]([2]([2]float64))
+
+ +

+An array type T may not have an element of type T, +or of a type containing T as a component, directly or indirectly, +if those containing types are only array or struct types. +

+ +
+// invalid array types
+type (
+	T1 [10]T1                 // element type of T1 is T1
+	T2 [10]struct{ f T2 }     // T2 contains T2 as component of a struct
+	T3 [10]T4                 // T3 contains T3 as component of a struct in T4
+	T4 struct{ f T3 }         // T4 contains T4 as component of array T3 in a struct
+)
+
+// valid array types
+type (
+	T5 [10]*T5                // T5 contains T5 as component of a pointer
+	T6 [10]func() T6          // T6 contains T6 as component of a function type
+	T7 [10]struct{ f []T7 }   // T7 contains T7 as component of a slice in a struct
+)
+
+ +

Slice types

+ +

+A slice is a descriptor for a contiguous segment of an underlying array and +provides access to a numbered sequence of elements from that array. +A slice type denotes the set of all slices of arrays of its element type. +The number of elements is called the length of the slice and is never negative. +The value of an uninitialized slice is nil. +

+ +
+SliceType = "[" "]" ElementType .
+
+ +

+The length of a slice s can be discovered by the built-in function +len; unlike with arrays it may change during +execution. The elements can be addressed by integer indices +0 through len(s)-1. The slice index of a +given element may be less than the index of the same element in the +underlying array. +

+

+A slice, once initialized, is always associated with an underlying +array that holds its elements. A slice therefore shares storage +with its array and with other slices of the same array; by contrast, +distinct arrays always represent distinct storage. +

+

+The array underlying a slice may extend past the end of the slice. +The capacity is a measure of that extent: it is the sum of +the length of the slice and the length of the array beyond the slice; +a slice of length up to that capacity can be created by +slicing a new one from the original slice. +The capacity of a slice a can be discovered using the +built-in function cap(a). +

+ +

+A new, initialized slice value for a given element type T may be +made using the built-in function +make, +which takes a slice type +and parameters specifying the length and optionally the capacity. +A slice created with make always allocates a new, hidden array +to which the returned slice value refers. That is, executing +

+ +
+make([]T, length, capacity)
+
+ +

+produces the same slice as allocating an array and slicing +it, so these two expressions are equivalent: +

+ +
+make([]int, 50, 100)
+new([100]int)[0:50]
+
+ +

+Like arrays, slices are always one-dimensional but may be composed to construct +higher-dimensional objects. +With arrays of arrays, the inner arrays are, by construction, always the same length; +however with slices of slices (or arrays of slices), the inner lengths may vary dynamically. +Moreover, the inner slices must be initialized individually. +

+ +

Struct types

+ +

+A struct is a sequence of named elements, called fields, each of which has a +name and a type. Field names may be specified explicitly (IdentifierList) or +implicitly (EmbeddedField). +Within a struct, non-blank field names must +be unique. +

+ +
+StructType    = "struct" "{" { FieldDecl ";" } "}" .
+FieldDecl     = (IdentifierList Type | EmbeddedField) [ Tag ] .
+EmbeddedField = [ "*" ] TypeName [ TypeArgs ] .
+Tag           = string_lit .
+
+ +
+// An empty struct.
+struct {}
+
+// A struct with 6 fields.
+struct {
+	x, y int
+	u float32
+	_ float32  // padding
+	A *[]int
+	F func()
+}
+
+ +

+A field declared with a type but no explicit field name is called an embedded field. +An embedded field must be specified as +a type name T or as a pointer to a non-interface type name *T, +and T itself may not be +a pointer type. The unqualified type name acts as the field name. +

+ +
+// A struct with four embedded fields of types T1, *T2, P.T3 and *P.T4
+struct {
+	T1        // field name is T1
+	*T2       // field name is T2
+	P.T3      // field name is T3
+	*P.T4     // field name is T4
+	x, y int  // field names are x and y
+}
+
+ +

+The following declaration is illegal because field names must be unique +in a struct type: +

+ +
+struct {
+	T     // conflicts with embedded field *T and *P.T
+	*T    // conflicts with embedded field T and *P.T
+	*P.T  // conflicts with embedded field T and *T
+}
+
+ +

+A field or method f of an +embedded field in a struct x is called promoted if +x.f is a legal selector that denotes +that field or method f. +

+ +

+Promoted fields act like ordinary fields +of a struct except that they cannot be used as field names in +composite literals of the struct. +

+ +

+Given a struct type S and a named type +T, promoted methods are included in the method set of the struct as follows: +

+ + +

+A field declaration may be followed by an optional string literal tag, +which becomes an attribute for all the fields in the corresponding +field declaration. An empty tag string is equivalent to an absent tag. +The tags are made visible through a reflection interface +and take part in type identity for structs +but are otherwise ignored. +

+ +
+struct {
+	x, y float64 ""  // an empty tag string is like an absent tag
+	name string  "any string is permitted as a tag"
+	_    [4]byte "ceci n'est pas un champ de structure"
+}
+
+// A struct corresponding to a TimeStamp protocol buffer.
+// The tag strings define the protocol buffer field numbers;
+// they follow the convention outlined by the reflect package.
+struct {
+	microsec  uint64 `protobuf:"1"`
+	serverIP6 uint64 `protobuf:"2"`
+}
+
+ +

+A struct type T may not contain a field of type T, +or of a type containing T as a component, directly or indirectly, +if those containing types are only array or struct types. +

+ +
+// invalid struct types
+type (
+	T1 struct{ T1 }            // T1 contains a field of T1
+	T2 struct{ f [10]T2 }      // T2 contains T2 as component of an array
+	T3 struct{ T4 }            // T3 contains T3 as component of an array in struct T4
+	T4 struct{ f [10]T3 }      // T4 contains T4 as component of struct T3 in an array
+)
+
+// valid struct types
+type (
+	T5 struct{ f *T5 }         // T5 contains T5 as component of a pointer
+	T6 struct{ f func() T6 }   // T6 contains T6 as component of a function type
+	T7 struct{ f [10][]T7 }    // T7 contains T7 as component of a slice in an array
+)
+
+ +

Pointer types

+ +

+A pointer type denotes the set of all pointers to variables of a given +type, called the base type of the pointer. +The value of an uninitialized pointer is nil. +

+ +
+PointerType = "*" BaseType .
+BaseType    = Type .
+
+ +
+*Point
+*[4]int
+
+ +

Function types

+ +

+A function type denotes the set of all functions with the same parameter +and result types. The value of an uninitialized variable of function type +is nil. +

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

+Within a list of parameters or results, the names (IdentifierList) +must either all be present or all be absent. If present, each name +stands for one item (parameter or result) of the specified type and +all non-blank names in the signature +must be unique. +If absent, each type stands for one item of that type. +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. +

+ +
+func()
+func(x int) int
+func(a, _ int, z float32) bool
+func(a, b int, z float32) (bool)
+func(prefix string, values ...int)
+func(a, b int, z float64, opt ...interface{}) (success bool)
+func(int, int, float64) (float64, *[]int)
+func(n int) func(p *T)
+
+ +

Interface types

+ +

+An interface type defines a type set. +A variable of interface type can store a value of any type that is in the type +set of the interface. Such a type is said to +implement the interface. +The value of an uninitialized variable of interface type is nil. +

+ +
+InterfaceType  = "interface" "{" { InterfaceElem ";" } "}" .
+InterfaceElem  = MethodElem | TypeElem .
+MethodElem     = MethodName Signature .
+MethodName     = identifier .
+TypeElem       = TypeTerm { "|" TypeTerm } .
+TypeTerm       = Type | UnderlyingType .
+UnderlyingType = "~" Type .
+
+ +

+An interface type is specified by a list of interface elements. +An interface element is either a method or a type element, +where a type element is a union of one or more type terms. +A type term is either a single type or a single underlying type. +

+ +

Basic interfaces

+ +

+In its most basic form an interface specifies a (possibly empty) list of methods. +The type set defined by such an interface is the set of types which implement all of +those methods, and the corresponding method set consists +exactly of the methods specified by the interface. +Interfaces whose type sets can be defined entirely by a list of methods are called +basic interfaces. +

+ +
+// A simple File interface.
+interface {
+	Read([]byte) (int, error)
+	Write([]byte) (int, error)
+	Close() error
+}
+
+ +

+The name of each explicitly specified method must be unique +and not blank. +

+ +
+interface {
+	String() string
+	String() string  // illegal: String not unique
+	_(x int)         // illegal: method must have non-blank name
+}
+
+ +

+More than one type may implement an interface. +For instance, if two types S1 and S2 +have the method set +

+ +
+func (p T) Read(p []byte) (n int, err error)
+func (p T) Write(p []byte) (n int, err error)
+func (p T) Close() error
+
+ +

+(where T stands for either S1 or S2) +then the File interface is implemented by both S1 and +S2, regardless of what other methods +S1 and S2 may have or share. +

+ +

+Every type that is a member of the type set of an interface implements that interface. +Any given type may implement several distinct interfaces. +For instance, all types implement the empty interface which stands for the set +of all (non-interface) types: +

+ +
+interface{}
+
+ +

+For convenience, the predeclared type any is an alias for the empty interface. +

+ +

+Similarly, consider this interface specification, +which appears within a type declaration +to define an interface called Locker: +

+ +
+type Locker interface {
+	Lock()
+	Unlock()
+}
+
+ +

+If S1 and S2 also implement +

+ +
+func (p T) Lock() { … }
+func (p T) Unlock() { … }
+
+ +

+they implement the Locker interface as well +as the File interface. +

+ +

Embedded interfaces

+ +

+In a slightly more general form +an interface T may use a (possibly qualified) interface type +name E as an interface element. This is called +embedding interface E in T. +The type set of T is the intersection of the type sets +defined by T's explicitly declared methods and the type sets +of T’s embedded interfaces. +In other words, the type set of T is the set of all types that implement all the +explicitly declared methods of T and also all the methods of +E. +

+ +
+type Reader interface {
+	Read(p []byte) (n int, err error)
+	Close() error
+}
+
+type Writer interface {
+	Write(p []byte) (n int, err error)
+	Close() error
+}
+
+// ReadWriter's methods are Read, Write, and Close.
+type ReadWriter interface {
+	Reader  // includes methods of Reader in ReadWriter's method set
+	Writer  // includes methods of Writer in ReadWriter's method set
+}
+
+ +

+When embedding interfaces, methods with the +same names must +have identical signatures. +

+ +
+type ReadCloser interface {
+	Reader   // includes methods of Reader in ReadCloser's method set
+	Close()  // illegal: signatures of Reader.Close and Close are different
+}
+
+ +

General interfaces

+ +

+In their most general form, an interface element may also be an arbitrary type term +T, or a term of the form ~T specifying the underlying type T, +or a union of terms t1|t2|…|tn. +Together with method specifications, these elements enable the precise +definition of an interface's type set as follows: +

+ + + +

+The quantification "the set of all non-interface types" refers not just to all (non-interface) +types declared in the program at hand, but all possible types in all possible programs, and +hence is infinite. +Similarly, given the set of all non-interface types that implement a particular method, the +intersection of the method sets of those types will contain exactly that method, even if all +types in the program at hand always pair that method with another method. +

+ +

+By construction, an interface's type set never contains an interface type. +

+ +
+// An interface representing only the type int.
+interface {
+	int
+}
+
+// An interface representing all types with underlying type int.
+interface {
+	~int
+}
+
+// An interface representing all types with underlying type int that implement the String method.
+interface {
+	~int
+	String() string
+}
+
+// An interface representing an empty type set: there is no type that is both an int and a string.
+interface {
+	int
+	string
+}
+
+ +

+In a term of the form ~T, the underlying type of T +must be itself, and T cannot be an interface. +

+ +
+type MyInt int
+
+interface {
+	~[]byte  // the underlying type of []byte is itself
+	~MyInt   // illegal: the underlying type of MyInt is not MyInt
+	~error   // illegal: error is an interface
+}
+
+ +

+Union elements denote unions of type sets: +

+ +
+// The Float interface represents all floating-point types
+// (including any named types whose underlying types are
+// either float32 or float64).
+type Float interface {
+	~float32 | ~float64
+}
+
+ +

+The type T in a term of the form T or ~T cannot +be a type parameter, and the type sets of all +non-interface terms must be pairwise disjoint (the pairwise intersection of the type sets must be empty). +Given a type parameter P: +

+ +
+interface {
+	P                // illegal: P is a type parameter
+	int | ~P         // illegal: P is a type parameter
+	~int | MyInt     // illegal: the type sets for ~int and MyInt are not disjoint (~int includes MyInt)
+	float32 | Float  // overlapping type sets but Float is an interface
+}
+
+ +

+Implementation restriction: +A union (with more than one term) cannot contain the +predeclared identifier comparable +or interfaces that specify methods, or embed comparable or interfaces +that specify methods. +

+ +

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

+An interface type T may not embed a type element +that is, contains, or embeds T, directly or indirectly. +

+ +
+// illegal: Bad may not embed itself
+type Bad interface {
+	Bad
+}
+
+// illegal: Bad1 may not embed itself using Bad2
+type Bad1 interface {
+	Bad2
+}
+type Bad2 interface {
+	Bad1
+}
+
+// illegal: Bad3 may not embed a union containing Bad3
+type Bad3 interface {
+	~int | ~string | Bad3
+}
+
+// illegal: Bad4 may not embed an array containing Bad4 as element type
+type Bad4 interface {
+	[10]Bad4
+}
+
+ +

Implementing an interface

+ +

+A type T implements an interface I if +

+ + + +

+A value of type T implements an interface if T +implements the interface. +

+ +

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. +The value of an uninitialized map is nil. +

+ +
+MapType     = "map" "[" KeyType "]" ElementType .
+KeyType     = Type .
+
+ +

+The comparison operators +== and != must be fully defined +for operands of the key type; thus the key type must not be a function, map, or +slice. +If the key type is an interface type, these +comparison operators must be defined for the dynamic key values; +failure will cause a run-time panic. +

+ +
+map[string]int
+map[*T]struct{ x, y float64 }
+map[string]interface{}
+
+ +

+The number of map elements is called its length. +For a map m, it can be discovered using the +built-in function len +and may change during execution. Elements may be added during execution +using assignments and retrieved with +index expressions; they may be removed with the +delete built-in function. +

+

+A new, empty map value is made using the built-in +function make, +which takes the map type and an optional capacity hint as arguments: +

+ +
+make(map[string]int)
+make(map[string]int, 100)
+
+ +

+The initial capacity does not bound its size: +maps grow to accommodate the number of items +stored in them, with the exception of nil maps. +A nil map is equivalent to an empty map except that no elements +may be added. + +

Channel types

+ +

+A channel provides a mechanism for +concurrently executing functions +to communicate by +sending and +receiving +values of a specified element type. +The value of an uninitialized channel is nil. +

+ +
+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 channel may be constrained only to send or only to receive by +assignment or +explicit conversion. +

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

+The <- operator associates with the leftmost chan +possible: +

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

+A new, initialized channel +value can be made using the built-in function +make, +which takes the channel type and an optional capacity as arguments: +

+ +
+make(chan int, 100)
+
+ +

+The capacity, in number of elements, sets the size of the buffer in the channel. +If the capacity is zero or absent, the channel is unbuffered and communication +succeeds only when both a sender and receiver are ready. Otherwise, the channel +is buffered and communication succeeds without blocking if the buffer +is not full (sends) or not empty (receives). +A nil channel is never ready for communication. +

+ +

+A channel may be closed with the built-in function +close. +The multi-valued assignment form of the +receive operator +reports whether a received value was sent before +the channel was closed. +

+ +

+A single channel may be used in +send statements, +receive operations, +and calls to the built-in functions +cap and +len +by any number of goroutines without further synchronization. +Channels act as first-in-first-out queues. +For example, if one goroutine sends values on a channel +and a second goroutine receives them, the values are +received in the order sent. +

+ +

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. +For a type parameter that is the underlying type of its +type constraint, which is always an interface. +

+ +
+type (
+	A1 = string
+	A2 = A1
+)
+
+type (
+	B1 string
+	B2 B1
+	B3 []B1
+	B4 B3
+)
+
+func f[P any](x P) { … }
+
+ +

+The underlying type of string, A1, A2, B1, +and B2 is string. +The underlying type of []B1, B3, and B4 is []B1. +The underlying type of P is interface{}. +

+ +

Core types

+ +

+Each non-interface type T has a core type, which is the same as the +underlying type of T. +

+ +

+An interface T has a core type if one of the following +conditions is satisfied: +

+ +
    +
  1. +There is a single type U which is the underlying type +of all types in the type set of T; or +
  2. +
  3. +the type set of T contains only channel types +with identical element type E, and all directional channels have the same +direction. +
  4. +
+ +

+No other interfaces have a core type. +

+ +

+The core type of an interface is, depending on the condition that is satisfied, either: +

+ +
    +
  1. +the type U; or +
  2. +
  3. +the type chan E if T contains only bidirectional +channels, or the type chan<- E or <-chan E +depending on the direction of the directional channels present. +
  4. +
+ +

+By definition, a core type is never a defined type, +type parameter, or +interface type. +

+ +

+Examples of interfaces with core types: +

+ +
+type Celsius float32
+type Kelvin  float32
+
+interface{ int }                          // int
+interface{ Celsius|Kelvin }               // float32
+interface{ ~chan int }                    // chan int
+interface{ ~chan int|~chan<- int }        // chan<- int
+interface{ ~[]*data; String() string }    // []*data
+
+ +

+Examples of interfaces without core types: +

+ +
+interface{}                               // no single underlying type
+interface{ Celsius|float64 }              // no single underlying type
+interface{ chan int | chan<- string }     // channels have different element types
+interface{ <-chan int | chan<- int }      // directional channels have different directions
+
+ +

+Some operations (slice expressions, +append and copy) +rely on a slightly more loose form of core types which accept byte slices and strings. +Specifically, if there are exactly two types, []byte and string, +which are the underlying types of all types in the type set of interface T, +the core type of T is called bytestring. +

+ +

+Examples of interfaces with bytestring core types: +

+ +
+interface{ int }                          // int (same as ordinary core type)
+interface{ []byte | string }              // bytestring
+interface{ ~[]byte | myString }           // bytestring
+
+ +

+Note that bytestring is not a real type; it cannot be used to declare +variables are compose other types. It exists solely to describe the behavior of some +operations that read from a sequence of bytes, which may be a byte slice or a string. +

+ +

Type identity

+ +

+Two types are either identical or different. +

+ +

+A named type is always different from any other type. +Otherwise, two types are identical if their underlying type literals are +structurally equivalent; that is, they have the same literal structure and corresponding +components have identical types. In detail: +

+ + + +

+Given the declarations +

+ +
+type (
+	A0 = []string
+	A1 = A0
+	A2 = struct{ a, b int }
+	A3 = int
+	A4 = func(A3, float64) *A0
+	A5 = func(x int, _ float64) *[]string
+
+	B0 A0
+	B1 []string
+	B2 struct{ a, b int }
+	B3 struct{ a, c int }
+	B4 func(int, float64) *B0
+	B5 func(x int, y float64) *A1
+
+	C0 = B0
+	D0[P1, P2 any] struct{ x P1; y P2 }
+	E0 = D0[int, string]
+)
+
+ +

+these types are identical: +

+ +
+A0, A1, and []string
+A2 and struct{ a, b int }
+A3 and int
+A4, func(int, float64) *[]string, and A5
+
+B0 and C0
+D0[int, string] and E0
+[]int and []int
+struct{ a, b *B5 } and struct{ a, b *B5 }
+func(x int, y float64) *[]string, func(int, float64) (result *[]string), and A5
+
+ +

+B0 and B1 are different because they are new types +created by distinct type definitions; +func(int, float64) *B0 and func(x int, y float64) *[]string +are different because B0 is different from []string; +and P1 and P2 are different because they are different +type parameters. +D0[int, string] and struct{ x int; y string } are +different because the former is an instantiated +defined type while the latter is a type literal +(but they are still assignable). +

+ +

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: +

+ + + +

+Additionally, if x's type V or T are type parameters, x +is assignable to a variable of type T if one of the following conditions applies: +

+ + + +

Representability

+ +

+A constant x is representable +by a value of type T, +where T is not a type parameter, +if one of the following conditions applies: +

+ + + +

+If T is a type parameter, +x is representable by a value of type T if x is representable +by a value of each type in T's type set. +

+ +
+x                   T           x is representable by a value of T because
+
+'a'                 byte        97 is in the set of byte values
+97                  rune        rune is an alias for int32, and 97 is in the set of 32-bit integers
+"foo"               string      "foo" is in the set of string values
+1024                int16       1024 is in the set of 16-bit integers
+42.0                byte        42 is in the set of unsigned 8-bit integers
+1e10                uint64      10000000000 is in the set of unsigned 64-bit integers
+2.718281828459045   float32     2.718281828459045 rounds to 2.7182817 which is in the set of float32 values
+-1e-1000            float64     -1e-1000 rounds to IEEE -0.0 which is further simplified to 0.0
+0i                  int         0 is an integer value
+(42 + 0i)           float32     42.0 (with zero imaginary part) is in the set of float32 values
+
+ +
+x                   T           x is not representable by a value of T because
+
+0                   bool        0 is not in the set of boolean values
+'a'                 string      'a' is a rune, it is not in the set of string values
+1024                byte        1024 is not in the set of unsigned 8-bit integers
+-1                  uint16      -1 is not in the set of unsigned 16-bit integers
+1.1                 int         1.1 is not an integer value
+42i                 float32     (0 + 42i) is not in the set of float32 values
+1e1000              float64     1e1000 overflows to IEEE +Inf after rounding
+
+ +

Method sets

+ +

+The method set of a type determines the methods that can be +called on an operand of that type. +Every type has a (possibly empty) method set associated with it: +

+ + + +

+Further rules apply to structs (and pointer to structs) containing embedded fields, +as described in the section on struct types. +Any other type has an empty method set. +

+ +

+In a method set, each method must have a +unique +non-blank method name. +

+ +

Blocks

+ +

+A block is a possibly empty sequence of declarations and statements +within matching brace brackets. +

+ +
+Block = "{" StatementList "}" .
+StatementList = { Statement ";" } .
+
+ +

+In addition to explicit blocks in the source code, there are implicit blocks: +

+ +
    +
  1. The universe block encompasses all Go source text.
  2. + +
  3. Each package has a package block containing all + Go source text for that package.
  4. + +
  5. Each file has a file block containing all Go source text + in that file.
  6. + +
  7. Each "if", + "for", and + "switch" + statement is considered to be in its own implicit block.
  8. + +
  9. Each clause in a "switch" + or "select" statement + acts as an implicit block.
  10. +
+ +

+Blocks nest and influence scoping. +

+ + +

Declarations and scope

+ +

+A declaration binds a non-blank identifier to a +constant, +type, +type parameter, +variable, +function, +label, or +package. +Every identifier in a program must be declared. +No identifier may be declared twice in the same block, and +no identifier may be declared in both the file and package block. +

+ +

+The blank identifier may be used like any other identifier +in a declaration, but it does not introduce a binding and thus is not declared. +In the package block, the identifier init may only be used for +init function declarations, +and like the blank identifier it does not introduce a new binding. +

+ +
+Declaration   = ConstDecl | TypeDecl | VarDecl .
+TopLevelDecl  = Declaration | FunctionDecl | MethodDecl .
+
+ +

+The scope of a declared identifier is the extent of source text in which +the identifier denotes the specified constant, type, variable, function, label, or package. +

+ +

+Go is lexically scoped using blocks: +

+ +
    +
  1. The scope of a predeclared identifier is the universe block.
  2. + +
  3. The scope of an identifier denoting a constant, type, variable, + or function (but not method) declared at top level (outside any + function) is the package block.
  4. + +
  5. The scope of the package name of an imported package is the file block + of the file containing the import declaration.
  6. + +
  7. The scope of an identifier denoting a method receiver, function parameter, + or result variable is the function body.
  8. + +
  9. The scope of an identifier denoting a type parameter of a function + or declared by a method receiver begins after the name of the function + and ends at the end of the function body.
  10. + +
  11. The scope of an identifier denoting a type parameter of a type + begins after the name of the type and ends at the end + of the TypeSpec.
  12. + +
  13. The scope of a constant or variable identifier declared + inside a function begins at the end of the ConstSpec or VarSpec + (ShortVarDecl for short variable declarations) + and ends at the end of the innermost containing block.
  14. + +
  15. The scope of a type identifier declared inside a function + begins at the identifier in the TypeSpec + and ends at the end of the innermost containing block.
  16. +
+ +

+An identifier declared in a block may be redeclared in an inner block. +While the identifier of the inner declaration is in scope, it denotes +the entity declared by the inner declaration. +

+ +

+The package clause is not a declaration; the package name +does not appear in any scope. Its purpose is to identify the files belonging +to the same package and to specify the default package name for import +declarations. +

+ + +

Label scopes

+ +

+Labels are declared by labeled statements and are +used in the "break", +"continue", and +"goto" statements. +It is illegal to define a label that is never used. +In contrast to other identifiers, labels are not block scoped and do +not conflict with identifiers that are not labels. The scope of a label +is the body of the function in which it is declared and excludes +the body of any nested function. +

+ + +

Blank identifier

+ +

+The blank identifier is represented by the underscore character _. +It serves as an anonymous placeholder instead of a regular (non-blank) +identifier and has special meaning in declarations, +as an operand, and in assignment statements. +

+ + +

Predeclared identifiers

+ +

+The following identifiers are implicitly declared in the +universe block: +

+
+Types:
+	any bool byte comparable
+	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 uppercase + letter (Unicode character category Lu); and
  2. +
  3. the identifier is declared in the package block + or it is a field name or + method name.
  4. +
+

+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

+ +

+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, and the nth identifier on +the left is bound to the value of the nth expression on the +right. +

+ +
+ConstDecl      = "const" ( ConstSpec | "(" { ConstSpec ";" } ")" ) .
+ConstSpec      = IdentifierList [ [ Type ] "=" ExpressionList ] .
+
+IdentifierList = identifier { "," identifier } .
+ExpressionList = Expression { "," Expression } .
+
+ +

+If the type is present, all constants take the type specified, and +the expressions must be assignable to that type, +which must not be a type parameter. +If the type is omitted, the constants take the +individual types of the corresponding expressions. +If the expression values are untyped constants, +the declared constants remain untyped and the constant identifiers +denote the constant values. For instance, if the expression is a +floating-point literal, the constant identifier denotes a floating-point +constant, even if the literal's fractional part is zero. +

+ +
+const Pi float64 = 3.14159265358979323846
+const zero = 0.0         // untyped floating-point constant
+const (
+	size int64 = 1024
+	eof        = -1  // untyped integer constant
+)
+const a, b, c = 3, 4, "foo"  // a = 3, b = 4, c = "foo", untyped integer and string constants
+const u, v float32 = 0, 3    // u = 0.0, v = 3.0
+
+ +

+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. The number of identifiers must be equal +to the number of expressions in the previous list. +Together with the iota constant generator +this mechanism permits light-weight declaration of sequential values: +

+ +
+const (
+	Sunday = iota
+	Monday
+	Tuesday
+	Wednesday
+	Thursday
+	Friday
+	Partyday
+	numberOfDays  // this constant is not exported
+)
+
+ + +

Iota

+ +

+Within a constant declaration, the predeclared identifier +iota represents successive untyped integer +constants. Its value is the index of the respective ConstSpec +in that constant declaration, starting at zero. +It can be used to construct a set of related constants: +

+ +
+const (
+	c0 = iota  // c0 == 0
+	c1 = iota  // c1 == 1
+	c2 = iota  // c2 == 2
+)
+
+const (
+	a = 1 << iota  // a == 1  (iota == 0)
+	b = 1 << iota  // b == 2  (iota == 1)
+	c = 3          // c == 3  (iota == 2, unused)
+	d = 1 << iota  // d == 8  (iota == 3)
+)
+
+const (
+	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
+const y = iota  // y == 0
+
+ +

+By definition, multiple uses of iota in the same ConstSpec all have the same value: +

+ +
+const (
+	bit0, mask0 = 1 << iota, 1<<iota - 1  // bit0 == 1, mask0 == 0  (iota == 0)
+	bit1, mask1                           // bit1 == 2, mask1 == 1  (iota == 1)
+	_, _                                  //                        (iota == 2, unused)
+	bit3, mask3                           // bit3 == 8, mask3 == 7  (iota == 3)
+)
+
+ +

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

+ + +

Type declarations

+ +

+A type declaration binds an identifier, the type name, to a type. +Type declarations come in two forms: alias declarations and type definitions. +

+ +
+TypeDecl = "type" ( TypeSpec | "(" { TypeSpec ";" } ")" ) .
+TypeSpec = AliasDecl | TypeDef .
+
+ +

Alias declarations

+ +

+An alias declaration binds an identifier to the given type. +

+ +
+AliasDecl = identifier "=" Type .
+
+ +

+Within the scope of +the identifier, it serves as an alias for the type. +

+ +
+type (
+	nodeList = []*Node  // nodeList and []*Node are identical types
+	Polar    = polar    // Polar and polar denote identical types
+)
+
+ + +

Type definitions

+ +

+A type definition creates a new, distinct type with the same +underlying type and operations as the given type +and binds an identifier, the type name, to it. +

+ +
+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
+)
+
+type TreeNode struct {
+	left, right *TreeNode
+	value any
+}
+
+type Block interface {
+	BlockSize() int
+	Encrypt(src, dst []byte)
+	Decrypt(src, dst []byte)
+}
+
+ +

+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: +

+ +
+// 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 PtrMutex's underlying type *Mutex 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 embedded field Mutex.
+type PrintableMutex struct {
+	Mutex
+}
+
+// MyBlock is an interface type that has the same method set as Block.
+type MyBlock Block
+
+ +

+Type definitions may be used to define different boolean, numeric, +or string types and associate methods with them: +

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

+If the type definition specifies type parameters, +the type name denotes a generic type. +Generic types must be instantiated when they +are used. +

+ +
+type List[T any] struct {
+	next  *List[T]
+	value T
+}
+
+ +

+In a type definition the given type cannot be a type parameter. +

+ +
+type T[P any] P    // illegal: P is a type parameter
+
+func f[T any]() {
+	type L T   // illegal: T is a type parameter declared by the enclosing function
+}
+
+ +

+A generic type may also have methods associated with it. +In this case, the method receivers must declare the same number of type parameters as +present in the generic type definition. +

+ +
+// The method Len returns the number of elements in the linked list l.
+func (l *List[T]) Len() int  { … }
+
+ +

Type parameter declarations

+ +

+A type parameter list declares the type parameters of a generic function or type declaration. +The type parameter list looks like an ordinary function parameter list +except that the type parameter names must all be present and the list is enclosed +in square brackets rather than parentheses. +

+ +
+TypeParameters  = "[" TypeParamList [ "," ] "]" .
+TypeParamList   = TypeParamDecl { "," TypeParamDecl } .
+TypeParamDecl   = IdentifierList TypeConstraint .
+
+ +

+All non-blank names in the list must be unique. +Each name declares a type parameter, which is a new and different named type +that acts as a place holder for an (as of yet) unknown type in the declaration. +The type parameter is replaced with a type argument upon +instantiation of the generic function or type. +

+ +
+[P any]
+[S interface{ ~[]byte|string }]
+[S ~[]E, E any]
+[P Constraint[int]]
+[_ any]
+
+ +

+Just as each ordinary function parameter has a parameter type, each type parameter +has a corresponding (meta-)type which is called its +type constraint. +

+ +

+A parsing ambiguity arises when the type parameter list for a generic type +declares a single type parameter P with a constraint C +such that the text P C forms a valid expression: +

+ +
+type T[P *C] …
+type T[P (C)] …
+type T[P *C|Q] …
+…
+
+ +

+In these rare cases, the type parameter list is indistinguishable from an +expression and the type declaration is parsed as an array type declaration. +To resolve the ambiguity, embed the constraint in an +interface or use a trailing comma: +

+ +
+type T[P interface{*C}] …
+type T[P *C,] …
+
+ +

+Type parameters may also be declared by the receiver specification +of a method declaration associated +with a generic type. +

+ +

+Within a type parameter list of a generic type T, a type constraint +may not (directly, or indirectly through the type parameter list of another +generic type) refer to T. +

+ +
+type T1[P T1[P]] …                    // illegal: T1 refers to itself
+type T2[P interface{ T2[int] }] …     // illegal: T2 refers to itself
+type T3[P interface{ m(T3[int])}] …   // illegal: T3 refers to itself
+type T4[P T5[P]] …                    // illegal: T4 refers to T5 and
+type T5[P T4[P]] …                    //          T5 refers to T4
+
+type T6[P int] struct{ f *T6[P] }     // ok: reference to T6 is not in type parameter list
+
+ +

Type constraints

+ +

+A type constraint is an interface that defines the +set of permissible type arguments for the respective type parameter and controls the +operations supported by values of that type parameter. +

+ +
+TypeConstraint = TypeElem .
+
+ +

+If the constraint is an interface literal of the form interface{E} where +E is an embedded type element (not a method), in a type parameter list +the enclosing interface{ … } may be omitted for convenience: +

+ +
+[T []P]                      // = [T interface{[]P}]
+[T ~int]                     // = [T interface{~int}]
+[T int|string]               // = [T interface{int|string}]
+type Constraint ~int         // illegal: ~int is not in a type parameter list
+
+ + + +

+The predeclared +interface type comparable +denotes the set of all non-interface types that are +strictly comparable. +

+ +

+Even though interfaces that are not type parameters are comparable, +they are not strictly comparable and therefore they do not implement comparable. +However, they satisfy comparable. +

+ +
+int                          // implements comparable (int is strictly comparable)
+[]byte                       // does not implement comparable (slices cannot be compared)
+interface{}                  // does not implement comparable (see above)
+interface{ ~int | ~string }  // type parameter only: implements comparable (int, string types are stricly comparable)
+interface{ comparable }      // type parameter only: implements comparable (comparable implements itself)
+interface{ ~int | ~[]byte }  // type parameter only: does not implement comparable (slices are not comparable)
+interface{ ~struct{ any } }  // type parameter only: does not implement comparable (field any is not strictly comparable)
+
+ +

+The comparable interface and interfaces that (directly or indirectly) embed +comparable may only be used as type constraints. They cannot be the types of +values or variables, or components of other, non-interface types. +

+ +

Satisfying a type constraint

+ +

+A type argument T satisfies a type constraint C +if T is an element of the type set defined by C; i.e., +if T implements C. +As an exception, a strictly comparable +type constraint may also be satisfied by a comparable +(not necessarily strictly comparable) type argument. +More precisely: +

+ +

+A type T satisfies a constraint C if +

+ + + +
+type argument      type constraint                // constraint satisfaction
+
+int                interface{ ~int }              // satisfied: int implements interface{ ~int }
+string             comparable                     // satisfied: string implements comparable (string is stricty comparable)
+[]byte             comparable                     // not satisfied: slices are not comparable
+any                interface{ comparable; int }   // not satisfied: any does not implement interface{ int }
+any                comparable                     // satisfied: any is comparable and implements the basic interface any
+struct{f any}      comparable                     // satisfied: struct{f any} is comparable and implements the basic interface any
+any                interface{ comparable; m() }   // not satisfied: any does not implement the basic interface interface{ m() }
+interface{ m() }   interface{ comparable; m() }   // satisfied: interface{ m() } is comparable and implements the basic interface interface{ m() }
+
+ +

+Because of the exception in the constraint satisfaction rule, comparing operands of type parameter type +may panic at run-time (even though comparable type parameters are always strictly comparable). +

+ +

Variable declarations

+ +

+A variable declaration creates one or more variables, +binds corresponding identifiers to them, and gives each a type and an initial value. +

+ +
+VarDecl     = "var" ( VarSpec | "(" { VarSpec ";" } ")" ) .
+VarSpec     = IdentifierList ( Type [ "=" ExpressionList ] | "=" ExpressionList ) .
+
+ +
+var i int
+var U, V, W float64
+var k = 0
+var x, y float32 = -1, -2
+var (
+	i       int
+	u, v, s = 2.0, 3.0, "bar"
+)
+var re, im = complexSqrt(-1)
+var _, found = entries[name]  // map lookup; only interested in "found"
+
+ +

+If a list of expressions is given, the variables are initialized +with the expressions following the rules for assignment statements. +Otherwise, each variable is initialized to its zero value. +

+ +

+If a type is present, each variable is given that type. +Otherwise, each variable is given the type of the corresponding +initialization value in the assignment. +If that value is an untyped constant, it is first implicitly +converted to its default type; +if it is an untyped boolean value, it is first implicitly converted to type bool. +The predeclared value nil cannot be used to initialize a variable +with no explicit type. +

+ +
+var d = math.Sin(0.5)  // d is float64
+var i = 42             // i is int
+var t, ok = x.(T)      // t is T, ok is bool
+var n = nil            // illegal
+
+ +

+Implementation restriction: A compiler may make it illegal to declare a variable +inside a function body if the variable is +never used. +

+ +

Short variable declarations

+ +

+A short variable declaration uses the syntax: +

+ +
+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()  // os.Pipe() returns a connected pair of Files and an error, if any
+_, 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. +The non-blank variable names on the left side of := +must be unique. +

+ +
+field1, offset := nextField(str, 0)
+field2, offset := nextField(str, offset)  // redeclares offset
+x, y, x := 1, 2, 3                        // illegal: x repeated on left side of :=
+
+ +

+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

+ + + +

+A function declaration binds an identifier, the function name, +to a function. +

+ +
+FunctionDecl = "func" FunctionName [ TypeParameters ] Signature [ FunctionBody ] .
+FunctionName = identifier .
+FunctionBody = Block .
+
+ +

+If the function's signature declares +result parameters, the function body's statement list must end in +a terminating statement. +

+ +
+func IndexRune(s string, r rune) int {
+	for i, c := range s {
+		if c == r {
+			return i
+		}
+	}
+	// invalid: missing return statement
+}
+
+ +

+If the function declaration specifies type parameters, +the function name denotes a generic function. +A generic function must be instantiated before it can be +called or used as a value. +

+ +
+func min[T ~int|~float64](x, y T) T {
+	if x < y {
+		return x
+	}
+	return y
+}
+
+ +

+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. +

+ +
+func flushICache(begin, end uintptr)  // implemented externally
+
+ +

Method declarations

+ +

+A method is a function with a receiver. +A method declaration binds an identifier, the method name, to a method, +and associates the method with the receiver's base type. +

+ +
+MethodDecl = "func" Receiver MethodName Signature [ FunctionBody ] .
+Receiver   = Parameters .
+
+ +

+The receiver is specified via an extra parameter section preceding the method +name. That parameter section must declare a single non-variadic parameter, the receiver. +Its type must be a defined type T or a +pointer to a defined type T, possibly followed by a list of type parameter +names [P1, P2, …] enclosed in square brackets. +T is called the receiver base type. 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. +

+ +

+A non-blank receiver identifier must be +unique in the method signature. +If the receiver's value is not referenced inside the body of the method, +its identifier may be omitted in the declaration. The same applies in +general to parameters of functions and methods. +

+ +

+For a base type, the non-blank names of methods bound to it must be unique. +If the base type is a struct type, +the non-blank method and field names must be distinct. +

+ +

+Given defined type Point the declarations +

+ +
+func (p *Point) Length() float64 {
+	return math.Sqrt(p.x * p.x + p.y * p.y)
+}
+
+func (p *Point) Scale(factor float64) {
+	p.x *= factor
+	p.y *= factor
+}
+
+ +

+bind the methods Length and Scale, +with receiver type *Point, +to the base type Point. +

+ +

+If the receiver base type is a generic type, the +receiver specification must declare corresponding type parameters for the method +to use. This makes the receiver type parameters available to the method. +Syntactically, this type parameter declaration looks like an +instantiation of the receiver base type: the type +arguments must be identifiers denoting the type parameters being declared, one +for each type parameter of the receiver base type. +The type parameter names do not need to match their corresponding parameter names in the +receiver base type definition, and all non-blank parameter names must be unique in the +receiver parameter section and the method signature. +The receiver type parameter constraints are implied by the receiver base type definition: +corresponding type parameters have corresponding constraints. +

+ +
+type Pair[A, B any] struct {
+	a A
+	b B
+}
+
+func (p Pair[A, B]) Swap() Pair[B, A]  { … }  // receiver declares A, B
+func (p Pair[First, _]) First() First  { … }  // receiver declares First, corresponds to A in Pair
+
+ +

Expressions

+ +

+An expression specifies the computation of a value by applying +operators and functions to operands. +

+ +

Operands

+ +

+Operands denote the elementary values in an expression. An operand may be a +literal, a (possibly qualified) +non-blank identifier denoting a +constant, +variable, or +function, +or a parenthesized expression. +

+ +
+Operand     = Literal | OperandName [ TypeArgs ] | "(" Expression ")" .
+Literal     = BasicLit | CompositeLit | FunctionLit .
+BasicLit    = int_lit | float_lit | imaginary_lit | rune_lit | string_lit .
+OperandName = identifier | QualifiedIdent .
+
+ +

+An operand name denoting a generic function +may be followed by a list of type arguments; the +resulting operand is an instantiated function. +

+ +

+The blank identifier may appear as an +operand only on the left-hand side of an assignment statement. +

+ +

+Implementation restriction: A compiler need not report an error if an operand's +type is a type parameter with an empty +type set. Functions with such type parameters +cannot be instantiated; any attempt will lead +to an error at the instantiation site. +

+ +

Qualified identifiers

+ +

+A qualified identifier is an identifier qualified with a package name prefix. +Both the package name and the identifier must not be +blank. +

+ +
+QualifiedIdent = PackageName "." identifier .
+
+ +

+A qualified identifier accesses an identifier in a different package, which +must be imported. +The identifier must be exported and +declared in the package block of that package. +

+ +
+math.Sin // denotes the Sin function in package math
+
+ +

Composite literals

+ +

+Composite literals construct new composite values each time they are evaluated. +They consist of the type of the literal followed by a brace-bound list of elements. +Each element may optionally be preceded by a corresponding key. +

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

+The LiteralType's core type T +must be a struct, array, slice, or map type +(the syntax enforces this constraint except when the type is given +as a TypeName). +The types of the elements and keys must be assignable +to the respective field, element, and key types of type T; +there is no additional conversion. +The key is interpreted as a field name for struct literals, +an index for array and slice literals, and a key for map literals. +For map literals, all elements must have a key. It is an error +to specify multiple elements with the same field name or +constant key value. For non-constant map keys, see the section on +evaluation order. +

+ +

+For struct literals the following rules apply: +

+ + +

+Given the declarations +

+
+type Point3D struct { x, y, z float64 }
+type Line struct { p, q Point3D }
+
+ +

+one may write +

+ +
+origin := Point3D{}                            // zero value for Point3D
+line := Line{origin, Point3D{y: -4, z: 12.3}}  // zero value for line.q.x
+
+ +

+For array and slice literals the following rules apply: +

+ + +

+Taking the address of a composite literal +generates a pointer to a unique variable initialized +with the literal's value. +

+ +
+var pointer *Point3D = &Point3D{y: 1000}
+
+ +

+Note that the zero value for a slice or map +type is not the same as an initialized but empty value of the same type. +Consequently, taking the address of an empty slice or map composite literal +does not have the same effect as allocating a new slice or map value with +new. +

+ +
+p1 := &[]int{}    // p1 points to an initialized, empty slice with value []int{} and length 0
+p2 := new([]int)  // p2 points to an uninitialized slice with value nil and length 0
+
+ +

+The length of an array literal is the length specified in the literal type. +If fewer elements than the length are provided in the literal, the missing +elements are set to the zero value for the array element type. +It is an error to provide elements with index values outside the index range +of the array. The notation ... specifies an array length equal +to the maximum element index plus one. +

+ +
+buffer := [10]string{}             // len(buffer) == 10
+intSet := [6]int{1, 2, 3, 5}       // len(intSet) == 6
+days := [...]string{"Sat", "Sun"}  // len(days) == 2
+
+ +

+A slice literal describes the entire underlying array literal. +Thus the length and capacity of a slice literal are the maximum +element index plus one. A slice literal has the form +

+ +
+[]T{x1, x2, … xn}
+
+ +

+and is shorthand for a slice operation applied to an array: +

+ +
+tmp := [n]T{x1, x2, … xn}
+tmp[0 : n]
+
+ +

+Within a composite literal of array, slice, or map type T, +elements or map keys that are themselves composite literals may elide the respective +literal type if it is identical to the element or key type of T. +Similarly, elements or keys that are addresses of composite literals may elide +the &T when the element or key type is *T. +

+ +
+[...]Point{{1.5, -3.5}, {0, 0}}     // same as [...]Point{Point{1.5, -3.5}, Point{0, 0}}
+[][]int{{1, 2, 3}, {4, 5}}          // same as [][]int{[]int{1, 2, 3}, []int{4, 5}}
+[][]Point{{{0, 1}, {1, 2}}}         // same as [][]Point{[]Point{Point{0, 1}, Point{1, 2}}}
+map[string]Point{"orig": {0, 0}}    // same as map[string]Point{"orig": Point{0, 0}}
+map[Point]string{{0, 0}: "orig"}    // same as map[Point]string{Point{0, 0}: "orig"}
+
+type PPoint *Point
+[2]*Point{{1.5, -3.5}, {}}          // same as [2]*Point{&Point{1.5, -3.5}, &Point{}}
+[2]PPoint{{1.5, -3.5}, {}}          // same as [2]PPoint{PPoint(&Point{1.5, -3.5}), PPoint(&Point{})}
+
+ +

+A parsing ambiguity arises when a composite literal using the +TypeName form of the LiteralType appears as an operand between the +keyword and the opening brace of the block +of an "if", "for", or "switch" statement, and the composite literal +is not enclosed in parentheses, square brackets, or curly braces. +In this rare case, the opening brace of the literal is erroneously parsed +as the one introducing the block of statements. To resolve the ambiguity, +the composite literal must appear within parentheses. +

+ +
+if x == (T{a,b,c}[i]) { … }
+if (x == T{a,b,c}[i]) { … }
+
+ +

+Examples of valid array, slice, and map literals: +

+ +
+// list of prime numbers
+primes := []int{2, 3, 5, 7, 9, 2147483647}
+
+// vowels[ch] is true if ch is a vowel
+vowels := [128]bool{'a': true, 'e': true, 'i': true, 'o': true, 'u': true, 'y': true}
+
+// the array [10]float32{-1, 0, 0, 0, -0.1, -0.1, 0, 0, 0, -1}
+filter := [10]float32{-1, 4: -0.1, -0.1, 9: -1}
+
+// frequencies in Hz for equal-tempered scale (A4 = 440Hz)
+noteFrequency := map[string]float32{
+	"C0": 16.35, "D0": 18.35, "E0": 20.60, "F0": 21.83,
+	"G0": 24.50, "A0": 27.50, "B0": 30.87,
+}
+
+ + +

Function literals

+ +

+A function literal represents an anonymous function. +Function literals cannot declare type parameters. +

+ +
+FunctionLit = "func" Signature FunctionBody .
+
+ +
+func(a, b int, z float64) bool { return a*b < int(z) }
+
+ +

+A function literal can be assigned to a variable or invoked directly. +

+ +
+f := func(x, y int) int { return x + y }
+func(ch chan int) { ch <- ACK }(replyChan)
+
+ +

+Function literals are closures: they may refer to variables +defined in a surrounding function. Those variables are then shared between +the surrounding function and the function literal, and they survive as long +as they are accessible. +

+ + +

Primary expressions

+ +

+Primary expressions are the operands for unary and binary expressions. +

+ +
+PrimaryExpr =
+	Operand |
+	Conversion |
+	MethodExpr |
+	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 ] ) [ "..." ] [ "," ] ] ")" .
+
+ + +
+x
+2
+(s + ".txt")
+f(3.1415, true)
+Point{1, 2}
+m["foo"]
+s[i : j + 1]
+obj.color
+f.p[i].x()
+
+ + +

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 +embedded field of T. +The number of embedded 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 embedded 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. + +
  3. +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. +
  4. + +
  5. +As an exception, if the type of x is a defined +pointer type and (*x).f is a valid selector expression denoting a field +(but not a method), x.f is shorthand for (*x).f. +
  6. + +
  7. +In all other cases, x.f is illegal. +
  8. + +
  9. +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. +
  10. + +
  11. +If x is of interface type and has the value +nil, calling or +evaluating the method x.f +causes a run-time panic. +
  12. +
+ +

+For example, given the declarations: +

+ +
+type T0 struct {
+	x int
+}
+
+func (*T0) M0()
+
+type T1 struct {
+	y int
+}
+
+func (T1) M1()
+
+type T2 struct {
+	z int
+	T1
+	*T0
+}
+
+func (*T2) M2()
+
+type Q *T2
+
+var t T2     // with t.T0 != nil
+var p *T2    // with p != nil and (*p).T0 != nil
+var q Q = p
+
+ +

+one may write: +

+ +
+t.z          // t.z
+t.y          // t.T1.y
+t.x          // (*t.T0).x
+
+p.z          // (*p).z
+p.y          // (*p).T1.y
+p.x          // (*(*p).T0).x
+
+q.x          // (*(*q).T0).x        (*q).x is a valid field selector
+
+p.M0()       // ((*p).T0).M0()      M0 expects *T0 receiver
+p.M1()       // ((*p).T1).M1()      M1 expects T1 receiver
+p.M2()       // p.M2()              M2 expects *T2 receiver
+t.M2()       // (&t).M2()           M2 expects *T2 receiver, see section on Calls
+
+ +

+but the following is invalid: +

+ +
+q.M0()       // (*q).M0 is valid but not a field selector
+
+ + +

Method expressions

+ +

+If M is in the method set of type T, +T.M is a function that is callable as a regular function +with the same arguments as M prefixed by an additional +argument that is the receiver of the method. +

+ +
+MethodExpr    = ReceiverType "." MethodName .
+ReceiverType  = Type .
+
+ +

+Consider a struct type T with two methods, +Mv, whose receiver is of type T, and +Mp, whose receiver is of type *T. +

+ +
+type T struct {
+	a int
+}
+func (tv  T) Mv(a int) int         { return 0 }  // value receiver
+func (tp *T) Mp(f float32) float32 { return 1 }  // pointer receiver
+
+var t T
+
+ +

+The expression +

+ +
+T.Mv
+
+ +

+yields a function equivalent to Mv but +with an explicit receiver as its first argument; it has signature +

+ +
+func(tv T, a int) int
+
+ +

+That function may be called normally with an explicit receiver, so +these five invocations are equivalent: +

+ +
+t.Mv(7)
+T.Mv(t, 7)
+(T).Mv(t, 7)
+f1 := T.Mv; f1(t, 7)
+f2 := (T).Mv; f2(t, 7)
+
+ +

+Similarly, the expression +

+ +
+(*T).Mp
+
+ +

+yields a function value representing Mp with signature +

+ +
+func(tp *T, f float32) float32
+
+ +

+For a method with a value receiver, one can derive a function +with an explicit pointer receiver, so +

+ +
+(*T).Mv
+
+ +

+yields a function value representing Mv with signature +

+ +
+func(tv *T, a int) int
+
+ +

+Such a function indirects through the receiver to create a value +to pass as the receiver to the underlying method; +the method does not overwrite the value whose address is passed in +the function call. +

+ +

+The final case, a value-receiver function for a pointer-receiver method, +is illegal because pointer-receiver methods are not in the method set +of the value type. +

+ +

+Function values derived from methods are called with function call syntax; +the receiver is provided as the first argument to the call. +That is, given f := T.Mv, f is invoked +as f(t, 7) not t.f(7). +To construct a function that binds the receiver, use a +function literal or +method value. +

+ +

+It is legal to derive a function value from a method of an interface type. +The resulting function takes an explicit receiver of that interface type. +

+ +

Method values

+ +

+If the expression x has static type T and +M is in the method set of type T, +x.M is called a method value. +The method value x.M is a function value that is callable +with the same arguments as a method call of x.M. +The expression x is evaluated and saved during the evaluation of the +method value; the saved copy is then used as the receiver in any calls, +which may be executed later. +

+ +
+type S struct { *T }
+type T int
+func (t T) M() { print(t) }
+
+t := new(T)
+s := S{T: t}
+f := t.M                    // receiver *t is evaluated and stored in f
+g := s.M                    // receiver *(s.T) is evaluated and stored in g
+*t = 42                     // does not affect stored receivers in f and g
+
+ +

+The type T may be an interface or non-interface type. +

+ +

+As in the discussion of method expressions above, +consider a struct type T with two methods, +Mv, whose receiver is of type T, and +Mp, whose receiver is of type *T. +

+ +
+type T struct {
+	a int
+}
+func (tv  T) Mv(a int) int         { return 0 }  // value receiver
+func (tp *T) Mp(f float32) float32 { return 1 }  // pointer receiver
+
+var t T
+var pt *T
+func makeT() T
+
+ +

+The expression +

+ +
+t.Mv
+
+ +

+yields a function value of type +

+ +
+func(int) int
+
+ +

+These two invocations are equivalent: +

+ +
+t.Mv(7)
+f := t.Mv; f(7)
+
+ +

+Similarly, the expression +

+ +
+pt.Mp
+
+ +

+yields a function value of type +

+ +
+func(float32) float32
+
+ +

+As with selectors, a reference to a non-interface method with a value receiver +using a pointer will automatically dereference that pointer: pt.Mv is equivalent to (*pt).Mv. +

+ +

+As with method calls, a reference to a non-interface method with a pointer receiver +using an addressable value will automatically take the address of that value: t.Mp is equivalent to (&t).Mp. +

+ +
+f := t.Mv; f(7)   // like t.Mv(7)
+f := pt.Mp; f(7)  // like pt.Mp(7)
+f := pt.Mv; f(7)  // like (*pt).Mv(7)
+f := t.Mp; f(7)   // like (&t).Mp(7)
+f := makeT().Mp   // invalid: result of makeT() is not addressable
+
+ +

+Although the examples above use non-interface types, it is also legal to create a method value +from a value of interface type. +

+ +
+var i interface { M(int) } = myVal
+f := i.M; f(7)  // like i.M(7)
+
+ + +

Index expressions

+ +

+A primary expression of the form +

+ +
+a[x]
+
+ +

+denotes the element of the array, pointer to array, slice, string or map a indexed by x. +The value x is called the index or map key, respectively. +The following rules apply: +

+ +

+If a is neither a map nor a type parameter: +

+ + +

+For a of array type A: +

+ + +

+For a of pointer to array type: +

+ + +

+For a of slice type S: +

+ + +

+For a of string type: +

+ + +

+For a of map type M: +

+ + +

+For a of type parameter type P: +

+ + +

+Otherwise a[x] is illegal. +

+ +

+An index expression on a map a of type map[K]V +used in an assignment statement or initialization of the special form +

+ +
+v, ok = a[x]
+v, ok := a[x]
+var v, ok = a[x]
+
+ +

+yields an additional untyped boolean value. The value of ok is +true if the key x is present in the map, and +false otherwise. +

+ +

+Assigning to an element of a nil map causes a +run-time panic. +

+ + +

Slice expressions

+ +

+Slice expressions construct a substring or slice from a string, array, pointer +to array, or slice. There are two variants: a simple form that specifies a low +and high bound, and a full form that also specifies a bound on the capacity. +

+ +

Simple slice expressions

+ +

+The primary expression +

+ +
+a[low : high]
+
+ +

+constructs a substring or slice. The core type of +a must be a string, array, pointer to array, slice, or a +bytestring. +The indices low and +high select which elements of operand a appear +in the result. The result has indices starting at 0 and length equal to +high - low. +After slicing the array a +

+ +
+a := [5]int{1, 2, 3, 4, 5}
+s := a[1:4]
+
+ +

+the slice s has type []int, length 3, capacity 4, and elements +

+ +
+s[0] == 2
+s[1] == 3
+s[2] == 4
+
+ +

+For convenience, any of the indices may be omitted. A missing low +index defaults to zero; a missing high index defaults to the length of the +sliced operand: +

+ +
+a[2:]  // same as a[2 : len(a)]
+a[:3]  // same as a[0 : 3]
+a[:]   // same as a[0 : len(a)]
+
+ +

+If a is a pointer to an array, a[low : high] is shorthand for +(*a)[low : high]. +

+ +

+For arrays or strings, the indices are in range if +0 <= low <= high <= len(a), +otherwise they are out of range. +For slices, the upper index bound is the slice capacity cap(a) rather than the length. +A constant index must be non-negative and +representable by a value of type +int; for arrays or constant strings, constant indices must also be in range. +If both indices are constant, they must satisfy low <= high. +If the indices are out of range at run time, a run-time panic occurs. +

+ +

+Except for untyped strings, if the sliced operand is a string or slice, +the result of the slice operation is a non-constant value of the same type as the operand. +For untyped string operands the result is a non-constant value of type string. +If the sliced operand is an array, it must be addressable +and the result of the slice operation is a slice with the same element type as the array. +

+ +

+If the sliced operand of a valid slice expression is a nil slice, the result +is a nil slice. Otherwise, if the result is a slice, it shares its underlying +array with the operand. +

+ +
+var a [10]int
+s1 := a[3:7]   // underlying array of s1 is array a; &s1[2] == &a[5]
+s2 := s1[1:4]  // underlying array of s2 is underlying array of s1 which is array a; &s2[1] == &a[5]
+s2[1] = 42     // s2[1] == s1[2] == a[5] == 42; they all refer to the same underlying array element
+
+var s []int
+s3 := s[:0]    // s3 == nil
+
+ + +

Full slice expressions

+ +

+The primary expression +

+ +
+a[low : high : max]
+
+ +

+constructs a slice of the same type, and with the same length and elements as the simple slice +expression a[low : high]. Additionally, it controls the resulting slice's capacity +by setting it to max - low. Only the first index may be omitted; it defaults to 0. +The core type of a must be an array, pointer to array, +or slice (but not a string). +After slicing the array a +

+ +
+a := [5]int{1, 2, 3, 4, 5}
+t := a[1:3:5]
+
+ +

+the slice t has type []int, length 2, capacity 4, and elements +

+ +
+t[0] == 2
+t[1] == 3
+
+ +

+As for simple slice expressions, if a is a pointer to an array, +a[low : high : max] is shorthand for (*a)[low : high : max]. +If the sliced operand is an array, it must be addressable. +

+ +

+The indices are in range if 0 <= low <= high <= max <= cap(a), +otherwise they are out of range. +A constant index must be non-negative and +representable by a value of type +int; for arrays, constant indices must also be in range. +If multiple indices are constant, the constants that are present must be in range relative to each +other. +If the indices are out of range at run time, a run-time panic occurs. +

+ +

Type assertions

+ +

+For an expression x of interface type, +but not a type parameter, and a type T, +the primary expression +

+ +
+x.(T)
+
+ +

+asserts that x is not nil +and that the value stored in x is of type T. +The notation x.(T) is called a type assertion. +

+

+More precisely, if T is not an interface type, x.(T) asserts +that the dynamic type of x is identical +to the type T. +In this case, T must implement the (interface) type of x; +otherwise the type assertion is invalid since it is not possible for x +to store a value of type T. +If T is an interface type, x.(T) asserts that the dynamic type +of x implements the interface T. +

+

+If the type assertion holds, the value of the expression is the value +stored in x and its type is T. If the type assertion is false, +a run-time panic occurs. +In other words, even though the dynamic type of x +is known only at run time, the type of x.(T) is +known to be T in a correct program. +

+ +
+var x interface{} = 7          // x has dynamic type int and value 7
+i := x.(int)                   // i has type int and value 7
+
+type I interface { m() }
+
+func f(y I) {
+	s := y.(string)        // illegal: string does not implement I (missing method m)
+	r := y.(io.Reader)     // r has type io.Reader and the dynamic type of y must implement both I and io.Reader
+	…
+}
+
+ +

+A type assertion used in an assignment statement or initialization of the special form +

+ +
+v, ok = x.(T)
+v, ok := x.(T)
+var v, ok = x.(T)
+var v, ok interface{} = x.(T) // dynamic types of v and ok are T and bool
+
+ +

+yields an additional untyped boolean value. The value of ok is true +if the assertion holds. Otherwise it is false and the value of v is +the zero value for type T. +No run-time panic occurs in this case. +

+ + +

Calls

+ +

+Given an expression f with a core type +F of function type, +

+ +
+f(a1, a2, … an)
+
+ +

+calls f with arguments a1, a2, … an. +Except for one special case, arguments must be single-valued expressions +assignable to the parameter types of +F and are evaluated before the function is called. +The type of the expression is the result type +of F. +A method invocation is similar but the method itself +is specified as a selector upon a value of the receiver type for +the method. +

+ +
+math.Atan2(x, y)  // function call
+var pt *Point
+pt.Scale(3.5)     // method call with receiver pt
+
+ +

+If f denotes a generic function, it must be +instantiated before it can be called +or used as a function value. +

+ +

+In a function call, the function value and arguments are evaluated in +the usual order. +After they are evaluated, the parameters of the call are passed by value to the function +and the called function begins execution. +The return parameters of the function are passed by value +back to the caller when the function returns. +

+ +

+Calling a nil function value +causes a run-time panic. +

+ +

+As a special case, if the return values of a function or method +g are equal in number and individually +assignable to the parameters of another function or method +f, then the call f(g(parameters_of_g)) +will invoke f after binding the return values of +g to the parameters of f in order. The call +of f must contain no parameters other than the call of g, +and g must have at least one return value. +If f has a final ... parameter, it is +assigned the return values of g that remain after +assignment of regular parameters. +

+ +
+func Split(s string, pos int) (string, string) {
+	return s[0:pos], s[pos:]
+}
+
+func Join(s, t string) string {
+	return s + t
+}
+
+if Join(Split(value, len(value)/2)) != value {
+	log.Panic("test fails")
+}
+
+ +

+A method call x.m() is valid if the method set +of (the type of) x contains m and the +argument list can be assigned to the parameter list of m. +If x is addressable and &x's method +set contains m, x.m() is shorthand +for (&x).m(): +

+ +
+var p Point
+p.Scale(3.5)
+
+ +

+There is no distinct method type and there are no method literals. +

+ +

Passing arguments to ... parameters

+ +

+If f is variadic with a final +parameter p of type ...T, then within f +the type of p is equivalent to type []T. +If f is invoked with no actual arguments for p, +the value passed to p is nil. +Otherwise, the value passed is a new slice +of type []T with a new underlying array whose successive elements +are the actual arguments, which all must be assignable +to T. The length and capacity of the slice is therefore +the number of arguments bound to p and may differ for each +call site. +

+ +

+Given the function and calls +

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

+within Greeting, who will have the value +nil in the first call, and +[]string{"Joe", "Anna", "Eileen"} in the second. +

+ +

+If the final argument is assignable to a slice type []T and +is followed by ..., it is passed unchanged as the value +for a ...T parameter. In this case no new slice is created. +

+ +

+Given the slice s and call +

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

+within Greeting, who will have the same value as s +with the same underlying array. +

+ +

Instantiations

+ +

+A generic function or type is instantiated by substituting type arguments +for the type parameters. +Instantiation proceeds in two steps: +

+ +
    +
  1. +Each type argument is substituted for its corresponding type parameter in the generic +declaration. +This substitution happens across the entire function or type declaration, +including the type parameter list itself and any types in that list. +
  2. + +
  3. +After substitution, each type argument must satisfy +the constraint (instantiated, if necessary) +of the corresponding type parameter. Otherwise instantiation fails. +
  4. +
+ +

+Instantiating a type results in a new non-generic named type; +instantiating a function produces a new non-generic function. +

+ +
+type parameter list    type arguments    after substitution
+
+[P any]                int               int satisfies any
+[S ~[]E, E any]        []int, int        []int satisfies ~[]int, int satisfies any
+[P io.Writer]          string            illegal: string doesn't satisfy io.Writer
+[P comparable]         any               any satisfies (but does not implement) comparable
+
+ +

+For a generic function, type arguments may be provided explicitly, or they +may be partially or completely inferred. +A generic function that is not called requires a +type argument list for instantiation; if the list is partial, all +remaining type arguments must be inferrable. +A generic function that is called may provide a (possibly partial) type +argument list, or may omit it entirely if the omitted type arguments are +inferrable from the ordinary (non-type) function arguments. +

+ +
+func min[T ~int|~float64](x, y T) T { … }
+
+f := min                   // illegal: min must be instantiated with type arguments when used without being called
+minInt := min[int]         // minInt has type func(x, y int) int
+a := minInt(2, 3)          // a has value 2 of type int
+b := min[float64](2.0, 3)  // b has value 2.0 of type float64
+c := min(b, -1)            // c has value -1.0 of type float64
+
+ +

+A partial type argument list cannot be empty; at least the first argument must be present. +The list is a prefix of the full list of type arguments, leaving the remaining arguments +to be inferred. Loosely speaking, type arguments may be omitted from "right to left". +

+ +
+func apply[S ~[]E, E any](s S, f func(E) E) S { … }
+
+f0 := apply[]                  // illegal: type argument list cannot be empty
+f1 := apply[[]int]             // type argument for S explicitly provided, type argument for E inferred
+f2 := apply[[]string, string]  // both type arguments explicitly provided
+
+var bytes []byte
+r := apply(bytes, func(byte) byte { … })  // both type arguments inferred from the function arguments
+
+ +

+For a generic type, all type arguments must always be provided explicitly. +

+ +

Type inference

+ +

+Missing function type arguments may be inferred by a series of steps, described below. +Each step attempts to use known information to infer additional type arguments. +Type inference stops as soon as all type arguments are known. +After type inference is complete, it is still necessary to substitute all type arguments +for type parameters and verify that each type argument +implements the relevant constraint; +it is possible for an inferred type argument to fail to implement a constraint, in which +case instantiation fails. +

+ +

+Type inference is based on +

+ + + +

+and then proceeds with the following steps: +

+ +
    +
  1. + apply function argument type inference + to all typed ordinary function arguments +
  2. +
  3. + apply constraint type inference +
  4. +
  5. + apply function argument type inference to all untyped ordinary function arguments + using the default type for each of the untyped function arguments +
  6. +
  7. + apply constraint type inference +
  8. +
+ +

+If there are no ordinary or untyped function arguments, the respective steps are skipped. +Constraint type inference is skipped if the previous step didn't infer any new type arguments, +but it is run at least once if there are missing type arguments. +

+ +

+The substitution map M is carried through all steps, and each step may add entries to M. +The process stops as soon as M has a type argument for each type parameter or if an inference step fails. +If an inference step fails, or if M is still missing type arguments after the last step, type inference fails. +

+ +

Type unification

+ +

+Type inference is based on type unification. A single unification step +applies to a substitution map and two types, either +or both of which may be or contain type parameters. The substitution map tracks +the known (explicitly provided or already inferred) type arguments: the map +contains an entry PA for each type +parameter P and corresponding known type argument A. +During unification, known type arguments take the place of their corresponding type +parameters when comparing types. Unification is the process of finding substitution +map entries that make the two types equivalent. +

+ +

+For unification, two types that don't contain any type parameters from the current type +parameter list are equivalent +if they are identical, or if they are channel types that are identical ignoring channel +direction, or if their underlying types are equivalent. +

+ +

+Unification works by comparing the structure of pairs of types: their structure +disregarding type parameters must be identical, and types other than type parameters +must be equivalent. +A type parameter in one type may match any complete subtype in the other type; +each successful match causes an entry to be added to the substitution map. +If the structure differs, or types other than type parameters are not equivalent, +unification fails. +

+ + + +

+For example, if T1 and T2 are type parameters, +[]map[int]bool can be unified with any of the following: +

+ +
+[]map[int]bool   // types are identical
+T1               // adds T1 → []map[int]bool to substitution map
+[]T1             // adds T1 → map[int]bool to substitution map
+[]map[T1]T2      // adds T1 → int and T2 → bool to substitution map
+
+ +

+On the other hand, []map[int]bool cannot be unified with any of +

+ +
+int              // int is not a slice
+struct{}         // a struct is not a slice
+[]struct{}       // a struct is not a map
+[]map[T1]string  // map element types don't match
+
+ +

+As an exception to this general rule, because a defined type +D and a type literal L are never equivalent, +unification compares the underlying type of D with L instead. +For example, given the defined type +

+ +
+type Vector []float64
+
+ +

+and the type literal []E, unification compares []float64 with +[]E and adds an entry Efloat64 to +the substitution map. +

+ +

Function argument type inference

+ + + +

+Function argument type inference infers type arguments from function arguments: +if a function parameter is declared with a type T that uses +type parameters, +unifying the type of the corresponding +function argument with T may infer type arguments for the type +parameters used by T. +

+ +

+For instance, given the generic function +

+ +
+func scale[Number ~int64|~float64|~complex128](v []Number, s Number) []Number
+
+ +

+and the call +

+ +
+var vector []float64
+scaledVector := scale(vector, 42)
+
+ +

+the type argument for Number can be inferred from the function argument +vector by unifying the type of vector with the corresponding +parameter type: []float64 and []Number +match in structure and float64 matches with Number. +This adds the entry Numberfloat64 to the +substitution map. +Untyped arguments, such as the second function argument 42 here, are ignored +in the first round of function argument type inference and only considered if there are +unresolved type parameters left. +

+ +

+Inference happens in two separate phases; each phase operates on a specific list of +(parameter, argument) pairs: +

+ +
    +
  1. + The list Lt contains all (parameter, argument) pairs where the parameter + type uses type parameters and where the function argument is typed. +
  2. +
  3. + The list Lu contains all remaining pairs where the parameter type is a single + type parameter. In this list, the respective function arguments are untyped. +
  4. +
+ +

+Any other (parameter, argument) pair is ignored. +

+ +

+By construction, the arguments of the pairs in Lu are untyped constants +(or the untyped boolean result of a comparison). And because default types +of untyped values are always predeclared non-composite types, they can never match against +a composite type, so it is sufficient to only consider parameter types that are single type +parameters. +

+ +

+Each list is processed in a separate phase: +

+ +
    +
  1. + In the first phase, the parameter and argument types of each pair in Lt + are unified. If unification succeeds for a pair, it may yield new entries that + are added to the substitution map M. If unification fails, type inference + fails. +
  2. +
  3. + The second phase considers the entries of list Lu. Type parameters for + which the type argument has already been determined are ignored in this phase. + For each remaining pair, the parameter type (which is a single type parameter) and + the default type of the corresponding untyped argument is + unified. If unification fails, type inference fails. +
  4. +
+ +

+While unification is successful, processing of each list continues until all list elements +are considered, even if all type arguments are inferred before the last list element has +been processed. +

+ +

+Example: +

+ +
+func min[T ~int|~float64](x, y T) T
+
+var x int
+min(x, 2.0)    // T is int, inferred from typed argument x; 2.0 is assignable to int
+min(1.0, 2.0)  // T is float64, inferred from default type for 1.0 and matches default type for 2.0
+min(1.0, 2)    // illegal: default type float64 (for 1.0) doesn't match default type int (for 2)
+
+ +

+In the example min(1.0, 2), processing the function argument 1.0 +yields the substitution map entry Tfloat64. Because +processing continues until all untyped arguments are considered, an error is reported. This +ensures that type inference does not depend on the order of the untyped arguments. +

+ +

Constraint type inference

+ +

+Constraint type inference infers type arguments by considering type constraints. +If a type parameter P has a constraint with a +core type C, +unifying P with C +may infer additional type arguments, either the type argument for P, +or if that is already known, possibly the type arguments for type parameters +used in C. +

+ +

+For instance, consider the type parameter list with type parameters List and +Elem: +

+ +
+[List ~[]Elem, Elem any]
+
+ +

+Constraint type inference can deduce the type of Elem from the type argument +for List because Elem is a type parameter in the core type +[]Elem of List. +If the type argument is Bytes: +

+ +
+type Bytes []byte
+
+ +

+unifying the underlying type of Bytes with the core type means +unifying []byte with []Elem. That unification succeeds and yields +the substitution map entry +Elembyte. +Thus, in this example, constraint type inference can infer the second type argument from the +first one. +

+ +

+Using the core type of a constraint may lose some information: In the (unlikely) case that +the constraint's type set contains a single defined type +N, the corresponding core type is N's underlying type rather than +N itself. In this case, constraint type inference may succeed but instantiation +will fail because the inferred type is not in the type set of the constraint. +Thus, constraint type inference uses the adjusted core type of +a constraint: if the type set contains a single type, use that type; otherwise use the +constraint's core type. +

+ +

+Generally, constraint type inference proceeds in two phases: Starting with a given +substitution map M +

+ +
    +
  1. +For all type parameters with an adjusted core type, unify the type parameter with that +type. If any unification fails, constraint type inference fails. +
  2. + +
  3. +At this point, some entries in M may map type parameters to other +type parameters or to types containing type parameters. For each entry +PA in M where A is or +contains type parameters Q for which there exist entries +QB in M, substitute those +Q with the respective B in A. +Stop when no further substitution is possible. +
  4. +
+ +

+The result of constraint type inference is the final substitution map M from type +parameters P to type arguments A where no type parameter P +appears in any of the A. +

+ +

+For instance, given the type parameter list +

+ +
+[A any, B []C, C *A]
+
+ +

+and the single provided type argument int for type parameter A, +the initial substitution map M contains the entry Aint. +

+ +

+In the first phase, the type parameters B and C are unified +with the core type of their respective constraints. This adds the entries +B[]C and C*A +to M. + +

+At this point there are two entries in M where the right-hand side +is or contains type parameters for which there exists other entries in M: +[]C and *A. +In the second phase, these type parameters are replaced with their respective +types. It doesn't matter in which order this happens. Starting with the state +of M after the first phase: +

+ +

+Aint, +B[]C, +C*A +

+ +

+Replace A on the right-hand side of → with int: +

+ +

+Aint, +B[]C, +C*int +

+ +

+Replace C on the right-hand side of → with *int: +

+ +

+Aint, +B[]*int, +C*int +

+ +

+At this point no further substitution is possible and the map is full. +Therefore, M represents the final map of type parameters +to type arguments for the given type parameter list. +

+ +

Operators

+ +

+Operators combine operands into expressions. +

+ +
+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   = "+" | "-" | "!" | "^" | "*" | "&" | "<-" .
+
+ +

+Comparisons are discussed elsewhere. +For other binary operators, the operand types must be identical +unless the operation involves shifts or untyped constants. +For operations involving constants only, see the section on +constant expressions. +

+ +

+Except for shift operations, if one operand is an untyped constant +and the other operand is not, the constant is implicitly converted +to the type of the other operand. +

+ +

+The right operand in a shift expression must have integer type +or be an untyped constant representable by a +value of type uint. +If the left operand of a non-constant shift expression is an untyped constant, +it is first implicitly converted to the type it would assume if the shift expression were +replaced by its left operand alone. +

+ +
+var a [1024]byte
+var s uint = 33
+
+// The results of the following examples are given for 64-bit ints.
+var i = 1<<s                   // 1 has type int
+var j int32 = 1<<s             // 1 has type int32; j == 0
+var k = uint64(1<<s)           // 1 has type uint64; k == 1<<33
+var m int = 1.0<<s             // 1.0 has type int; m == 1<<33
+var n = 1.0<<s == j            // 1.0 has type int32; n == true
+var o = 1<<s == 2<<s           // 1 and 2 have type int; o == false
+var p = 1<<s == 1<<33          // 1 has type int; p == true
+var u = 1.0<<s                 // illegal: 1.0 has type float64, cannot shift
+var u1 = 1.0<<s != 0           // illegal: 1.0 has type float64, cannot shift
+var u2 = 1<<s != 1.0           // illegal: 1 has type float64, cannot shift
+var v1 float32 = 1<<s          // illegal: 1 has type float32, cannot shift
+var v2 = string(1<<s)          // illegal: 1 is converted to a string, cannot shift
+var w int64 = 1.0<<33          // 1.0<<33 is a constant shift expression; w == 1<<33
+var x = a[1.0<<s]              // panics: 1.0 has type int, but 1<<33 overflows array bounds
+var b = make([]byte, 1.0<<s)   // 1.0 has type int; len(b) == 1<<33
+
+// The results of the following examples are given for 32-bit ints,
+// which means the shifts will overflow.
+var mm int = 1.0<<s            // 1.0 has type int; mm == 0
+var oo = 1<<s == 2<<s          // 1 and 2 have type int; oo == true
+var pp = 1<<s == 1<<33         // illegal: 1 has type int, but 1<<33 overflows int
+var xx = a[1.0<<s]             // 1.0 has type int; xx == a[0]
+var bb = make([]byte, 1.0<<s)  // 1.0 has type int; len(bb) == 0
+
+ +

Operator precedence

+

+Unary operators have the highest precedence. +As the ++ and -- operators form +statements, not expressions, they fall +outside the operator hierarchy. +As a consequence, statement *p++ is the same as (*p)++. +

+There are five precedence levels for binary operators. +Multiplication operators bind strongest, followed by addition +operators, comparison operators, && (logical AND), +and finally || (logical OR): +

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

+Binary operators of the same precedence associate from left to right. +For instance, x / y * z is the same as (x / y) * z. +

+ +
++x
+23 + 3*x[i]
+x <= f()
+^a >> b
+f() || g()
+x == y+1 && <-chanInt > 0
+
+ + +

Arithmetic operators

+

+Arithmetic operators apply to numeric values and yield a result of the same +type as the first operand. The four standard arithmetic operators (+, +-, *, /) apply to +integer, floating-point, and +complex types; + also applies to strings. +The bitwise logical and shift operators apply to integers only. +

+ +
++    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 << integer >= 0
+>>   right shift            integer >> integer >= 0
+
+ +

+If the operand type is a type parameter, +the operator must apply to each type in that type set. +The operands are represented as values of the type argument that the type parameter +is instantiated with, and the operation is computed +with the precision of that type argument. For example, given the function: +

+ +
+func dotProduct[F ~float32|~float64](v1, v2 []F) F {
+	var s F
+	for i, x := range v1 {
+		y := v2[i]
+		s += x * y
+	}
+	return s
+}
+
+ +

+the product x * y and the addition s += x * y +are computed with float32 or float64 precision, +respectively, depending on the type argument for F. +

+ +

Integer operators

+ +

+For two integer values x and y, the integer quotient +q = x / y and remainder r = x % y satisfy the following +relationships: +

+ +
+x = q*y + r  and  |r| < |y|
+
+ +

+with x / y truncated towards zero +("truncated division"). +

+ +
+ x     y     x / y     x % y
+ 5     3       1         2
+-5     3      -1        -2
+ 5    -3      -1         2
+-5    -3       1        -2
+
+ +

+The one exception to this rule is that if the dividend x is +the most negative value for the int type of x, the quotient +q = x / -1 is equal to x (and r = 0) +due to two's-complement integer overflow: +

+ +
+                         x, q
+int8                     -128
+int16                  -32768
+int32             -2147483648
+int64    -9223372036854775808
+
+ +

+If the divisor is a constant, it must not be zero. +If the divisor is zero at run time, a run-time panic occurs. +If the dividend is non-negative and the divisor is a constant power of 2, +the division may be replaced by a right shift, and computing the remainder may +be replaced by a bitwise AND operation: +

+ +
+ x     x / 4     x % 4     x >> 2     x & 3
+ 11      2         3         2          3
+-11     -2        -3        -3          1
+
+ +

+The shift operators shift the left operand by the shift count specified by the +right operand, which must be non-negative. If the shift count is negative at run time, +a run-time panic occurs. +The shift operators implement arithmetic shifts if the left operand is a signed +integer and logical shifts if it is an unsigned integer. +There is no upper limit on the shift count. Shifts behave +as if the left operand is shifted n times by 1 for a shift +count of n. +As a result, x << 1 is the same as x*2 +and x >> 1 is the same as +x/2 but truncated towards negative infinity. +

+ +

+For integer operands, the unary operators ++, -, and ^ are defined as +follows: +

+ +
++x                          is 0 + x
+-x    negation              is 0 - x
+^x    bitwise complement    is m ^ x  with m = "all bits set to 1" for unsigned x
+                                      and  m = -1 for signed x
+
+ + +

Integer overflow

+ +

+For unsigned integer values, the operations +, +-, *, and << are +computed modulo 2n, where n is the bit width of +the unsigned integer's type. +Loosely speaking, these unsigned integer operations +discard high bits upon overflow, and programs may rely on "wrap around". +

+ +

+For signed integers, the operations +, +-, *, /, and << may legally +overflow and the resulting value exists and is deterministically defined +by the signed integer representation, the operation, and its operands. +Overflow does not cause a run-time panic. +A compiler may not optimize code under the assumption that overflow does +not occur. For instance, it may not assume that x < x + 1 is always true. +

+ +

Floating-point operators

+ +

+For floating-point and complex numbers, ++x is the same as x, +while -x is the negation of x. +The result of a floating-point or complex division by zero is not specified beyond the +IEEE-754 standard; whether a run-time panic +occurs is implementation-specific. +

+ +

+An implementation may combine multiple floating-point operations into a single +fused operation, possibly across statements, and produce a result that differs +from the value obtained by executing and rounding the instructions individually. +An explicit floating-point type conversion rounds to +the precision of the target type, preventing fusion that would discard that rounding. +

+ +

+For instance, some architectures provide a "fused multiply and add" (FMA) instruction +that computes x*y + z without rounding the intermediate result x*y. +These examples show when a Go implementation can use that instruction: +

+ +
+// FMA allowed for computing r, because x*y is not explicitly rounded:
+r  = x*y + z
+r  = z;   r += x*y
+t  = x*y; r = t + z
+*p = x*y; r = *p + z
+r  = x*y + float64(z)
+
+// FMA disallowed for computing r, because it would omit rounding of x*y:
+r  = float64(x*y) + z
+r  = z; r += float64(x*y)
+t  = float64(x*y); r = t + z
+
+ +

String concatenation

+ +

+Strings can be concatenated using the + operator +or the += assignment operator: +

+ +
+s := "hi" + string(c)
+s += " and good bye"
+
+ +

+String addition creates a new string by concatenating the operands. +

+ +

Comparison operators

+ +

+Comparison operators compare two operands and yield an untyped boolean value. +

+ +
+==    equal
+!=    not equal
+<     less
+<=    less or equal
+>     greater
+>=    greater or equal
+
+ +

+In any comparison, the first operand +must be assignable +to the type of the second operand, or vice versa. +

+

+The equality operators == and != apply +to operands of comparable types. +The ordering operators <, <=, >, and >= +apply to operands of ordered types. +These terms and the result of the comparisons are defined as follows: +

+ + + +

+A comparison of two interface values with identical dynamic types +causes a run-time panic if that type +is not comparable. This behavior applies not only to direct interface +value comparisons but also when comparing arrays of interface values +or structs with interface-valued fields. +

+ +

+Slice, map, and function types are not comparable. +However, as a special case, a slice, map, or function value may +be compared to the predeclared identifier nil. +Comparison of pointer, channel, and interface values to nil +is also allowed and follows from the general rules above. +

+ +
+const c = 3 < 4            // c is the untyped boolean constant true
+
+type MyBool bool
+var x, y int
+var (
+	// The result of a comparison is an untyped boolean.
+	// The usual assignment rules apply.
+	b3        = x == y // b3 has type bool
+	b4 bool   = x == y // b4 has type bool
+	b5 MyBool = x == y // b5 has type MyBool
+)
+
+ +

+A type is strictly comparable if it is comparable and not an interface +type nor composed of interface types. +Specifically: +

+ + + +

Logical operators

+ +

+Logical operators apply to boolean values +and yield a result of the same type as the operands. +The right operand is evaluated conditionally. +

+ +
+&&    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

+ +

+For an operand x of type T, the address operation +&x generates a pointer of type *T to x. +The operand must be addressable, +that is, either a variable, pointer indirection, or slice indexing +operation; or a field selector of an addressable struct operand; +or an array indexing operation of an addressable array. +As an exception to the addressability requirement, x may also be a +(possibly parenthesized) +composite literal. +If the evaluation of x would cause a run-time panic, +then the evaluation of &x does too. +

+ +

+For an operand x of pointer type *T, the pointer +indirection *x denotes the variable of type T pointed +to by x. +If x is nil, an attempt to evaluate *x +will cause a run-time panic. +

+ +
+&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

+ +

+For an operand ch whose core type is a +channel, +the value of the receive operation <-ch is the value received +from the channel ch. The channel direction must permit receive operations, +and the type of the receive operation is the element type of the channel. +The expression blocks until a value is available. +Receiving from a nil channel blocks forever. +A receive operation on a closed channel can always proceed +immediately, yielding the element type's zero value +after any previously sent values have been received. +

+ +
+v1 := <-ch
+v2 = <-ch
+f(<-ch)
+<-strobe  // wait until clock pulse and discard received value
+
+ +

+A receive expression used in an assignment statement or initialization of the special form +

+ +
+x, ok = <-ch
+x, ok := <-ch
+var x, ok = <-ch
+var x, ok T = <-ch
+
+ +

+yields an additional untyped boolean result reporting whether the +communication succeeded. The value of ok is true +if the value received was delivered by a successful send operation to the +channel, or false if it is a zero value generated because the +channel is closed and empty. +

+ + +

Conversions

+ +

+A conversion changes the type of an expression +to the type specified by the conversion. +A conversion may appear literally in the source, or it may be implied +by the context in which an expression appears. +

+ +

+An explicit conversion is an expression of the form T(x) +where T is a type and x is an expression +that can be converted to type T. +

+ +
+Conversion = Type "(" Expression [ "," ] ")" .
+
+ +

+If the type starts with the operator * or <-, +or if the type starts with the keyword func +and has no result list, it must be parenthesized when +necessary to avoid ambiguity: +

+ +
+*Point(p)        // same as *(Point(p))
+(*Point)(p)      // p is converted to *Point
+<-chan int(c)    // same as <-(chan int(c))
+(<-chan int)(c)  // c is converted to <-chan int
+func()(x)        // function signature func() x
+(func())(x)      // x is converted to func()
+(func() int)(x)  // x is converted to func() int
+func() int(x)    // x is converted to func() int (unambiguous)
+
+ +

+A constant value x can be converted to +type T if x is representable +by a value of T. +As a special case, an integer constant x can be explicitly converted to a +string type using the +same rule +as for non-constant x. +

+ +

+Converting a constant to a type that is not a type parameter +yields a typed constant. +

+ +
+uint(iota)               // iota value of type uint
+float32(2.718281828)     // 2.718281828 of type float32
+complex128(1)            // 1.0 + 0.0i of type complex128
+float32(0.49999999)      // 0.5 of type float32
+float64(-1e-1000)        // 0.0 of type float64
+string('x')              // "x" of type string
+string(0x266c)           // "♬" of type string
+myString("foo" + "bar")  // "foobar" of type myString
+string([]byte{'a'})      // not a constant: []byte{'a'} is not a constant
+(*int)(nil)              // not a constant: nil is not a constant, *int is not a boolean, numeric, or string type
+int(1.2)                 // illegal: 1.2 cannot be represented as an int
+string(65.0)             // illegal: 65.0 is not an integer constant
+
+ +

+Converting a constant to a type parameter yields a non-constant value of that type, +with the value represented as a value of the type argument that the type parameter +is instantiated with. +For example, given the function: +

+ +
+func f[P ~float32|~float64]() {
+	… P(1.1) …
+}
+
+ +

+the conversion P(1.1) results in a non-constant value of type P +and the value 1.1 is represented as a float32 or a float64 +depending on the type argument for f. +Accordingly, if f is instantiated with a float32 type, +the numeric value of the expression P(1.1) + 1.2 will be computed +with the same precision as the corresponding non-constant float32 +addition. +

+ +

+A non-constant value x can be converted to type T +in any of these cases: +

+ + + +

+Additionally, if T or x's type V are type +parameters, x +can also be converted to type T if one of the following conditions applies: +

+ + + +

+Struct tags are ignored when comparing struct types +for identity for the purpose of conversion: +

+ +
+type Person struct {
+	Name    string
+	Address *struct {
+		Street string
+		City   string
+	}
+}
+
+var data *struct {
+	Name    string `json:"name"`
+	Address *struct {
+		Street string `json:"street"`
+		City   string `json:"city"`
+	} `json:"address"`
+}
+
+var person = (*Person)(data)  // ignoring tags, the underlying types are identical
+
+ +

+Specific rules apply to (non-constant) conversions between numeric types or +to and from a string type. +These conversions may change the representation of x +and incur a run-time cost. +All other conversions only change the type but not the representation +of x. +

+ +

+There is no linguistic mechanism to convert between pointers and integers. +The package unsafe +implements this functionality under restricted circumstances. +

+ +

Conversions between numeric types

+ +

+For the conversion of non-constant numeric values, the following rules apply: +

+ +
    +
  1. +When converting between integer types, if the value is a signed integer, it is +sign extended to implicit infinite precision; otherwise it is zero extended. +It is then truncated to fit in the result type's size. +For example, if v := uint16(0x10F0), then uint32(int8(v)) == 0xFFFFFFF0. +The conversion always yields a valid value; there is no indication of overflow. +
  2. +
  3. +When converting a floating-point number to an integer, the fraction is discarded +(truncation towards zero). +
  4. +
  5. +When converting an integer or floating-point number to a floating-point type, +or a complex number to another complex type, the result value is rounded +to the precision specified by the destination type. +For instance, the value of a variable x of type float32 +may be stored using additional precision beyond that of an IEEE-754 32-bit number, +but float32(x) represents the result of rounding x's value to +32-bit precision. Similarly, x + 0.1 may use more than 32 bits +of precision, but float32(x + 0.1) does not. +
  6. +
+ +

+In all non-constant conversions involving floating-point or complex values, +if the result type cannot represent the value the conversion +succeeds but the result value is implementation-dependent. +

+ +

Conversions to and from a string type

+ +
    +
  1. +Converting a signed or unsigned integer value to a string type yields a +string containing the UTF-8 representation of the integer. Values outside +the range of valid Unicode code points are converted to "\uFFFD". + +
    +string('a')       // "a"
    +string(-1)        // "\ufffd" == "\xef\xbf\xbd"
    +string(0xf8)      // "\u00f8" == "ø" == "\xc3\xb8"
    +
    +type myString string
    +myString(0x65e5)  // "\u65e5" == "日" == "\xe6\x97\xa5"
    +
    +
  2. + +
  3. +Converting a slice of bytes to a string type yields +a string whose successive bytes are the elements of the slice. + +
    +string([]byte{'h', 'e', 'l', 'l', '\xc3', '\xb8'})   // "hellø"
    +string([]byte{})                                     // ""
    +string([]byte(nil))                                  // ""
    +
    +type bytes []byte
    +string(bytes{'h', 'e', 'l', 'l', '\xc3', '\xb8'})    // "hellø"
    +
    +type myByte byte
    +string([]myByte{'w', 'o', 'r', 'l', 'd', '!'})       // "world!"
    +myString([]myByte{'\xf0', '\x9f', '\x8c', '\x8d'})   // "🌍"
    +
    +
  4. + +
  5. +Converting a slice of runes to a string type yields +a string that is the concatenation of the individual rune values +converted to strings. + +
    +string([]rune{0x767d, 0x9d6c, 0x7fd4})   // "\u767d\u9d6c\u7fd4" == "白鵬翔"
    +string([]rune{})                         // ""
    +string([]rune(nil))                      // ""
    +
    +type runes []rune
    +string(runes{0x767d, 0x9d6c, 0x7fd4})    // "\u767d\u9d6c\u7fd4" == "白鵬翔"
    +
    +type myRune rune
    +string([]myRune{0x266b, 0x266c})         // "\u266b\u266c" == "♫♬"
    +myString([]myRune{0x1f30e})              // "\U0001f30e" == "🌎"
    +
    +
  6. + +
  7. +Converting a value of a string type to a slice of bytes type +yields a slice whose successive elements are the bytes of the string. + +
    +[]byte("hellø")             // []byte{'h', 'e', 'l', 'l', '\xc3', '\xb8'}
    +[]byte("")                  // []byte{}
    +
    +bytes("hellø")              // []byte{'h', 'e', 'l', 'l', '\xc3', '\xb8'}
    +
    +[]myByte("world!")          // []myByte{'w', 'o', 'r', 'l', 'd', '!'}
    +[]myByte(myString("🌏"))    // []myByte{'\xf0', '\x9f', '\x8c', '\x8f'}
    +
    +
  8. + +
  9. +Converting a value of a string type to a slice of runes type +yields a slice containing the individual Unicode code points of the string. + +
    +[]rune(myString("白鵬翔"))   // []rune{0x767d, 0x9d6c, 0x7fd4}
    +[]rune("")                  // []rune{}
    +
    +runes("白鵬翔")              // []rune{0x767d, 0x9d6c, 0x7fd4}
    +
    +[]myRune("♫♬")              // []myRune{0x266b, 0x266c}
    +[]myRune(myString("🌐"))    // []myRune{0x1f310}
    +
    +
  10. +
+ +

Conversions from slice to array or array pointer

+ +

+Converting a slice to an array yields an array containing the elements of the underlying array of the slice. +Similarly, converting a slice to an array pointer yields a pointer to the underlying array of the slice. +In both cases, if the length of the slice is less than the length of the array, +a run-time panic occurs. +

+ +
+s := make([]byte, 2, 4)
+
+a0 := [0]byte(s)
+a1 := [1]byte(s[1:])     // a1[0] == s[1]
+a2 := [2]byte(s)         // a2[0] == s[0]
+a4 := [4]byte(s)         // panics: len([4]byte) > len(s)
+
+s0 := (*[0]byte)(s)      // s0 != nil
+s1 := (*[1]byte)(s[1:])  // &s1[0] == &s[1]
+s2 := (*[2]byte)(s)      // &s2[0] == &s[0]
+s4 := (*[4]byte)(s)      // panics: len([4]byte) > len(s)
+
+var t []string
+t0 := [0]string(t)       // ok for nil slice t
+t1 := (*[0]string)(t)    // t1 == nil
+t2 := (*[1]string)(t)    // panics: len([1]string) > len(t)
+
+u := make([]byte, 0)
+u0 := (*[0]byte)(u)      // u0 != nil
+
+ +

Constant expressions

+ +

+Constant expressions may contain only constant +operands and are evaluated at compile time. +

+ +

+Untyped boolean, numeric, and string constants may be used as operands +wherever it is legal to use an operand of boolean, numeric, or string type, +respectively. +

+ +

+A constant comparison always yields +an untyped boolean constant. If the left operand of a constant +shift expression is an untyped constant, the +result is an integer constant; otherwise it is a constant of the same +type as the left operand, which must be of +integer type. +

+ +

+Any other operation on untyped constants results in an untyped constant of the +same kind; that is, a boolean, integer, floating-point, complex, or string +constant. +If the untyped operands of a binary operation (other than a shift) are of +different kinds, the result is of the operand's kind that appears later in this +list: integer, rune, floating-point, complex. +For example, an untyped integer constant divided by an +untyped complex constant yields an untyped complex constant. +

+ +
+const a = 2 + 3.0          // a == 5.0   (untyped floating-point constant)
+const b = 15 / 4           // b == 3     (untyped integer constant)
+const c = 15 / 4.0         // c == 3.75  (untyped floating-point constant)
+const Θ float64 = 3/2      // Θ == 1.0   (type float64, 3/2 is integer division)
+const Π float64 = 3/2.     // Π == 1.5   (type float64, 3/2. is float division)
+const d = 1 << 3.0         // d == 8     (untyped integer constant)
+const e = 1.0 << 3         // e == 8     (untyped integer constant)
+const f = int32(1) << 33   // illegal    (constant 8589934592 overflows int32)
+const g = float64(2) >> 1  // illegal    (float64(2) is a typed floating-point constant)
+const h = "foo" > "bar"    // h == true  (untyped boolean constant)
+const j = true             // j == true  (untyped boolean constant)
+const k = 'w' + 1          // k == 'x'   (untyped rune constant)
+const l = "hi"             // l == "hi"  (untyped string constant)
+const m = string(k)        // m == "x"   (type string)
+const Σ = 1 - 0.707i       //            (untyped complex constant)
+const Δ = Σ + 2.0e-4       //            (untyped complex constant)
+const Φ = iota*1i - 1/1i   //            (untyped complex constant)
+
+ +

+Applying the built-in function complex to untyped +integer, rune, or floating-point constants yields +an untyped complex constant. +

+ +
+const ic = complex(0, c)   // ic == 3.75i  (untyped complex constant)
+const iΘ = complex(0, Θ)   // iΘ == 1i     (type complex128)
+
+ +

+Constant expressions are always evaluated exactly; intermediate values and the +constants themselves may require precision significantly larger than supported +by any predeclared type in the language. The following are legal declarations: +

+ +
+const Huge = 1 << 100         // Huge == 1267650600228229401496703205376  (untyped integer constant)
+const Four int8 = Huge >> 98  // Four == 4                                (type int8)
+
+ +

+The divisor of a constant division or remainder operation must not be zero: +

+ +
+3.14 / 0.0   // illegal: division by zero
+
+ +

+The values of typed constants must always be accurately +representable by values +of the constant type. The following constant expressions are illegal: +

+ +
+uint(-1)     // -1 cannot be represented as a uint
+int(3.14)    // 3.14 cannot be represented as an int
+int64(Huge)  // 1267650600228229401496703205376 cannot be represented as an int64
+Four * 300   // operand 300 cannot be represented as an int8 (type of Four)
+Four * 100   // product 400 cannot be represented as an int8 (type of Four)
+
+ +

+The mask used by the unary bitwise complement operator ^ matches +the rule for non-constants: the mask is all 1s for unsigned constants +and -1 for signed and untyped constants. +

+ +
+^1         // untyped integer constant, equal to -2
+uint8(^1)  // illegal: same as uint8(-2), -2 cannot be represented as a uint8
+^uint8(1)  // typed uint8 constant, same as 0xFF ^ uint8(1) = uint8(0xFE)
+int8(^1)   // same as int8(-2)
+^int8(1)   // same as -1 ^ int8(1) = -2
+
+ +

+Implementation restriction: A compiler may use rounding while +computing untyped floating-point or complex constant expressions; see +the implementation restriction in the section +on constants. This rounding may cause a +floating-point constant expression to be invalid in an integer +context, even if it would be integral when calculated using infinite +precision, and vice versa. +

+ + +

Order of evaluation

+ +

+At package level, initialization dependencies +determine the evaluation order of individual initialization expressions in +variable declarations. +Otherwise, when evaluating the operands of an +expression, assignment, or +return statement, +all function calls, method calls, and +communication operations are evaluated in lexical left-to-right +order. +

+ +

+For example, in the (function-local) assignment +

+
+y[f()], ok = g(h(), i()+x[j()], <-c), k()
+
+

+the function calls and communication happen in the order +f(), h(), i(), j(), +<-c, g(), and k(). +However, the order of those events compared to the evaluation +and indexing of x and the evaluation +of y is not specified. +

+ +
+a := 1
+f := func() int { a++; return a }
+x := []int{a, f()}            // x may be [1, 2] or [2, 2]: evaluation order between a and f() is not specified
+m := map[int]int{a: 1, a: 2}  // m may be {2: 1} or {2: 2}: evaluation order between the two map assignments is not specified
+n := map[int]int{a: f()}      // n may be {2: 3} or {3: 3}: evaluation order between the key and the value is not specified
+
+ +

+At package level, initialization dependencies override the left-to-right rule +for individual initialization expressions, but not for operands within each +expression: +

+ +
+var a, b, c = f() + v(), g(), sqr(u()) + v()
+
+func f() int        { return c }
+func g() int        { return a }
+func sqr(x int) int { return x*x }
+
+// functions u and v are independent of all other variables and functions
+
+ +

+The function calls happen in the order +u(), sqr(), v(), +f(), v(), and g(). +

+ +

+Floating-point operations within a single expression are evaluated according to +the associativity of the operators. Explicit parentheses affect the evaluation +by overriding the default associativity. +In the expression x + (y + z) the addition y + z +is performed before adding x. +

+ +

Statements

+ +

+Statements control execution. +

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

Terminating statements

+ +

+A terminating statement interrupts the regular flow of control in +a block. The following statements are terminating: +

+ +
    +
  1. + A "return" or + "goto" statement. + +
    +
  2. + +
  3. + A call to the built-in function + panic. + +
    +
  4. + +
  5. + A block in which the statement list ends in a terminating statement. + +
    +
  6. + +
  7. + An "if" statement in which: +
      +
    • the "else" branch is present, and
    • +
    • both branches are terminating statements.
    • +
    +
  8. + +
  9. + A "for" statement in which: +
      +
    • there are no "break" statements referring to the "for" statement, and
    • +
    • the loop condition is absent, and
    • +
    • the "for" statement does not use a range clause.
    • +
    +
  10. + +
  11. + A "switch" statement in which: +
      +
    • there are no "break" statements referring to the "switch" statement,
    • +
    • there is a default case, and
    • +
    • the statement lists in each case, including the default, end in a terminating + statement, or a possibly labeled "fallthrough" + statement.
    • +
    +
  12. + +
  13. + A "select" statement in which: +
      +
    • there are no "break" statements referring to the "select" statement, and
    • +
    • the statement lists in each case, including the default if present, + end in a terminating statement.
    • +
    +
  14. + +
  15. + A labeled statement labeling + a terminating statement. +
  16. +
+ +

+All other statements are not terminating. +

+ +

+A statement list ends in a terminating statement if the list +is not empty and its final non-empty statement is terminating. +

+ + +

Empty statements

+ +

+The empty statement does nothing. +

+ +
+EmptyStmt = .
+
+ + +

Labeled statements

+ +

+A labeled statement may be the target of a goto, +break or continue statement. +

+ +
+LabeledStmt = Label ":" Statement .
+Label       = identifier .
+
+ +
+Error: log.Panic("error encountered")
+
+ + +

Expression statements

+ +

+With the exception of specific built-in functions, +function and method calls and +receive operations +can appear in statement context. Such statements may be parenthesized. +

+ +
+ExpressionStmt = Expression .
+
+ +

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

+ +
+append cap complex imag len make new real
+unsafe.Add unsafe.Alignof unsafe.Offsetof unsafe.Sizeof unsafe.Slice
+
+ +
+h(x+y)
+f.Close()
+<-ch
+(<-ch)
+len("foo")  // illegal if len is the built-in function
+
+ + +

Send statements

+ +

+A send statement sends a value on a channel. +The channel expression's core type +must be a channel, +the channel direction must permit send operations, +and the type of the value to be sent must be assignable +to the channel's element type. +

+ +
+SendStmt = Channel "<-" Expression .
+Channel  = Expression .
+
+ +

+Both the channel and the value expression are evaluated before communication +begins. Communication blocks until the send can proceed. +A send on an unbuffered channel can proceed if a receiver is ready. +A send on a buffered channel can proceed if there is room in the buffer. +A send on a closed channel proceeds by causing a run-time panic. +A send on a nil channel blocks forever. +

+ +
+ch <- 3  // send value 3 to channel ch
+
+ + +

IncDec statements

+ +

+The "++" and "--" statements increment or decrement their operands +by the untyped constant 1. +As with an assignment, the operand must be addressable +or a map index expression. +

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

+The following assignment statements are semantically +equivalent: +

+ +
+IncDec statement    Assignment
+x++                 x += 1
+x--                 x -= 1
+
+ + +

Assignment statements

+ +

+An assignment replaces the current value stored in a variable +with a new value specified by an expression. +An assignment statement may assign a single value to a single variable, or multiple values to a +matching number of variables. +

+ +
+Assignment = ExpressionList assign_op ExpressionList .
+
+assign_op = [ add_op | mul_op ] "=" .
+
+ +

+Each left-hand side operand must be addressable, +a map index expression, or (for = assignments only) the +blank identifier. +Operands may be parenthesized. +

+ +
+x = 1
+*p = f()
+a[i] = 23
+(k) = <-ch  // same as: k = <-ch
+
+ +

+An assignment operation x op= +y where op is a binary arithmetic operator +is equivalent to x = x op +(y) but evaluates x +only once. The op= construct is a single token. +In assignment operations, both the left- and right-hand expression lists +must contain exactly one single-valued expression, and the left-hand +expression must not be the blank identifier. +

+ +
+a[i] <<= 2
+i &^= 1<<n
+
+ +

+A tuple assignment assigns the individual elements of a multi-valued +operation to a list of variables. There are two forms. In the +first, the right hand operand is a single multi-valued expression +such as a function call, a channel or +map operation, or a type assertion. +The number of operands on the left +hand side must match the number of values. For instance, if +f is a function returning two values, +

+ +
+x, y = f()
+
+ +

+assigns the first value to x and the second to y. +In the second form, the number of operands on the left must equal the number +of expressions on the right, each of which must be single-valued, and the +nth expression on the right is assigned to the nth +operand on the left: +

+ +
+one, two, three = '一', '二', '三'
+
+ +

+The blank identifier provides a way to +ignore right-hand side values in an assignment: +

+ +
+_ = x       // evaluate x but ignore it
+x, _ = f()  // evaluate f() but ignore second result value
+
+ +

+The assignment proceeds in two phases. +First, the operands of index expressions +and pointer indirections +(including implicit pointer indirections in selectors) +on the left and the expressions on the right are all +evaluated in the usual order. +Second, the assignments are carried out in left-to-right order. +

+ +
+a, b = b, a  // exchange a and b
+
+x := []int{1, 2, 3}
+i := 0
+i, x[i] = 1, 2  // set i = 1, x[0] = 2
+
+i = 0
+x[i], i = 2, 1  // set x[0] = 2, i = 1
+
+x[0], x[0] = 1, 2  // set x[0] = 1, then x[0] = 2 (so x[0] == 2 at end)
+
+x[1], x[3] = 4, 5  // set x[1] = 4, then panic setting x[3] = 5.
+
+type Point struct { x, y int }
+var p *Point
+x[2], p.x = 6, 7  // set x[2] = 6, then panic setting p.x = 7
+
+i = 2
+x = []int{3, 5, 7}
+for i, x[i] = range x {  // set i, x[2] = 0, x[0]
+	break
+}
+// after this loop, i == 0 and x == []int{3, 5, 3}
+
+ +

+In assignments, each value must be assignable +to the type of the operand to which it is assigned, with the following special cases: +

+ +
    +
  1. + Any typed value may be assigned to the blank identifier. +
  2. + +
  3. + If an untyped constant + is assigned to a variable of interface type or the blank identifier, + the constant is first implicitly converted to its + default type. +
  4. + +
  5. + If an untyped boolean value is assigned to a variable of interface type or + the blank identifier, it is first implicitly converted to type bool. +
  6. +
+ +

If statements

+ +

+"If" statements specify the conditional execution of two branches +according to the value of a boolean expression. If the expression +evaluates to true, the "if" branch is executed, otherwise, if +present, the "else" branch is executed. +

+ +
+IfStmt = "if" [ SimpleStmt ";" ] Expression Block [ "else" ( IfStmt | Block ) ] .
+
+ +
+if x > max {
+	x = max
+}
+
+ +

+The expression may be preceded by a simple statement, which +executes before the expression is evaluated. +

+ +
+if x := f(); x < y {
+	return x
+} else if x > z {
+	return z
+} else {
+	return y
+}
+
+ + +

Switch statements

+ +

+"Switch" statements provide multi-way execution. +An expression or type is compared to the "cases" +inside the "switch" to determine which branch +to execute. +

+ +
+SwitchStmt = ExprSwitchStmt | TypeSwitchStmt .
+
+ +

+There are two forms: expression switches and type switches. +In an expression switch, the cases contain expressions that are compared +against the value of the switch expression. +In a type switch, the cases contain types that are compared against the +type of a specially annotated switch expression. +The switch expression is evaluated exactly once in a switch statement. +

+ +

Expression switches

+ +

+In an expression switch, +the switch expression is evaluated and +the case expressions, which need not be constants, +are evaluated left-to-right and top-to-bottom; the first one that equals the +switch expression +triggers execution of the statements of the associated case; +the other cases are skipped. +If no case matches and there is a "default" case, +its statements are executed. +There can be at most one default case and it may appear anywhere in the +"switch" statement. +A missing switch expression is equivalent to the boolean value +true. +

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

+If the switch expression evaluates to an untyped constant, it is first implicitly +converted to its default type. +The predeclared untyped value nil cannot be used as a switch expression. +The switch expression type must be comparable. +

+ +

+If a case expression is untyped, it is first implicitly converted +to the type of the switch expression. +For each (possibly converted) case expression x and the value t +of the switch expression, x == t must be a valid comparison. +

+ +

+In other words, the switch expression is treated as if it were used to declare and +initialize a temporary variable t without explicit type; it is that +value of t against which each case expression x is tested +for equality. +

+ +

+In a case or default clause, the last non-empty statement +may be a (possibly labeled) +"fallthrough" statement to +indicate that control should flow from the end of this clause to +the first statement of the next clause. +Otherwise control flows to the end of the "switch" statement. +A "fallthrough" statement may appear as the last statement of all +but the last clause of an expression switch. +

+ +

+The switch expression may be preceded by a simple statement, which +executes before the expression is evaluated. +

+ +
+switch tag {
+default: s3()
+case 0, 1, 2, 3: s1()
+case 4, 5, 6, 7: s2()
+}
+
+switch x := f(); {  // missing switch expression means "true"
+case x < 0: return -x
+default: return x
+}
+
+switch {
+case x < y: f1()
+case x < z: f2()
+case x == 4: f3()
+}
+
+ +

+Implementation restriction: A compiler may disallow multiple case +expressions evaluating to the same constant. +For instance, the current compilers disallow duplicate integer, +floating point, or string constants in case expressions. +

+ +

Type switches

+ +

+A type switch compares types rather than values. It is otherwise similar +to an expression switch. It is marked by a special switch expression that +has the form of a type assertion +using the keyword type rather than an actual type: +

+ +
+switch x.(type) {
+// cases
+}
+
+ +

+Cases then match actual types T against the dynamic type of the +expression x. As with type assertions, x must be of +interface type, but not a +type parameter, and each non-interface type +T listed in a case must implement the type of x. +The types listed in the cases of a type switch must all be +different. +

+ +
+TypeSwitchStmt  = "switch" [ SimpleStmt ";" ] TypeSwitchGuard "{" { TypeCaseClause } "}" .
+TypeSwitchGuard = [ identifier ":=" ] PrimaryExpr "." "(" "type" ")" .
+TypeCaseClause  = TypeSwitchCase ":" StatementList .
+TypeSwitchCase  = "case" TypeList | "default" .
+
+ +

+The TypeSwitchGuard may include a +short variable declaration. +When that form is used, the variable is declared at the end of the +TypeSwitchCase in the implicit block of each clause. +In clauses with a case listing exactly one type, the variable +has that type; otherwise, the variable has the type of the expression +in the TypeSwitchGuard. +

+ +

+Instead of a type, a case may use the predeclared identifier +nil; +that case is selected when the expression in the TypeSwitchGuard +is a nil interface value. +There may be at most one nil case. +

+ +

+Given an expression x of type interface{}, +the following type switch: +

+ +
+switch i := x.(type) {
+case nil:
+	printString("x is nil")                // type of i is type of x (interface{})
+case int:
+	printInt(i)                            // type of i is int
+case float64:
+	printFloat64(i)                        // type of i is float64
+case func(int) float64:
+	printFunction(i)                       // type of i is func(int) float64
+case bool, string:
+	printString("type is bool or string")  // type of i is type of x (interface{})
+default:
+	printString("don't know the type")     // type of i is type of x (interface{})
+}
+
+ +

+could be rewritten: +

+ +
+v := x  // x is evaluated exactly once
+if v == nil {
+	i := v                                 // type of i is type of x (interface{})
+	printString("x is nil")
+} else if i, isInt := v.(int); isInt {
+	printInt(i)                            // type of i is int
+} else if i, isFloat64 := v.(float64); isFloat64 {
+	printFloat64(i)                        // type of i is float64
+} else if i, isFunc := v.(func(int) float64); isFunc {
+	printFunction(i)                       // type of i is func(int) float64
+} else {
+	_, isBool := v.(bool)
+	_, isString := v.(string)
+	if isBool || isString {
+		i := v                         // type of i is type of x (interface{})
+		printString("type is bool or string")
+	} else {
+		i := v                         // type of i is type of x (interface{})
+		printString("don't know the type")
+	}
+}
+
+ +

+A type parameter or a generic type +may be used as a type in a case. If upon instantiation that type turns +out to duplicate another entry in the switch, the first matching case is chosen. +

+ +
+func f[P any](x any) int {
+	switch x.(type) {
+	case P:
+		return 0
+	case string:
+		return 1
+	case []P:
+		return 2
+	case []byte:
+		return 3
+	default:
+		return 4
+	}
+}
+
+var v1 = f[string]("foo")   // v1 == 0
+var v2 = f[byte]([]byte{})  // v2 == 2
+
+ +

+The type switch guard may be preceded by a simple statement, which +executes before the guard is evaluated. +

+ +

+The "fallthrough" statement is not permitted in a type switch. +

+ +

For statements

+ +

+A "for" statement specifies repeated execution of a block. There are three forms: +The iteration may be controlled by a single condition, a "for" clause, or a "range" clause. +

+ +
+ForStmt = "for" [ Condition | ForClause | RangeClause ] Block .
+Condition = Expression .
+
+ +

For statements with single condition

+ +

+In its simplest form, a "for" statement specifies the repeated execution of +a block as long as a boolean condition evaluates to true. +The condition is evaluated before each iteration. +If the condition is absent, it is equivalent to the boolean value +true. +

+ +
+for a < b {
+	a *= 2
+}
+
+ +

For statements with for clause

+ +

+A "for" statement with a ForClause is also controlled by its condition, but +additionally it may specify an init +and a post statement, such as an assignment, +an increment or decrement statement. The init statement may be a +short variable declaration, but the post statement must not. +Variables declared by the init statement are re-used in each iteration. +

+ +
+ForClause = [ InitStmt ] ";" [ Condition ] ";" [ PostStmt ] .
+InitStmt = SimpleStmt .
+PostStmt = SimpleStmt .
+
+ +
+for i := 0; i < 10; i++ {
+	f(i)
+}
+
+ +

+If non-empty, the init statement is executed once before evaluating the +condition for the first iteration; +the post statement is executed after each execution of the block (and +only if the block was executed). +Any element of the ForClause may be empty but the +semicolons are +required unless there is only a condition. +If the condition is absent, it is equivalent to the boolean value +true. +

+ +
+for cond { S() }    is the same as    for ; cond ; { S() }
+for      { S() }    is the same as    for true     { S() }
+
+ +

For statements with range clause

+ +

+A "for" statement with a "range" clause +iterates through all entries of an array, slice, string or map, +or values received on a channel. For each entry it assigns iteration values +to corresponding iteration variables if present and then executes the block. +

+ +
+RangeClause = [ ExpressionList "=" | IdentifierList ":=" ] "range" Expression .
+
+ +

+The expression on the right in the "range" clause is called the range expression, +its core type must be +an array, pointer to an array, slice, string, map, or channel permitting +receive operations. +As with an assignment, if present the operands on the left must be +addressable or map index expressions; they +denote the iteration variables. If the range expression is a channel, at most +one iteration variable is permitted, otherwise there may be up to two. +If the last iteration variable is the blank identifier, +the range clause is equivalent to the same clause without that identifier. +

+ +

+The range expression x is evaluated once before beginning the loop, +with one exception: if at most one iteration variable is present and +len(x) is constant, +the range expression is not evaluated. +

+ +

+Function calls on the left are evaluated once per iteration. +For each iteration, iteration values are produced as follows +if the respective iteration variables are present: +

+ +
+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
+
+ +
    +
  1. +For an array, pointer to array, or slice value a, the index iteration +values are produced in increasing order, starting at element index 0. +If at most one iteration variable is present, the range loop produces +iteration values from 0 up to len(a)-1 and does not index into the array +or slice itself. For a nil slice, the number of iterations is 0. +
  2. + +
  3. +For a string value, the "range" clause iterates over the Unicode code points +in the string starting at byte index 0. On successive iterations, the index value will be the +index of the first byte of successive UTF-8-encoded code points in the string, +and the second value, of type rune, will be the value of +the corresponding code point. If the iteration encounters an invalid +UTF-8 sequence, the second value will be 0xFFFD, +the Unicode replacement character, and the next iteration will advance +a single byte in the string. +
  4. + +
  5. +The iteration order over maps is not specified +and is not guaranteed to be the same from one iteration to the next. +If a map entry that has not yet been reached is removed during iteration, +the corresponding iteration value will not be produced. If a map entry is +created during iteration, that entry may be produced during the iteration or +may be skipped. The choice may vary for each entry created and from one +iteration to the next. +If the map is nil, the number of iterations is 0. +
  6. + +
  7. +For channels, the iteration values produced are the successive values sent on +the channel until the channel is closed. If the channel +is nil, the range expression blocks forever. +
  8. +
+ +

+The iteration values are assigned to the respective +iteration variables as in an assignment statement. +

+ +

+The iteration variables may be declared by the "range" clause using a form of +short variable declaration +(:=). +In this case their types are set to the types of the respective iteration values +and their scope is the block of the "for" +statement; they are re-used in each iteration. +If the iteration variables are declared outside the "for" statement, +after execution their values will be those of the last iteration. +

+ +
+var testdata *struct {
+	a *[7]int
+}
+for i, _ := range testdata.a {
+	// testdata.a is never evaluated; len(testdata.a) is constant
+	// i ranges from 0 to 6
+	f(i)
+}
+
+var a [10]string
+for i, s := range a {
+	// type of i is int
+	// type of s is string
+	// s == a[i]
+	g(i, s)
+}
+
+var key string
+var val interface{}  // element type of m is assignable to val
+m := map[string]int{"mon":0, "tue":1, "wed":2, "thu":3, "fri":4, "sat":5, "sun":6}
+for key, val = range m {
+	h(key, val)
+}
+// key == last map key encountered in iteration
+// val == map[key]
+
+var ch chan Work = producer()
+for w := range ch {
+	doWork(w)
+}
+
+// empty a channel
+for range ch {}
+
+ + +

Go statements

+ +

+A "go" statement starts the execution of a function call +as an independent concurrent thread of control, or goroutine, +within the same address space. +

+ +
+GoStmt = "go" Expression .
+
+ +

+The expression must be a function or method call; it cannot be parenthesized. +Calls of built-in functions are restricted as for +expression statements. +

+ +

+The function value and parameters are +evaluated as usual +in the calling goroutine, but +unlike with a regular call, program execution does not wait +for the invoked function to complete. +Instead, the function begins executing independently +in a new goroutine. +When the function terminates, its goroutine also terminates. +If the function has any return values, they are discarded when the +function completes. +

+ +
+go Server()
+go func(ch chan<- bool) { for { sleep(10); ch <- true }} (c)
+
+ + +

Select statements

+ +

+A "select" statement chooses which of a set of possible +send or +receive +operations will proceed. +It looks similar to a +"switch" statement but with the +cases all referring to communication operations. +

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

+A case with a RecvStmt may assign the result of a RecvExpr to one or +two variables, which may be declared using a +short variable declaration. +The RecvExpr must be a (possibly parenthesized) receive operation. +There can be at most one default case and it may appear anywhere +in the list of cases. +

+ +

+Execution of a "select" statement proceeds in several steps: +

+ +
    +
  1. +For all the cases in the statement, the channel operands of receive operations +and the channel and right-hand-side expressions of send statements are +evaluated exactly once, in source order, upon entering the "select" statement. +The result is a set of channels to receive from or send to, +and the corresponding values to send. +Any side effects in that evaluation will occur irrespective of which (if any) +communication operation is selected to proceed. +Expressions on the left-hand side of a RecvStmt with a short variable declaration +or assignment are not yet evaluated. +
  2. + +
  3. +If one or more of the communications can proceed, +a single one that can proceed is chosen via a uniform pseudo-random selection. +Otherwise, if there is a default case, that case is chosen. +If there is no default case, the "select" statement blocks until +at least one of the communications can proceed. +
  4. + +
  5. +Unless the selected case is the default case, the respective communication +operation is executed. +
  6. + +
  7. +If the selected case is a RecvStmt with a short variable declaration or +an assignment, the left-hand side expressions are evaluated and the +received value (or values) are assigned. +
  8. + +
  9. +The statement list of the selected case is executed. +
  10. +
+ +

+Since communication on nil channels can never proceed, +a select with only nil channels and no default case blocks forever. +

+ +
+var a []int
+var c, c1, c2, c3, c4 chan int
+var i1, i2 int
+select {
+case i1 = <-c1:
+	print("received ", i1, " from c1\n")
+case c2 <- i2:
+	print("sent ", i2, " to c2\n")
+case i3, ok := (<-c3):  // same as: i3, ok := <-c3
+	if ok {
+		print("received ", i3, " from c3\n")
+	} else {
+		print("c3 is closed\n")
+	}
+case a[f()] = <-c4:
+	// same as:
+	// case t := <-c4
+	//	a[f()] = t
+default:
+	print("no communication\n")
+}
+
+for {  // send random sequence of bits to c
+	select {
+	case c <- 0:  // note: no statement, no fallthrough, no folding of cases
+	case c <- 1:
+	}
+}
+
+select {}  // block forever
+
+ + +

Return statements

+ +

+A "return" statement in a function F terminates the execution +of F, and optionally provides one or more result values. +Any functions deferred by F +are executed before F returns to its caller. +

+ +
+ReturnStmt = "return" [ ExpressionList ] .
+
+ +

+In a function without a result type, a "return" statement must not +specify any result values. +

+
+func noResult() {
+	return
+}
+
+ +

+There are three ways to return values from a function with a result +type: +

+ +
    +
  1. The return value or values may be explicitly listed + in the "return" statement. Each expression must be single-valued + and assignable + to the corresponding element of the function's result type. +
    +func simpleF() int {
    +	return 2
    +}
    +
    +func complexF1() (re float64, im float64) {
    +	return -7.0, -4.0
    +}
    +
    +
  2. +
  3. The expression list in the "return" statement may be a single + call to a multi-valued function. The effect is as if each value + returned from that function were assigned to a temporary + variable with the type of the respective value, followed by a + "return" statement listing these variables, at which point the + rules of the previous case apply. +
    +func complexF2() (re float64, im float64) {
    +	return complexF1()
    +}
    +
    +
  4. +
  5. The expression list may be empty if the function's result + type specifies names for its result parameters. + The result parameters act as ordinary local variables + and the function may assign values to them as necessary. + The "return" statement returns the values of these variables. +
    +func complexF3() (re float64, im float64) {
    +	re = 7.0
    +	im = 4.0
    +	return
    +}
    +
    +func (devnull) Write(p []byte) (n int, _ error) {
    +	n = len(p)
    +	return
    +}
    +
    +
  6. +
+ +

+Regardless of how they are declared, all the result values are initialized to +the zero values for their type upon entry to the +function. A "return" statement that specifies results sets the result parameters before +any deferred functions are executed. +

+ +

+Implementation restriction: A compiler may disallow an empty expression list +in a "return" statement if a different entity (constant, type, or variable) +with the same name as a result parameter is in +scope at the place of the return. +

+ +
+func f(n int) (res int, err error) {
+	if _, err := f(n-1); err != nil {
+		return  // invalid return statement: err is shadowed
+	}
+	return
+}
+
+ +

Break statements

+ +

+A "break" statement terminates execution of the innermost +"for", +"switch", or +"select" statement +within the same function. +

+ +
+BreakStmt = "break" [ Label ] .
+
+ +

+If there is a label, it must be that of an enclosing +"for", "switch", or "select" statement, +and that is the one whose execution terminates. +

+ +
+OuterLoop:
+	for i = 0; i < n; i++ {
+		for j = 0; j < m; j++ {
+			switch a[i][j] {
+			case nil:
+				state = Error
+				break OuterLoop
+			case item:
+				state = Found
+				break OuterLoop
+			}
+		}
+	}
+
+ +

Continue statements

+ +

+A "continue" statement begins the next iteration of the +innermost enclosing "for" loop +by advancing control to the end of the loop block. +The "for" loop must be within the same function. +

+ +
+ContinueStmt = "continue" [ Label ] .
+
+ +

+If there is a label, it must be that of an enclosing +"for" statement, and that is the one whose execution +advances. +

+ +
+RowLoop:
+	for y, row := range rows {
+		for x, data := range row {
+			if data == endOfRow {
+				continue RowLoop
+			}
+			row[x] = data + bias(x, y)
+		}
+	}
+
+ +

Goto statements

+ +

+A "goto" statement transfers control to the statement with the corresponding label +within the same function. +

+ +
+GotoStmt = "goto" Label .
+
+ +
+goto Error
+
+ +

+Executing the "goto" statement must not cause any variables to come into +scope that were not already in scope at the point of the goto. +For instance, this example: +

+ +
+	goto L  // BAD
+	v := 3
+L:
+
+ +

+is erroneous because the jump to label L skips +the creation of v. +

+ +

+A "goto" statement outside a block cannot jump to a label inside that block. +For instance, this example: +

+ +
+if n%2 == 1 {
+	goto L1
+}
+for n > 0 {
+	f()
+	n--
+L1:
+	f()
+	n--
+}
+
+ +

+is erroneous because the label L1 is inside +the "for" statement's block but the goto is not. +

+ +

Fallthrough statements

+ +

+A "fallthrough" statement transfers control to the first statement of the +next case clause in an expression "switch" statement. +It may be used only as the final non-empty statement in such a clause. +

+ +
+FallthroughStmt = "fallthrough" .
+
+ + +

Defer statements

+ +

+A "defer" statement invokes a function whose execution is deferred +to the moment the surrounding function returns, either because the +surrounding function executed a return statement, +reached the end of its function body, +or because the corresponding goroutine is panicking. +

+ +
+DeferStmt = "defer" Expression .
+
+ +

+The expression must be a function or method call; it cannot be parenthesized. +Calls of built-in functions are restricted as for +expression statements. +

+ +

+Each time a "defer" statement +executes, the function value and parameters to the call are +evaluated as usual +and saved anew but the actual function is not invoked. +Instead, deferred functions are invoked immediately before +the surrounding function returns, in the reverse order +they were deferred. That is, if the surrounding function +returns through an explicit return statement, +deferred functions are executed after any result parameters are set +by that return statement but before the function returns to its caller. +If a deferred function value evaluates +to nil, execution panics +when the function is invoked, not when the "defer" statement is executed. +

+ +

+For instance, if the deferred function is +a function literal and the surrounding +function has named result parameters that +are in scope within the literal, the deferred function may access and modify +the result parameters before they are returned. +If the deferred function has any return values, they are discarded when +the function completes. +(See also the section on handling panics.) +

+ +
+lock(l)
+defer unlock(l)  // unlocking happens before surrounding function returns
+
+// prints 3 2 1 0 before surrounding function returns
+for i := 0; i <= 3; i++ {
+	defer fmt.Print(i)
+}
+
+// f returns 42
+func f() (result int) {
+	defer func() {
+		// result is accessed after it was set to 6 by the return statement
+		result *= 7
+	}()
+	return 6
+}
+
+ +

Built-in functions

+ +

+Built-in functions are +predeclared. +They are called like any other function but some of them +accept a type instead of an expression as the first argument. +

+ +

+The built-in functions do not have standard Go types, +so they can only appear in call expressions; +they cannot be used as function values. +

+ +

Close

+ +

+For an argument ch with a core type +that is a channel, the built-in function close +records that no more values will be sent on the channel. +It is an error if ch is a receive-only channel. +Sending to or closing a closed channel causes a run-time panic. +Closing the nil channel also causes a run-time panic. +After calling close, and after any previously +sent values have been received, receive operations will return +the zero value for the channel's type without blocking. +The multi-valued receive operation +returns a received value along with an indication of whether the channel is closed. +

+ +

Length and capacity

+ +

+The built-in functions len and cap take arguments +of various types and return a result of type int. +The implementation guarantees that the result always fits into an int. +

+ +
+Call      Argument type    Result
+
+len(s)    string type      string length in bytes
+          [n]T, *[n]T      array length (== n)
+          []T              slice length
+          map[K]T          map length (number of defined keys)
+          chan T           number of elements queued in channel buffer
+          type parameter   see below
+
+cap(s)    [n]T, *[n]T      array length (== n)
+          []T              slice capacity
+          chan T           channel buffer capacity
+          type parameter   see below
+
+ +

+If the argument type is a type parameter P, +the call len(e) (or cap(e) respectively) must be valid for +each type in P's type set. +The result is the length (or capacity, respectively) of the argument whose type +corresponds to the type argument with which P was +instantiated. +

+ +

+The capacity of a slice is the number of elements for which there is +space allocated in the underlying array. +At any time the following relationship holds: +

+ +
+0 <= len(s) <= cap(s)
+
+ +

+The length of a nil slice, map or channel is 0. +The capacity of a nil slice or channel is 0. +

+ +

+The expression len(s) is constant if +s is a string constant. The expressions len(s) and +cap(s) are constants if the type of s is an array +or pointer to an array and the expression s does not contain +channel receives or (non-constant) +function calls; in this case s is not evaluated. +Otherwise, invocations of len and cap are not +constant and s is evaluated. +

+ +
+const (
+	c1 = imag(2i)                    // imag(2i) = 2.0 is a constant
+	c2 = len([10]float64{2})         // [10]float64{2} contains no function calls
+	c3 = len([10]float64{c1})        // [10]float64{c1} contains no function calls
+	c4 = len([10]float64{imag(2i)})  // imag(2i) is a constant and no function call is issued
+	c5 = len([10]float64{imag(z)})   // invalid: imag(z) is a (non-constant) function call
+)
+var z complex128
+
+ +

Allocation

+ +

+The built-in function new takes a type T, +allocates storage for a variable of that type +at run time, and returns a value of type *T +pointing to it. +The variable is initialized as described in the section on +initial values. +

+ +
+new(T)
+
+ +

+For instance +

+ +
+type S struct { a int; b float64 }
+new(S)
+
+ +

+allocates storage for a variable of type S, +initializes it (a=0, b=0.0), +and returns a value of type *S containing the address +of the location. +

+ +

Making slices, maps and channels

+ +

+The built-in function make takes a type T, +optionally followed by a type-specific list of expressions. +The core type of T must +be a slice, map or channel. +It returns a value of type T (not *T). +The memory is initialized as described in the section on +initial values. +

+ +
+Call             Core type    Result
+
+make(T, n)       slice        slice of type T with length n and capacity n
+make(T, n, m)    slice        slice of type T with length n and capacity m
+
+make(T)          map          map of type T
+make(T, n)       map          map of type T with initial space for approximately n elements
+
+make(T)          channel      unbuffered channel of type T
+make(T, n)       channel      buffered channel of type T, buffer size n
+
+ + +

+Each of the size arguments n and m must be of integer type, +have a type set containing only integer types, +or be an untyped constant. +A constant size argument must be non-negative and representable +by a value of type int; if it is an untyped constant it is given type int. +If both n and m are provided and are constant, then +n must be no larger than m. +For slices and channels, if n is negative or larger than m at run time, +a run-time panic occurs. +

+ +
+s := make([]int, 10, 100)       // slice with len(s) == 10, cap(s) == 100
+s := make([]int, 1e3)           // slice with len(s) == cap(s) == 1000
+s := make([]int, 1<<63)         // illegal: len(s) is not representable by a value of type int
+s := make([]int, 10, 0)         // illegal: len(s) > cap(s)
+c := make(chan int, 10)         // channel with a buffer size of 10
+m := make(map[string]int, 100)  // map with initial space for approximately 100 elements
+
+ +

+Calling make with a map type and size hint n will +create a map with initial space to hold n map elements. +The precise behavior is implementation-dependent. +

+ + +

Appending to and copying slices

+ +

+The built-in functions append and copy assist in +common slice operations. +For both functions, the result is independent of whether the memory referenced +by the arguments overlaps. +

+ +

+The variadic function append +appends zero or more values x to a slice s +and returns the resulting slice of the same type as s. +The core type of s must be a slice +of type []E. +The values x are passed to a parameter of type ...E +and the respective parameter +passing rules apply. +As a special case, if the core type of s is []byte, +append also accepts a second argument with core type +bytestring followed by .... +This form appends the bytes of the byte slice or string. +

+ +
+append(s S, x ...E) S  // core type of S is []E
+
+ +

+If the capacity of s is not large enough to fit the additional +values, append allocates a new, sufficiently large underlying +array that fits both the existing slice elements and the additional values. +Otherwise, append re-uses the underlying array. +

+ +
+s0 := []int{0, 0}
+s1 := append(s0, 2)                // append a single element     s1 == []int{0, 0, 2}
+s2 := append(s1, 3, 5, 7)          // append multiple elements    s2 == []int{0, 0, 2, 3, 5, 7}
+s3 := append(s2, s0...)            // append a slice              s3 == []int{0, 0, 2, 3, 5, 7, 0, 0}
+s4 := append(s3[3:6], s3[2:]...)   // append overlapping slice    s4 == []int{3, 5, 7, 2, 3, 5, 7, 0, 0}
+
+var t []interface{}
+t = append(t, 42, 3.1415, "foo")   //                             t == []interface{}{42, 3.1415, "foo"}
+
+var b []byte
+b = append(b, "bar"...)            // append string contents      b == []byte{'b', 'a', 'r' }
+
+ +

+The function copy copies slice elements from +a source src to a destination dst and returns the +number of elements copied. +The core types of both arguments must be slices +with identical element type. +The number of elements copied is the minimum of +len(src) and len(dst). +As a special case, if the destination's core type is []byte, +copy also accepts a source argument with core type + bytestring. +This form copies the bytes from the byte slice or string into the byte slice. +

+ +
+copy(dst, src []T) int
+copy(dst []byte, src string) int
+
+ +

+Examples: +

+ +
+var a = [...]int{0, 1, 2, 3, 4, 5, 6, 7}
+var s = make([]int, 6)
+var b = make([]byte, 5)
+n1 := copy(s, a[0:])            // n1 == 6, s == []int{0, 1, 2, 3, 4, 5}
+n2 := copy(s, s[2:])            // n2 == 4, s == []int{2, 3, 4, 5, 4, 5}
+n3 := copy(b, "Hello, World!")  // n3 == 5, b == []byte("Hello")
+
+ + +

Deletion of map elements

+ +

+The built-in function delete removes the element with key +k from a map m. The +value k must be assignable +to the key type of m. +

+ +
+delete(m, k)  // remove element m[k] from map m
+
+ +

+If the type of m is a type parameter, +all types in that type set must be maps, and they must all have identical key types. +

+ +

+If the map m is nil or the element m[k] +does not exist, delete is a no-op. +

+ + +

Manipulating complex numbers

+ +

+Three functions assemble and disassemble complex numbers. +The built-in function complex constructs a complex +value from a floating-point real and imaginary part, while +real and imag +extract the real and imaginary parts of a complex value. +

+ +
+complex(realPart, imaginaryPart floatT) complexT
+real(complexT) floatT
+imag(complexT) floatT
+
+ +

+The type of the arguments and return value correspond. +For complex, the two arguments must be of the same +floating-point type and the return type is the +complex type +with the corresponding floating-point constituents: +complex64 for float32 arguments, and +complex128 for float64 arguments. +If one of the arguments evaluates to an untyped constant, it is first implicitly +converted to the type of the other argument. +If both arguments evaluate to untyped constants, they must be non-complex +numbers or their imaginary parts must be zero, and the return value of +the function is an untyped complex constant. +

+ +

+For real and imag, the argument must be +of complex type, and the return type is the corresponding floating-point +type: float32 for a complex64 argument, and +float64 for a complex128 argument. +If the argument evaluates to an untyped constant, it must be a number, +and the return value of the function is an untyped floating-point constant. +

+ +

+The real and imag functions together form the inverse of +complex, so for a value z of a complex type Z, +z == Z(complex(real(z), imag(z))). +

+ +

+If the operands of these functions are all constants, the return +value is a constant. +

+ +
+var a = complex(2, -2)             // complex128
+const b = complex(1.0, -1.4)       // untyped complex constant 1 - 1.4i
+x := float32(math.Cos(math.Pi/2))  // float32
+var c64 = complex(5, -x)           // complex64
+var s int = complex(1, 0)          // untyped complex constant 1 + 0i can be converted to int
+_ = complex(1, 2<<s)               // illegal: 2 assumes floating-point type, cannot shift
+var rl = real(c64)                 // float32
+var im = imag(a)                   // float64
+const c = imag(b)                  // untyped constant -1.4
+_ = imag(3 << s)                   // illegal: 3 assumes complex type, cannot shift
+
+ +

+Arguments of type parameter type are not permitted. +

+ +

Handling panics

+ +

Two built-in functions, panic and recover, +assist in reporting and handling run-time panics +and program-defined error conditions. +

+ +
+func panic(interface{})
+func recover() interface{}
+
+ +

+While executing a function F, +an explicit call to panic or a run-time panic +terminates the execution of F. +Any functions deferred by F +are then executed as usual. +Next, any deferred functions run by F's caller are run, +and so on up to any deferred by the top-level function in the executing goroutine. +At that point, the program is terminated and the error +condition is reported, including the value of the argument to panic. +This termination sequence is called panicking. +

+ +
+panic(42)
+panic("unreachable")
+panic(Error("cannot parse"))
+
+ +

+The recover function allows a program to manage behavior +of a panicking goroutine. +Suppose a function G defers a function D that calls +recover and a panic occurs in a function on the same goroutine in which G +is executing. +When the running of deferred functions reaches D, +the return value of D's call to recover will be the value passed to the call of panic. +If D returns normally, without starting a new +panic, the panicking sequence stops. In that case, +the state of functions called between G and the call to panic +is discarded, and normal execution resumes. +Any functions deferred by G before D are then run and G's +execution terminates by returning to its caller. +

+ +

+The return value of recover is nil if any of the following conditions holds: +

+ + +

+The protect function in the example below invokes +the function argument g and protects callers from +run-time panics raised by g. +

+ +
+func protect(g func()) {
+	defer func() {
+		log.Println("done")  // Println executes normally even if there is a panic
+		if x := recover(); x != nil {
+			log.Printf("run time panic: %v", x)
+		}
+	}()
+	log.Println("start")
+	g()
+}
+
+ + +

Bootstrapping

+ +

+Current implementations provide several built-in functions useful during +bootstrapping. These functions are documented for completeness but are not +guaranteed to stay in the language. They do not return a result. +

+ +
+Function   Behavior
+
+print      prints all arguments; formatting of arguments is implementation-specific
+println    like print but prints spaces between arguments and a newline at the end
+
+ +

+Implementation restriction: print and println need not +accept arbitrary argument types, but printing of boolean, numeric, and string +types must be supported. +

+ +

Packages

+ +

+Go programs are constructed by linking together packages. +A package in turn is constructed from one or more source files +that together declare constants, types, variables and functions +belonging to the package and which are accessible in all files +of the same package. Those elements may be +exported and used in another package. +

+ +

Source file organization

+ +

+Each source file consists of a package clause defining the package +to which it belongs, followed by a possibly empty set of import +declarations that declare packages whose contents it wishes to use, +followed by a possibly empty set of declarations of functions, +types, variables, and constants. +

+ +
+SourceFile       = PackageClause ";" { ImportDecl ";" } { TopLevelDecl ";" } .
+
+ +

Package clause

+ +

+A package clause begins each source file and defines the package +to which the file belongs. +

+ +
+PackageClause  = "package" PackageName .
+PackageName    = identifier .
+
+ +

+The PackageName must not be the blank identifier. +

+ +
+package math
+
+ +

+A set of files sharing the same PackageName form the implementation of a package. +An implementation may require that all source files for a package inhabit the same directory. +

+ +

Import declarations

+ +

+An import declaration states that the source file containing the declaration +depends on functionality of the imported package +(§Program initialization and execution) +and enables access to exported identifiers +of that package. +The import names an identifier (PackageName) to be used for access and an ImportPath +that specifies the package to be imported. +

+ +
+ImportDecl       = "import" ( ImportSpec | "(" { ImportSpec ";" } ")" ) .
+ImportSpec       = [ "." | PackageName ] ImportPath .
+ImportPath       = string_lit .
+
+ +

+The PackageName is used in qualified identifiers +to access exported identifiers of the package within the importing source file. +It is declared in the file block. +If the PackageName is omitted, it defaults to the identifier specified in the +package clause of the imported package. +If an explicit period (.) appears instead of a name, all the +package's exported identifiers declared in that package's +package block will be declared in the importing source +file's file block and must be accessed without a qualifier. +

+ +

+The interpretation of the ImportPath is implementation-dependent but +it is typically a substring of the full file name of the compiled +package and may be relative to a repository of installed packages. +

+ +

+Implementation restriction: A compiler may restrict ImportPaths to +non-empty strings using only characters belonging to +Unicode's +L, M, N, P, and S general categories (the Graphic characters without +spaces) and may also exclude the characters +!"#$%&'()*,:;<=>?[\]^`{|} +and the Unicode replacement character U+FFFD. +

+ +

+Consider a compiled a package containing the package clause +package math, which exports function Sin, and +installed the compiled package in the file identified by +"lib/math". +This table illustrates how Sin is accessed in files +that import the package after the +various types of import declaration. +

+ +
+Import declaration          Local name of Sin
+
+import   "lib/math"         math.Sin
+import m "lib/math"         m.Sin
+import . "lib/math"         Sin
+
+ +

+An import declaration declares a dependency relation between +the importing and imported package. +It is illegal for a package to import itself, directly or indirectly, +or to directly import a package without +referring to any of its exported identifiers. To import a package solely for +its side-effects (initialization), use the blank +identifier as explicit package name: +

+ +
+import _ "lib/math"
+
+ + +

An example package

+ +

+Here is a complete Go package that implements a concurrent prime sieve. +

+ +
+package main
+
+import "fmt"
+
+// Send the sequence 2, 3, 4, … to channel 'ch'.
+func generate(ch chan<- int) {
+	for i := 2; ; i++ {
+		ch <- i  // Send 'i' to channel 'ch'.
+	}
+}
+
+// Copy the values from channel 'src' to channel 'dst',
+// removing those divisible by 'prime'.
+func filter(src <-chan int, dst chan<- int, prime int) {
+	for i := range src {  // Loop over values received from 'src'.
+		if i%prime != 0 {
+			dst <- i  // Send 'i' to channel 'dst'.
+		}
+	}
+}
+
+// The prime sieve: Daisy-chain filter processes together.
+func sieve() {
+	ch := make(chan int)  // Create a new channel.
+	go generate(ch)       // Start generate() as a subprocess.
+	for {
+		prime := <-ch
+		fmt.Print(prime, "\n")
+		ch1 := make(chan int)
+		go filter(ch, ch1, prime)
+		ch = ch1
+	}
+}
+
+func main() {
+	sieve()
+}
+
+ +

Program initialization and execution

+ +

The zero value

+

+When storage is allocated for a variable, +either through a declaration or a call of new, or when +a new value is created, either through a composite literal or a call +of make, +and no explicit initialization is provided, the variable or value is +given a default value. Each element of such a variable or value is +set to the zero value for its type: false for booleans, +0 for numeric types, "" +for strings, and nil for pointers, functions, interfaces, slices, channels, and maps. +This initialization is done recursively, so for instance each element of an +array of structs will have its fields zeroed if no value is specified. +

+

+These two simple declarations are equivalent: +

+ +
+var i int
+var i int = 0
+
+ +

+After +

+ +
+type T struct { i int; f float64; next *T }
+t := new(T)
+
+ +

+the following holds: +

+ +
+t.i == 0
+t.f == 0.0
+t.next == nil
+
+ +

+The same would also be true after +

+ +
+var t T
+
+ +

Package initialization

+ +

+Within a package, package-level variable initialization proceeds stepwise, +with each step selecting the variable earliest in declaration order +which has no dependencies on uninitialized variables. +

+ +

+More precisely, a package-level variable is considered ready for +initialization if it is not yet initialized and either has +no initialization expression or +its initialization expression has no dependencies on uninitialized variables. +Initialization proceeds by repeatedly initializing the next package-level +variable that is earliest in declaration order and ready for initialization, +until there are no variables ready for initialization. +

+ +

+If any variables are still uninitialized when this +process ends, those variables are part of one or more initialization cycles, +and the program is not valid. +

+ +

+Multiple variables on the left-hand side of a variable declaration initialized +by single (multi-valued) expression on the right-hand side are initialized +together: If any of the variables on the left-hand side is initialized, all +those variables are initialized in the same step. +

+ +
+var x = a
+var a, b = f() // a and b are initialized together, before x is initialized
+
+ +

+For the purpose of package initialization, blank +variables are treated like any other variables in declarations. +

+ +

+The declaration order of variables declared in multiple files is determined +by the order in which the files are presented to the compiler: Variables +declared in the first file are declared before any of the variables declared +in the second file, and so on. +

+ +

+Dependency analysis does not rely on the actual values of the +variables, only on lexical references to them in the source, +analyzed transitively. For instance, if a variable x's +initialization expression refers to a function whose body refers to +variable y then x depends on y. +Specifically: +

+ + + +

+For example, given the declarations +

+ +
+var (
+	a = c + b  // == 9
+	b = f()    // == 4
+	c = f()    // == 5
+	d = 3      // == 5 after initialization has finished
+)
+
+func f() int {
+	d++
+	return d
+}
+
+ +

+the initialization order is d, b, c, a. +Note that the order of subexpressions in initialization expressions is irrelevant: +a = c + b and a = b + c result in the same initialization +order in this example. +

+ +

+Dependency analysis is performed per package; only references referring +to variables, functions, and (non-interface) methods declared in the current +package are considered. If other, hidden, data dependencies exists between +variables, the initialization order between those variables is unspecified. +

+ +

+For instance, given the declarations +

+ +
+var x = I(T{}).ab()   // x has an undetected, hidden dependency on a and b
+var _ = sideEffect()  // unrelated to x, a, or b
+var a = b
+var b = 42
+
+type I interface      { ab() []int }
+type T struct{}
+func (T) ab() []int   { return []int{a, b} }
+
+ +

+the variable a will be initialized after b but +whether x is initialized before b, between +b and a, or after a, and +thus also the moment at which sideEffect() is called (before +or after x is initialized) is not specified. +

+ +

+Variables may also be initialized using functions named init +declared in the package block, with no arguments and no result parameters. +

+ +
+func init() { … }
+
+ +

+Multiple such functions may be defined per package, even within a single +source file. In the package block, the init identifier can +be used only to declare init functions, yet the identifier +itself is not declared. Thus +init functions cannot be referred to from anywhere +in a program. +

+ +

+A package with no imports is initialized by assigning initial values +to all its package-level variables followed by calling all init +functions in the order they appear in the source, possibly in multiple files, +as presented to the compiler. +If a package has imports, the imported packages are initialized +before initializing the package itself. If multiple packages import +a package, the imported package will be initialized only once. +The importing of packages, by construction, guarantees that there +can be no cyclic initialization dependencies. +

+ +

+Package initialization—variable initialization and the invocation of +init functions—happens in a single goroutine, +sequentially, one package at a time. +An init function may launch other goroutines, which can run +concurrently with the initialization code. However, initialization +always sequences +the init functions: it will not invoke the next one +until the previous one has returned. +

+ +

+To ensure reproducible initialization behavior, build systems are encouraged +to present multiple files belonging to the same package in lexical file name +order to a compiler. +

+ + +

Program execution

+

+A complete program is created by linking a single, unimported package +called the main package with all the packages it imports, transitively. +The main package must +have package name main and +declare a function main that takes no +arguments and returns no value. +

+ +
+func main() { … }
+
+ +

+Program execution begins by initializing the main package and then +invoking the function main. +When that function invocation returns, the program exits. +It does not wait for other (non-main) goroutines to complete. +

+ +

Errors

+ +

+The predeclared type error is defined as +

+ +
+type error interface {
+	Error() string
+}
+
+ +

+It is the conventional interface for representing an error condition, +with the nil value representing no error. +For instance, a function to read data from a file might be defined: +

+ +
+func Read(f *File, b []byte) (n int, err error)
+
+ +

Run-time panics

+ +

+Execution errors such as attempting to index an array out +of bounds trigger a run-time panic equivalent to a call of +the built-in function panic +with a value of the implementation-defined interface type runtime.Error. +That type satisfies the predeclared interface type +error. +The exact error values that +represent distinct run-time error conditions are unspecified. +

+ +
+package runtime
+
+type Error interface {
+	error
+	// and perhaps other methods
+}
+
+ +

System considerations

+ +

Package unsafe

+ +

+The built-in package unsafe, known to the compiler +and accessible through the import path "unsafe", +provides facilities for low-level programming including operations +that violate the type system. A package using unsafe +must be vetted manually for type safety and may not be portable. +The package provides the following interface: +

+ +
+package unsafe
+
+type ArbitraryType int  // shorthand for an arbitrary Go type; it is not a real type
+type Pointer *ArbitraryType
+
+func Alignof(variable ArbitraryType) uintptr
+func Offsetof(selector ArbitraryType) uintptr
+func Sizeof(variable ArbitraryType) uintptr
+
+type IntegerType int  // shorthand for an integer type; it is not a real type
+func Add(ptr Pointer, len IntegerType) Pointer
+func Slice(ptr *ArbitraryType, len IntegerType) []ArbitraryType
+func SliceData(slice []ArbitraryType) *ArbitraryType
+func String(ptr *byte, len IntegerType) string
+func StringData(str string) *byte
+
+ + + +

+A Pointer is a pointer type but a Pointer +value may not be dereferenced. +Any pointer or value of underlying type uintptr can be +converted to a type of underlying type Pointer and vice versa. +The effect of converting between Pointer and uintptr is implementation-defined. +

+ +
+var f float64
+bits = *(*uint64)(unsafe.Pointer(&f))
+
+type ptr unsafe.Pointer
+bits = *(*uint64)(ptr(&f))
+
+var p ptr = nil
+
+ +

+The functions Alignof and Sizeof take an expression x +of any type and return the alignment or size, respectively, of a hypothetical variable v +as if v was declared via var v = x. +

+

+The function Offsetof takes a (possibly parenthesized) selector +s.f, denoting a field f of the struct denoted by s +or *s, and returns the field offset in bytes relative to the struct's address. +If f is an embedded field, it must be reachable +without pointer indirections through fields of the struct. +For a struct s with field f: +

+ +
+uintptr(unsafe.Pointer(&s)) + unsafe.Offsetof(s.f) == uintptr(unsafe.Pointer(&s.f))
+
+ +

+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)) % unsafe.Alignof(x) == 0
+
+ +

+A (variable of) type T has variable size if T +is a type parameter, or if it is an +array or struct type containing elements +or fields of variable size. Otherwise the size is constant. +Calls to Alignof, Offsetof, and Sizeof +are compile-time constant expressions of +type uintptr if their arguments (or the struct s in +the selector expression s.f for Offsetof) are types +of constant size. +

+ +

+The function Add adds len to ptr +and returns the updated pointer unsafe.Pointer(uintptr(ptr) + uintptr(len)). +The len argument must be of integer type or an untyped constant. +A constant len argument must be representable by a value of type int; +if it is an untyped constant it is given type int. +The rules for valid uses of Pointer still apply. +

+ +

+The function Slice returns a slice whose underlying array starts at ptr +and whose length and capacity are len. +Slice(ptr, len) is equivalent to +

+ +
+(*[len]ArbitraryType)(unsafe.Pointer(ptr))[:]
+
+ +

+except that, as a special case, if ptr +is nil and len is zero, +Slice returns nil. +

+ +

+The len argument must be of integer type or an untyped constant. +A constant len argument must be non-negative and representable by a value of type int; +if it is an untyped constant it is given type int. +At run time, if len is negative, +or if ptr is nil and len is not zero, +a run-time panic occurs. +

+ +

+The function SliceData returns a pointer to the underlying array of the slice argument. +If the slice's capacity cap(slice) is not zero, that pointer is &slice[:1][0]. +If slice is nil, the result is nil. +Otherwise it is a non-nil pointer to an unspecified memory address. +

+ +

+The function String returns a string value whose underlying bytes start at +ptr and whose length is len. +The same requirements apply to the ptr and len argument as in the function +Slice. If len is zero, the result is the empty string "". +Since Go strings are immutable, the bytes passed to String must not be modified afterwards. +

+ +

+The function StringData returns a pointer to the underlying bytes of the str argument. +For an empty string the return value is unspecified, and may be nil. +Since Go strings are immutable, the bytes returned by StringData must not be modified. +

+ +

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: +

+
    +
  1. For a variable x of any type: unsafe.Alignof(x) is at least 1. +
  2. + +
  3. 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. +
  4. + +
  5. For a variable x of array type: unsafe.Alignof(x) is the same as + the alignment of a variable of the array's element type. +
  6. +
+ +

+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. +

-- cgit v1.2.3