Basics
Updated: April 21, 2020
Learn the basic components that make up the Go language.
Table of Contents
- Syntax
- Types
- Conversions
- Zero Values
- Scope
- Variables
- Constants
- Range
- Loops
- Arrays
- Switches
- Slices
- Maps
- Functions
- Structs
- Interfaces
- Methods
- Calls
- Pointers
- Channels
- Concurrency
SYNTAX
// This is a single line comment
/* This is
a multi line
comment */
"Double quote strings"
'Go does not allow'
math.Pi // Name is exported if it is capitalized to be used from an imported package
return // A return statement without arguments returns the named return values. This is known as a "naked" return.
TYPES
- Types can express state and behavior.
- State = data structure, not safe for concurrent access
- Behavior = methods
- The int, uint, and uintptr types are usually 32 bits wide on 32-bit systems and 64 bits wide on 64-bit systems.
bool
string
int int8 int16 int32 int64 // signed intergers can include negative numbers
uint uint8 uint16 uint32 uint64 uintptr // unsigned integers only contain 0 or positive numbers
byte // alias for uint8
rune // alias for int32 | represents a Unicode code point
float32 float64
complex64 complex128
ERRORS
- Think of errors as strings
- Error is an interface
errors.New("error here")
is usually sufficient
type error interface {
Error() string // has an error method that returns a string
}
- Exported error variables can be easily checked
var ErrNoName = errors.New("Zero length page name")
func NewPage(name string) (*Page, error)
{
if len(name) == 0 {
return nil, ErrNoName
}
}
CONVERSIONS
The expression T(v) converts the value v to the type T.
Some numeric conversions:
var i int = 42
var f float64 = float64(i)
var u uint = uint(f)
Or, put more simply:
i := 42
f := float64(i)
u := uint(f)
Unlike in C, in Go assignment between items of different type requires an explicit conversion. Try removing the float64 or uint conversions in the example and see what happens.
ZERO VALUES
0 // for numeric types,
false // for the boolean type, and
"" // (the empty string) for strings.
SCOPE
VARIABLES
- Type always comes after the variable name.
var num_items int = 1000 // var declaration with explicit type
var price1, price2 float64 = 9.99, 8.99 // declare multiple variables of the same type
price1, price2 := 9.99, 8.99 // := called short assignment | implicit var declaration | cannot be used outside a function. Type Inference is when = or := does not explicit type.
---
import "fmt"
var c, python, java bool // <-- Package level variable
func main() {
var i int // <-- Function level variable
fmt.Println(i, c, python, java)
}
---
CONSTANTS
-
Constants are declared like variables, but with the
const
keyword. -
Constants can be character, string, boolean, or numeric values.
-
Constants cannot be declared using the := syntax.
RANGE
LOOPS
ARRAYS
SWITCHES
SLICES
MAPS
- Maps are not safe for concurrent access until wrapped with mutexes || channels and locks.
FUNCTIONS
- Functions can take 0 or more arguments.
- When two or more consecutive named function parameters share a type, you can omit the type from all but the last.
- A function can return any number of results.
- Functions should only accept interfaces that require the methods they need
- Functions should not accept a broad interface when a narrow one would work
- Functions should not depend on state
- The same inputs will always result in the same outputs
- Functions can accept interfaces as input
STRUCTS
INTERFACES
- Interfaces provide reusability through dynamic dispatch polymorphism.
- One of Go’s most powerful features
- Permits extensibility
- Defined by methods
- Adherence is only satisfied by behavior
METHODS
- Defines the behavior of a type
- Methods are bound to a specific type
- Methods provide message sending mechanism on any type.
- Do not overuse methods (OO programmers tend to do this)
- A function that operates against a value
- Should use state
- Logically connected
CALLS
POINTERS
- Use a pointer if you want to share the value with a function or method; otherwise use a value (copy)
- If you want to share a value with it’s method, use a pointer receiver
- Not safe for concurrent access
VALUES [#values]
- Use if you want the value copied, not shared
- If the type is an empty struct (stateless, just behavior) use value
- Safe for concurrent access if made safe with sync package and channels.
CHANNELS
// Declaring and initializing
c := make(chan int)
// Sending a value on a channel
c <- 1
// Receiving a value from a channel
x = <-c