0% found this document useful (0 votes)
108 views6 pages

Go Cheat Sheet: Operators

The document provides a summary of operators, data types, and basic syntax in Go programming language. It includes: 1) Comparison and arithmetic operators like ==, +, -, *, /, % etc. 2) Go is an imperative, statically typed language similar to C/C++ but with fewer parentheses and no semicolons. It compiles to native code and has built-in concurrency with goroutines and channels. 3) Functions can return multiple values, be used as values, and closures allow accessing outer scope values. Built-in types include basic types like bool, string, integers and floats.

Uploaded by

rakesh
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
108 views6 pages

Go Cheat Sheet: Operators

The document provides a summary of operators, data types, and basic syntax in Go programming language. It includes: 1) Comparison and arithmetic operators like ==, +, -, *, /, % etc. 2) Go is an imperative, statically typed language similar to C/C++ but with fewer parentheses and no semicolons. It compiles to native code and has built-in concurrency with goroutines and channels. 3) Functions can return multiple values, be used as values, and closures allow accessing outer scope values. Built-in types include basic types like bool, string, integers and floats.

Uploaded by

rakesh
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 6

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) {}

// multiple parameters of the same type


func functionName(param1, param2 int) {}
Functions (cont) Functions (cont)
// return type declaration
func functionName() int { Variadic Functions
return 42
} func main() {
fmt.Println(adder(1, 2, 3)) // 6
// Can return multiple values at once fmt.Println(adder(9, 9)) // 18
func returnMulti() (int, string) {
return 42, "foobar" nums := []int{10, 20, 30}
} fmt.Println(adder(nums...)) // 60
var x, str = returnMulti() }

// 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 }

If // As with for and if, an assignment statement before the


// switch value is allowed
func main() { switch os := runtime.GOOS; os {
// Basic one case "darwin": ...
if x > 0 { }
return x
} else {
return -x
} Arrays, Slices, Ranges
// You can put one statement before the condition
if a := b + c; a < 42 { Arrays
return a var a [10]int // int array with length 10. Length is part of type!
} else { a[3] = 42 // set elements
return a - 42 i := a[3] // read elements
}
// declare and initialize
// Type assertion inside if var a = [2]int{1, 2}
var val interface{} a := [2]int{1, 2} //shorthand
val = "foo" a := [...]int{1, 2} // elipsis -> Compiler figures out array length
if str, ok := val.(string); ok {
fmt.Println(str)
}
} Slices
var a []int // a slice – like an array, but length is unspecified
var a = []int {1, 2, 3, 4} // declare and initialize a slice
Loops // (backed by given array implicitly)
a := []int{1, 2, 3, 4} // shorthand
// There's only `for`. No `while`, no `until` chars := []string{0:"a", 2:"c", 1:"b"} // ["a", "b", "c"]
for i := 1; i < 10; i++ {
} var b = a[lo:hi] // creates a slice (view of the array) from
for ; i < 10; { // while loop // index lo to hi-1
} var b = a[1:4] // slice from index 1 to 3
for i < 10 { // can omit semicolons if there's only a condition var b = a[:3] // missing low index implies 0
} var b = a[3:] // missing high index implies len(a)
for { // can omit the condition ~ while (true)
} // create a slice with make
a = make([]byte, 5, 5) // first arg length, second capacity
a = make([]byte, 5) // capacity is optional
Arrays, Slices, Ranges (cont) Structs
// create a slice from an array There are no classes, only structs. Structs can have methods.
x := [3]string{"Лайка", "Белка", "Стрелка"}
s := x[:] // a slice referencing the storage of x // A struct is a type. It's also a collection of fields

// 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

// The type of a pointer to a Vertex is *Vertex

var s *Vertex = new(Vertex) // create ptr to a new struct instance


Errors (cont)
Interfaces
// interface declaration A function that might return an error:
type Awesomizer interface {
Awesomize() string func doStuff() (int, error) {
} }

// types do *not* declare to implement interfaces func main() {


type Foo struct {} result, error := doStuff()
if (error != nil) {
// instead, types implicitly satisfy an interface if they implement // handle error
all required methods } else {
func (foo Foo) Awesomize() string { // all is good, use result
return "Awesome!" }
} }

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(...) }

// Field name of an embedded type is its type name ('Logger' here)


var logger *log.Logger = server.Logger

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:

type error interface {


Error() string
}
Channels Channels (cont)
ch := make(chan int) // create a channel of type int c <- "Hello, Panic!"
ch <- 42 // Send a value to the channel ch. // panic: send on closed channel
v := <-ch // Receive a value from ch

// 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)

// Read from channel and test if it has been closed


// If ok is false, channel has been closed
v, ok := <-ch Snippets

// Read from channel until it is closed


for i := range ch { HTTP Server
fmt.Println(i) package main
}
import (
// select blocks on multiple channel operations. "fmt"
// If one unblocks, the corresponding case is executed "net/http"
func doStuff(channelOut, channelIn chan int) { )
select {
case channelOut <- 42: // define a type for the response
fmt.Println("We could write to channelOut!") type Hello struct{}
case x := <- channelIn:
fmt.Println("We could read from channelIn") // let that type implement the ServeHTTP method (defined in
case <-time.After(time.Second * 1): // interface http.Handler)
fmt.Println("timeout") func (h Hello) ServeHTTP(w http.ResponseWriter, r *http.Request) {
} fmt.Fprint(w, "Hello!")
} }

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!

// III. A send to a closed channel panics


var c = make(chan string, 1)
c <- "Hello, World!"
close(c)

You might also like