Basic Grammar

package main
import "fmt"
func totalLength(a string, b string) int {
 return len(a) + len(b)
}
// The type of args should noted behind the name.
// The type of return value should noted behind the args.
 
func threeTotalLength(a, b, c string) int {
  return len(a) + len(b) + len(b)
}
// When we have multiple consecutive parameter of same type,
// we can omit it up to the final variable of this type and declare the type.
 
func main() {
  fmt.Println("Total Length: ", totalLength("Hello", "World"))
  fmt.Println("Three Total Length: ", threeTotalLength("Hello", "Golang", "World"))
}
// Call like most other languages.
/*
Total Length: 10
Three Total Length: 16
*/

Multiple Return Values

Go has built-in support for multiple return values.
This feature is often used, e.g. return both result and error value from a function.

func show() (string, string) {
  return "Hello", "World"
}
// The `(string, string)` in signature shows that the function will return two strings.
 
func main() {
  a, b := show()
  fmt.Println(a, b)
  // Use multiple assignment to receive the values.
 
  _, c := show()
  fmt.Println(c)
  // Like Python, use underscore as blank identifier to receive the value you don't care.
}
/*
Hello World
World
*/

Variadic Function

Variadic function can be call with any number of trailing args, e.g. fmt.Println().

package main
import "fmt"
func sum(nums ... int) {
  // Use `...` to declare a function accept arbitrary number of args.
  fmt.Print("Nums", nums)
  // In the function, `nums` is equivalent to `[]int`
  total := 0
  for _, n := range nums { // To traverse an array use `range`, index and value will be returned.
    total += n
  }
  fmt.Println("Sum: ", total)
}
 
func main() {
  sum(1, 2, 3, 4, 5)
  // Call in usual way.
 
  s := []int{1, 2, 3, 4, 5}
  sum(s...)
  // To apply a slice to a variadic function, use `function(slice...)`
}

Closures

In Go, function is first-class citizen, which can be used to create Higher-Order Function.
Moreover, Go supports anonymous functions, which can be used to create closures.

package main
import "fmt"
func intSeq() func() int {
  // To declare a function that returns another function.
  i := 0
  return func() int {
    i++
    return i
  }
  // The returned function is an anonymous function defined in the body of `inSeq()`
}
 
func main() {
  nextInt := intSeq()
  fmt.Println(nextInt())
  fmt.Println(nextInt())
  fmt.Println(nextInt())
 
  newInts := intSeq()
  fmt.Println(newInts())
  // Behaves just like what Python does.
}