Functions

Basic syntax:
- func foo() {
  ...
}

Parameters:
- Comma delimited list of variable and types
  - func foo(bar string, baz int)
- Parameters of same type list type once, at the end
  - func foo(bar, baz int)
- When pointers are passed in, the function can change the value in the caller
  - This is always true for data of slices and maps
- Use variadic parameters to send list of same types in
  - Must be last parameter
  - Received as a slice
  - func foo(bar string, baz ...int)

Return Values:
- Single return values just list type
  - func foo() int
- Multiple return values list types surrounded by parentheses
  - func foo() (int, error)
  - The (result type, error) paradigm is a very common idiom
- Can use named return values
  - Initializes returned variable
  - Return using return keyword on its own
- Can return addresses of local variables
  - Automatically promoted from local memory (stack) to shared memory (heap)

Anonymous Functions:
- Functions don't have names if they are:
  - Immediately Invoked Function Expressions (IIFE), I.E:
    - func() {
      ...
    }()
  - Assigned to a variable or passed as an argument to a function
    - a := func() {
      ...
    }
    a()

Functions as Types:
- Can assign functions to variables or use as arguments and return values in functions
- Type signature is like function signature, with no parameter names
  - var f func(string, string, string) (int, error)

Methods:
- Function that executes in context of a type
- Format:
  - func (g greeter) greet() {
    ...
  }
- Receiver can be value or pointer
  - Value receiver gets copy of type
  - Pointer receiver gets pointer to type

Interfaces

// Basic syntax:
type Writer interface {
  Write([]byte) (int, error)
}

type ConsoleWriter struct{}

func (cw ConsoleWriter) Write(data[]byte) (int, error){
  n, err := fmt.Println(string(data))
  return n, err
}


// Composing Interfaces:
type Writer interface {
  Write([]byte) (int, error)
}

type Closer interface {
  Close() error
}

type WriterCloser interface {
  Writer
  Closer
}


// Type Conversion:
var wc WriterCloser = NewBufferedWriterCloser()
bwc := wc.(*BufferedWriterCloser)

Implementing with Values vs. Pointers:
- Method set of "value" is all methods with value receivers
- Method set of pointer is all methods, regardless of receiver type


// Best Practices:
- Use many, small interfaces
  - Single method interfaces are some of the most powerful and flexible Go-lang tools
    - io.Writer, io.Reader, interface{}
- Don't export interfaces for types that will be consumed
- Do export interfaces for types that will be used by packages
- Design functions and methods to receive interfaces whenever possible

d

By Levi

Leave a Reply

Your email address will not be published. Required fields are marked *