If

simple

  1. if x > 0 {
  2. return y
  3. }

accept an initialization statement

  1. if err := file.Chmod(0664); err != nil {
  2. log.Print(err)
  3. return err
  4. }

the unnecessary else is omitted

  1. f, err := os.Open(name)
  2. if err != nil {
  3. return err
  4. }
  5. d, err := f.Stat()
  6. if err != nil {
  7. f.Close()
  8. return err
  9. }
  10. // no else
  11. codeUsing(f, d)

Redeclaration and reassignment

  1. f, err := os.Open(name)
  2. d, err := f.Stat()

err is declared by the first statement, but only re-assigned in the second.


For

three forms

  1. // Like a C for
  2. for init; condition; post { }
  3. // Like a C while
  4. for condition { }
  5. // Like a C for(;;)
  6. for { }

range clause

  1. for key, value := range oldMap {
  2. newMap[key] = value
  3. }
  4. // only the first item (key or index)
  5. for key := range oldMap {
  6. handleKey(key)
  7. }
  8. // only the second item (value), use blank identifier (an underscore)
  9. for _, value := range array {
  10. handleValue(value)
  11. }

For strings, the range breaks out individual Unicode code points by parsing the UTF-8.

  1. for pos, char := range "😀😁" {
  2. fmt.Printf("character %#U starts at byte position %d, cp is %d\n", char, pos, char)
  3. }
  4. // prints out:
  5. // character U+1F600 '😀' starts at byte position 0, cp is 128512
  6. // character U+1F601 '😁' starts at byte position 4, cp is 128513

Go has no comma operator, and ++, -- are statements not expressions.
parallel assignment (use multiple variables in a for loop)

  1. // Reverse a
  2. for i, j := 0, len(a)-1; i < j; i, j = i+1, j-1 {
  3. a[i], a[j] = a[j], a[i]
  4. }

Switch

write an if``-``else``-``if``-``else chain as a switch

  1. func unhex(c byte) byte {
  2. switch {
  3. case '0' <= c && c <= '9':
  4. return c - '0'
  5. case 'a' <= c && c <= 'f':
  6. return c - 'a' + 10
  7. case 'A' <= c && c <= 'F':
  8. return c - 'A' + 10
  9. }
  10. return 0
  11. }

cases can be presented in comma-separated lists

  1. func shouldEscape(c byte) bool {
  2. switch c {
  3. case ' ', '?', '&', '=', '#', '+', '%':
  4. return true
  5. }
  6. return false
  7. }

no automatic fall through
break / continue / Label:


Type switch

  1. var t interface{}
  2. t = functionOfSomeType()
  3. switch t := t.(type) {
  4. default:
  5. fmt.Printf("unexpected type %T\n", t) // %T prints whatever type t has
  6. case bool:
  7. fmt.Printf("boolean %t\n", t) // t has type bool
  8. case int:
  9. fmt.Printf("integer %d\n", t) // t has type int
  10. case *bool:
  11. fmt.Printf("pointer to boolean %t\n", *t) // t has type *bool
  12. case *int:
  13. fmt.Printf("pointer to integer %d\n", *t) // t has type *int
  14. }