Functions in go are typed. The return value of a function is also typed. Functions can also return multiple values. This is super common for error handling.

There are no default parameters or optional parameters in Go. They always have values. The difference is that Go initializes the value to the “zero value” of the declared type in their absence.

package main

import (

type Point struct {
	X, Y float64

func GetGirlfriendLocation() (loc *Point, err error) {
	args := os.Args[1:]
	if len(args) > 1 {
		return nil, fmt.Errorf("can't have more than one girlfriend")

	if len(args) < 1 {
		return nil, fmt.Errorf("you don't have a girlfriend")

	// retrieve location of girlfriend
	return &Point{64.11111, 312.0000089}, nil

func main() {
	point, err := GetGirlfriendLocation()
	if err != nil {
		fmt.Printf("Failed to find her %v\n", err)
	fmt.Printf("Your gf is at %x", point)

Arguments are passed by value in Go functions, not reference. Each function call receives a copy of the arguments. The obvious exception to this is, of course, pointers. Passing pointers as an argument in Go is quite popular.

One interesting aspect of Go’s function syntax is “bare returns”. This is super crazy to me because it seems like a magical feature in a very anti-magic language. Go seems to favor explicity and readability; this is the opposite of that. Still cool.

func countWords(url string)(words, links int, err error) {
  resp, err := http.Get(url)
  if err != nil {
    return // this is the same as return err
  words, links := countWordsAndLinks(resp)
  return // this is the same as return words, links, err

Go detects the variable names matching the named type parameters in the type of the return value of the function. It matches the variable names in the blocks to the type definition of the function, and returns them implicitly.

end of storey Last modified: