Go Cheat Sheet: Operators
Go Cheat Sheet: Operators
Comparison
Arithmetic
Credits Operator Description
Operator Description
Most example code taken from A Tour of Go, which is an excellent introduction to Go. If == equal
+ addition
you're new to Go, do that tour. Seriously. != not equal
- subtraction
< less than
Original HTML Cheat Sheet by Ariel Mashraki (a8m): * multiplication
<= less than or equal
https://github.com/a8m/go-lang-cheat-sheet / quotient
> greater than
% remainder
>= greater than or equal
Go in a Nutshell & bitwise AND
| bitwise OR Logical
• Imperative language
^ bitwise XOR Operator Description
• Statically typed
• Syntax similar to Java/C/C++, but less parentheses and no semicolons &^ bit clear (AND NOT) && logical AND
• Compiles to native code (no JVM) << left shift || logical OR
• No classes, but structs with methods >> right shift (logical) ! logical NOT
• Interfaces
Other
• No implementation inheritance. There's type embedding, though.
• Functions are first class citizens Operator Description
• Functions can return multiple values & address of / create pointer
• Has closures * dereference pointer
• Pointers, but not pointer arithmetic send / receive operator (see
<-
• Built-in concurrency primitives: Goroutines and Channels 'Channels' below)
Declarations
Basic Syntax
Type goes after identifier!
var foo int // declaration without initialization
Hello World var foo int = 42 // declaration with initialization
File hello.go: var foo, bar int = 42, 1302 // declare/init multiple vars at once
var foo = 42 // type omitted, will be inferred
package main foo := 42 // shorthand, only in func bodies, implicit type
const constant = "This is a constant"
import "fmt"
func main() {
fmt.Println("Hello Go") Functions
}
// a simple function
func functionName() {}
$ go run hello.go
// function with parameters (again, types go after identifiers)
func functionName(param1 string, param2 int) {}
// Return multiple named results simply by return // Using ... before the type name of the last parameter indicates
func returnMulti2() (n int, s string) { // that it takes zero or more of those parameters.
n = 42 // The function is invoked like any other function except we can
s = "foobar" // pass as many arguments as we want.
// n and s will be returned func adder(args ...int) int {
return total := 0
} for _, v := range args { // Iterate over all args
var x, str = returnMulti2() total += v
}
return total
}
Functions As Values And Closures
func main() {
// assign a function to a name Built-in Types
add := func(a, b int) int {
return a + b bool
}
// use the name to call the function string
fmt.Println(add(3, 4))
} int int8 int16 int32 int64
uint uint8 uint16 uint32 uint64 uintptr
// Closures, lexically scoped: Functions can access values that were
// in scope when defining the function byte // alias for uint8
func scope() func() int{
outer_var := 2 rune // alias for int32 ~= (Unicode code point) - Very Viking
foo := func() int { return outer_var}
return foo float32 float64
}
complex64 complex128
func another_scope() func() int{
// won't compile - outer_var and foo not defined in this scope
outer_var = 444
return foo Type Conversions
}
var i int = 42
// Closures: don't mutate outer vars, instead redefine them! var f float64 = float64(i)
func outer() (func() int, int) { var u uint = uint(f)
outer_var := 2 // NOTE outer_var is outside inner's scope
inner := func() int { // alternative syntax
outer_var += 99 // attempt to mutate outer_var i := 42
return outer_var // => 101 (but outer_var is a newly redefined f := float64(i)
// variable visible only inside inner) u := uint(f)
}
return inner, outer_var // => 101, 2 (still!)
}
Control structures (cont)
Packages
• package declaration at top of every source file Switch
• executables are in package main // switch statement
switch operatingSystem {
• convention: package name == last name of import path case "darwin":
(import path math/rand => package rand) fmt.Println("Mac OS Hipster")
// cases break automatically, no fallthrough by default
• upper case identifier: exported (visible from other packages) case "linux":
• Lower case identifier: private (not visible from other packages) fmt.Println("Linux Geek")
default:
// Windows, BSD, ...
fmt.Println("Other")
Control structures }
// Declaration
Operations on Arrays and Slices type Vertex struct {
X, Y int
len(a) gives you the length of an array/a slice. It's a built-in function, not a attribute/method }
on the array. // Creating
var v = Vertex{1, 2}
// loop over an array/a slice var v = Vertex{X: 1, Y: 2} // Creates a struct by defining values
for i, e := range a { // with keys
// i is the index, e the element
} // Accessing members
v.X = 4
// if you only need e:
for _, e := range a { // You can declare methods on structs. The struct you want to declare
// e is the element // the method on (the receiving type) comes between the func keyword
} // and the method name. The struct is copied on each method call(!)
func (v Vertex) Abs() float64 {
// ...and if you only need the index return math.Sqrt(v.X*v.X + v.Y*v.Y)
for i := range a { }
}
// Call method
// In Go pre-1.4, it is a compiler error to not use i and e. v.Abs()
// Go 1.4 introduced a variable-free form:
for range time.Tick(time.Second) { // For mutating methods, you need to use a pointer (see below) to the
// do it once a sec // Struct as the type. With this, the struct value is not copied for
} // the method call.
func (v *Vertex) add(n float64) {
v.X += n
v.Y += n
Maps }
var m map[string]int
m = make(map[string]int)
m["key"] = 42 Anonymous structs
fmt.Println(m["key"]) Cheaper and safer than using map[string]interface{}.
delete(m, "key") point := struct {
X, Y int
elem, ok := m["key"] // test if key "key" is present, retrieve if so }{1, 2}
// map literal
var m = map[string]Vertex{
"Bell Labs": {40.68433, -74.39967}, Pointers
"Google": {37.42202, -122.08408},
} p := Vertex{1, 2} // p is a Vertex
q := &p // q is a pointer to a Vertex
r := &Vertex{1, 2} // r is also a pointer to a Vertex
Embedding Concurrency
There is no subclassing in Go. Instead, there is interface and struct embedding (composition).
Goroutines
// ReadWriter implementations must satisfy both Reader and Writer
type ReadWriter interface { Goroutines are lightweight threads (managed by Go, not OS threads). go f(a, b) starts a
Reader
Writer new goroutine which runs f (given f is a function).
}
// just a function (which can be later started as a goroutine)
// Server exposes all the methods that Logger has func doStuff(s string) {
type Server struct { }
Host string
Port int func main() {
*log.Logger // using a named function in a goroutine
} go doStuff("foobar")
// initialize the embedded type the usual way // using an anonymous inner function in a goroutine
server := &Server{"localhost", 80, log.New(...)} go func (x int) {
// function body goes here
// methods implemented on the embedded struct are passed through }(42)
server.Log(...) // calls server.Logger.Log(...) }
Errors
There is no exception handling. Functions that might produce an error just declare an
additional return value of type Error. This is the Error interface:
// Non-buffered channels block. Read blocks when no value is // IV. A receive from a close channel returns the zero value
// immediately
// available, write blocks if a value already has been written
// but not read. var c = make(chan int, 2)
c <- 1
// Create a buffered channel. Writing to a buffered channels does c <- 2
close(c)
// not block if less than <buffer size> unread values have been
// written. for i := 0; i < 3; i++ {
fmt.Printf("%d ", <-c)
ch := make(chan int, 100)
}
// 1 2 0
close(c) // closes the channel (only sender should close)
func main() {
Channel Axioms var h Hello
http.ListenAndServe("localhost:4000", h)
// I. A send to a nil channel blocks forever }
var c chan string
c <- "Hello, World!" // Here's the method signature of http.ServeHTTP:
// fatal error: all goroutines are asleep - deadlock! // type Handler interface {
// ServeHTTP(w http.ResponseWriter, r *http.Request)
// II. A receive from a nil channel blocks forever // }
var c chan string
fmt.Println(<-c)
// fatal error: all goroutines are asleep - deadlock!