The Go Programming Language
Rate it:
Open Preview
2%
Flag icon
Package main is special. It defines a standalone executable program, not a library. Within package main the function main is also special—it’s where execution of the program begins.
3%
Flag icon
Go does not require semicolons at the ends of statements or declarations, except where two or more appear on the same line. In effect, newlines following certain tokens are converted into semicolons, so where newlines are placed matters to proper parsing of Go code.
3%
Flag icon
These are statements, not expressions as they are in most languages in the C family, so j = i++ is illegal, and they are postfix only, so --i is not legal either.
4%
Flag icon
The first form, a short variable declaration, is the most compact, but it may be used only within a function, not for package-level variables. The second form relies on default initialization to the zero value for strings, which is "".
4%
Flag icon
It’s not a problem if the map doesn’t yet contain that key. The first time a new line is seen, the expression counts[line] on the right-hand side evaluates to the zero value for its type, which is 0 for int.
7%
Flag icon
consistently; the program would have a serious bug called a race condition (§9.1). To avoid this problem, we must ensure that at most one goroutine accesses the variable at a time, which is the purpose of the mu.Lock() and mu.Unlock()
8%
Flag icon
If the name begins with an upper-case letter, it is exported, which means that it is visible and accessible outside of its own package
9%
Flag icon
The expression new(T) creates an unnamed variable of type T, initializes it to the zero value of T, and returns its address, which is a value of type *T.
10%
Flag icon
each variable that escapes requires an extra memory allocation.
10%
Flag icon
All of the right-hand side expressions are evaluated before any of the variables are updated, making this form most useful when some of the variables appear on both sides of the assignment,
10%
Flag icon
nil may be assigned to any variable of interface or reference type.
10%
Flag icon
Whether two values may be compared with == and != is related to assignability: in any comparison, the first operand must be assignable to the type of the second operand, or vice versa.
12%
Flag icon
Package initialization begins by initializing package-level variables in the order in which they are declared, except that dependencies are resolved first:
12%
Flag icon
A syntactic block is a sequence of statements enclosed in braces like those that surround the body of a function or loop.
13%
Flag icon
normal practice in Go is to deal with the error in the if block and then return, so that the successful execution path is not indented.
13%
Flag icon
The type rune is a synonym for int32 and conventionally indicates that a value is a Unicode code point.
13%
Flag icon
type byte is a synonym for uint8,
13%
Flag icon
In Go, the sign of the remainder is always the same as the sign of the dividend, so -5%3 and -5%-3 are both -2. The behavior of / depends on whether its operands are integers, so 5.0/4.0 is 1.25, but 5/4 is 1 because integer division truncates the result toward zero.
14%
Flag icon
Arithmetically, a left shift x<<n is equivalent to multiplication by 2n and a right shift x>>n is equivalent to the floor of division by 2n.
14%
Flag icon
Left shifts fill the vacated bits with zeros, as do right shifts of unsigned numbers, but right shifts of signed numbers fill the vacated bits with copies of the sign bit.
14%
Flag icon
to be used for exactly one purpose—file permissions
15%
Flag icon
It’s tempting to use NaN as a sentinel value in a numeric computation, but testing whether a specific computational result is equal to NaN is perilous because any comparison with NaN always yields false (except !=, which is always the negation of == ):
16%
Flag icon
The built-in len function returns the number of bytes (not runes) in a string, and the index operation s[i] retrieves the i-th byte of string s, where 0 ≤ i < len(s).
16%
Flag icon
The i-th byte of a string is not necessarily the i-th character of a string, because the UTF-8 encoding of a non-ASCII code point requires two or more bytes.
16%
Flag icon
Immutability means that it is safe for two copies of a string to share the same underlying memory, making it cheap to copy strings of any length. Similarly, a string s and a substring like s[7:] may safely share the same data, so the substring operation is also cheap. No new memory is allocated in either case.
17%
Flag icon
A raw string literal is written `...`, using backquotes instead of double quotes. Within a raw string literal, no escape sequences are processed; the contents are taken literally, including backslashes and newlines, ...more
17%
Flag icon
UTF-8 was invented by Ken Thompson and Rob Pike, two of the creators of Go, and is now a Unicode standard. It uses between 1 and 4 bytes to represent each rune, but only 1 byte for ASCII characters, and only 2 or 3 bytes for most runes in common use. The high-order bits of the first byte of the encoding for a rune indicate how many bytes follow.
17%
Flag icon
The lexicographic byte order equals the Unicode code point order, so sorting UTF-8 works naturally.
17%
Flag icon
Go’s range loop, when applied to a string, performs UTF-8 decoding implicitly. The output of the loop below is also shown in Figure 3.5; notice how the index jumps by more than 1 for each non-ASCII rune.
18%
Flag icon
fmt.Println(string(65))     // "A", not "65"
18%
Flag icon
Because strings are immutable, building up strings incrementally can involve a lot of allocation and copying. In such cases, it’s more efficient to use the bytes.Buffer type,
20%
Flag icon
if an ellipsis “...” appears in place of the length, the array length is determined by the number of initializers.
21%
Flag icon
A simple way to rotate a slice left by n elements is to apply the reverse function three times, first to the leading n elements, then to the remaining elements, and finally to the whole slice.
21%
Flag icon
The zero value of a slice type is nil. A nil slice has no underlying array. The nil slice has length and capacity zero, but there are also non-nil slices of length and capacity zero, such as []int{} or make([]int, 3)[3:].
21%
Flag icon
The built-in function make creates a slice of a specified element type, length, and capacity. The capacity argument may be omitted, in which case the capacity equals the length.
21%
Flag icon
Under the hood, make creates an unnamed array variable and returns a slice of it; the array is accessible only through the returned slice.
22%
Flag icon
The key type K must be comparable using ==, so that the map can test whether a given key is equal to one already within it. Though floating-point numbers are comparable, it’s a bad idea to compare floats for equality and, as we mentioned in Chapter 3, especially bad if NaN is a possible value. There are no restrictions on the value type V.
23%
Flag icon
One reason that we can’t take the address of a map element is that growing a map might cause rehashing of existing elements into new storage locations,
23%
Flag icon
As with slices, maps cannot be compared to each other; the only legal comparison is with nil. To test whether two maps contain the same keys and the same associated values, we must write a loop:
24%
Flag icon
Field order is significant to type identity.
24%
Flag icon
The struct type with no fields is called the empty struct, written struct{}. It has size zero and carries no information but may be useful nonetheless. Some Go programmers use it instead of bool as the value type of a map that represents a set, to emphasize that only the keys are significant, but the space saving is marginal and the syntax more cumbersome, so we generally avoid it.
25%
Flag icon
If all the fields of a struct are comparable, the struct itself is comparable,
25%
Flag icon
Because “anonymous” fields do have implicit names, you can’t have two anonymous fields of the same type since their names would conflict. And because the name of the field is implicitly determined by its type, so too is the visibility of the field.
25%
Flag icon
the explicit long form shown in the comment would be forbidden outside the declaring package because circle and point would be inaccessible.
27%
Flag icon
Within an action, the | notation makes the result of one operation the argument of another, analogous to a Unix shell pipeline.
29%
Flag icon
Because error messages are frequently chained together, message strings should not be capitalized and newlines should be avoided.
32%
Flag icon
All function values created by this loop “capture” and share the same variable—an addressable storage location, not its value at that particular moment. The value of dir is updated in successive iterations, so by the time the cleanup functions are called, the dir variable has been updated several times by the now-completed for loop.
33%
Flag icon
A deferred anonymous function can even change the values that the enclosing function returns to its caller: func triple(x int) (result int) {     defer func() { result += x }()     return double(x) }
33%
Flag icon
A panic is often the best thing to do when some “impossible” situation happens, for instance, execution reaches a case that logically can’t happen:
34%
Flag icon
as a general rule, you should not attempt to recover from another package’s panic. Public APIs should report failures as errors. Similarly, you should not recover from a panic that may pass through a function you do not maintain, such as a caller-provided callback, since you cannot reason about its safety.
« Prev 1