Day 1 Part 2

  1. Go has automatic semi-colon insertion
  2. fmt.Printf() format flags:
    1. %c for character
    2. %T for type
    3. %#v for debugging value
    4. %s for string
  3. Use utf8.RuneCountInString(s) to get the actual count of unicode codepoints in the string vs the byte length of the string which you’d get if you simply use len(s).
  4. Looping through characters of a string (not just bytes):
for i, r := range s {
// i is index
// r is a rune (i32)
}  
  1. Writing a isPalindrome function that respects unicode characters:
func isPalindrome(s string) bool {
	rs := []rune(s)
	for i := 0; i < len(rs) / 2; i++ {
		if rs[i] != rs[len(rs) - i - 1] {
			return false
		}
	}
	
	return true
}

Day 1 Part 3

  1. resp.Body is of type io.ReadCloser, which is a custom type that implements both io.Reader and io.Closer interfaces
  2. io.Copy(to, from) — different from other langs, possibly to imitate to = from analogy?
  3. log.Fatalf() can be used to print some message and quit (by calling os.Exit(1), which it does for you)
  4. resp.Header is not a map, even though it looks like one
  5. If we want to ignore some returned value, we can use _
  6. Fun fact: api.github.com returns a prettified JSON response depending on the user agent. It does this for curl and browser agents.
  7. By default, Go’s JSON decoder will convert JSON number to float64
  8. JSON arrays are mapped to []any
  9. JSON objects could be mapped to either map[string]any or struct
  10. JSON decoding/encoding:
    1. JSON → io.Reader → Go: json.Decode
    2. JSON → []byte → Go: json.Unmarshal
    3. Go: io.Writer → Go: json.Encode
    4. Go: []byte → Go: json.Marshal
  11. url.PathEscape can be used to escape part of a URL path

Day 1 Part 4

  1. We don’t want to keep file descriptors open, but we also want to close them only at the end of the current function. We can use defer file.Close() to have this get executed before the function returns