mirror of
https://github.com/chubin/cheat.sheets
synced 2024-11-01 21:40:24 +00:00
moved go/ to _go/
This commit is contained in:
parent
c6b0b5c065
commit
ee44275862
12
sheets/_go/Arrays
Normal file
12
sheets/_go/Arrays
Normal file
@ -0,0 +1,12 @@
|
||||
// gives you the length of an array/a slice
|
||||
// It's a built-in function, not a attribute/method on the array.
|
||||
len(a)
|
||||
|
||||
var a [10]int // declare an int array with length 10. Array length is part of the type!
|
||||
a[3] = 42 // set elements
|
||||
i := a[3] // read elements
|
||||
|
||||
// declare and initialize
|
||||
var a = [2]int{1, 2}
|
||||
a := [2]int{1, 2} //shorthand
|
||||
a := [...]int{1, 2} // elipsis -> Compiler figures out array length
|
26
sheets/_go/Axioms
Normal file
26
sheets/_go/Axioms
Normal file
@ -0,0 +1,26 @@
|
||||
// - A send to a nil channel blocks forever
|
||||
var c chan string
|
||||
c <- "Hello, World!"
|
||||
// fatal error: all goroutines are asleep - deadlock!
|
||||
|
||||
// - A receive from a nil channel blocks forever
|
||||
var c chan string
|
||||
fmt.Println(<-c)
|
||||
// fatal error: all goroutines are asleep - deadlock!
|
||||
|
||||
// - A send to a closed channel panics
|
||||
var c = make(chan string, 1)
|
||||
c <- "Hello, World!"
|
||||
close(c)
|
||||
c <- "Hello, Panic!"
|
||||
// panic: send on closed channel
|
||||
|
||||
// - A receive from a closed channel returns the zero value immediately
|
||||
var c = make(chan int, 2)
|
||||
c <- 1
|
||||
c <- 2
|
||||
close(c)
|
||||
for i := 0; i < 3; i++ {
|
||||
fmt.Printf("%d ", <-c)
|
||||
}
|
||||
// 1 2 0
|
36
sheets/_go/Channels
Normal file
36
sheets/_go/Channels
Normal file
@ -0,0 +1,36 @@
|
||||
ch := make(chan int) // create a channel of type int
|
||||
ch <- 42 // Send a value to the channel ch.
|
||||
v := <-ch // Receive a value from ch
|
||||
|
||||
// Create a buffered channel.
|
||||
// Writing to a buffered channels does not block
|
||||
// if less than <buffer size> unread values have been written.
|
||||
ch := make(chan int, 100)
|
||||
// Non-buffered channels block.
|
||||
// Read blocks when no value is available,
|
||||
// write blocks if a value already has been written but not read.
|
||||
|
||||
close(ch) // closes the channel (only sender should close)
|
||||
|
||||
// read from channel and test if it has been closed
|
||||
v, ok := <-ch
|
||||
// if ok is false, channel has been closed
|
||||
|
||||
// Read from channel until it is closed
|
||||
for i := range ch {
|
||||
fmt.Println(i)
|
||||
}
|
||||
|
||||
// select blocks on multiple channel operations,
|
||||
// if one unblocks, the corresponding case is executed
|
||||
func doStuff(channelOut, channelIn chan int) {
|
||||
select {
|
||||
case channelOut <- 42:
|
||||
fmt.Println("We could write to channelOut!")
|
||||
case x := <- channelIn:
|
||||
fmt.Println("We could read from channelIn")
|
||||
case <-time.After(time.Second * 1):
|
||||
fmt.Println("timeout")
|
||||
}
|
||||
}
|
||||
|
7
sheets/_go/Declarations
Normal file
7
sheets/_go/Declarations
Normal file
@ -0,0 +1,7 @@
|
||||
// Type goes after identifier!
|
||||
var foo int // declaration without initialization
|
||||
var foo int = 42 // declaration with initialization
|
||||
var foo, bar int = 42, 1302 // declare and init multiple vars at once
|
||||
var foo = 42 // type omitted, will be inferred
|
||||
foo := 42 // shorthand, only in func bodies, omit var keyword, type is always implicit
|
||||
const constant = "This is a constant"
|
23
sheets/_go/Embedding
Normal file
23
sheets/_go/Embedding
Normal file
@ -0,0 +1,23 @@
|
||||
// There is no subclassing in Go. Instead, there is interface and struct embedding.
|
||||
|
||||
// ReadWriter implementations must satisfy both Reader and Writer
|
||||
type ReadWriter interface {
|
||||
Reader
|
||||
Writer
|
||||
}
|
||||
|
||||
// Server exposes all the methods that Logger has
|
||||
type Server struct {
|
||||
Host string
|
||||
Port int
|
||||
*log.Logger
|
||||
}
|
||||
|
||||
// initialize the embedded type the usual way
|
||||
server := &Server{"localhost", 80, log.New(...)}
|
||||
|
||||
// methods implemented on the embedded struct are passed through
|
||||
server.Log(...) // calls server.Logger.Log(...)
|
||||
|
||||
// the field name of the embedded type is its type name (in this case Logger)
|
||||
var logger *log.Logger = server.Logger
|
19
sheets/_go/Errors
Normal file
19
sheets/_go/Errors
Normal file
@ -0,0 +1,19 @@
|
||||
// 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
|
||||
}
|
||||
//
|
||||
// A function that might return an error:
|
||||
func doStuff() (int, error) {
|
||||
}
|
||||
//
|
||||
func main() {
|
||||
result, error := doStuff()
|
||||
if (error != nil) {
|
||||
// handle error
|
||||
} else {
|
||||
// all is good, use result
|
||||
}
|
||||
}
|
13
sheets/_go/Interfaces
Normal file
13
sheets/_go/Interfaces
Normal file
@ -0,0 +1,13 @@
|
||||
// interface declaration
|
||||
type Awesomizer interface {
|
||||
Awesomize() string
|
||||
}
|
||||
//
|
||||
// types do *not* declare to implement interfaces
|
||||
type Foo struct {}
|
||||
//
|
||||
// instead, types implicitly satisfy an interface
|
||||
// if they implement all required methods
|
||||
func (foo Foo) Awesomize() string {
|
||||
return "Awesome!"
|
||||
}
|
16
sheets/_go/Maps
Normal file
16
sheets/_go/Maps
Normal file
@ -0,0 +1,16 @@
|
||||
var m map[string]int
|
||||
m = make(map[string]int)
|
||||
m["key"] = 42
|
||||
fmt.Println(m["key"])
|
||||
|
||||
// delete key from a map
|
||||
delete(m, "key")
|
||||
|
||||
// test if key "key" is present and retrieve it, if so
|
||||
elem, ok := m["key"]
|
||||
|
||||
// map literal
|
||||
var m = map[string]Vertex{
|
||||
"Bell Labs": {40.68433, -74.39967},
|
||||
"Google": {37.42202, -122.08408},
|
||||
}
|
40
sheets/_go/Operators
Normal file
40
sheets/_go/Operators
Normal file
@ -0,0 +1,40 @@
|
||||
// ### Arithmetic
|
||||
// |Operator|Description|
|
||||
// |--------|-----------|
|
||||
// |`+` |addition |
|
||||
// |`-` |subtraction|
|
||||
// |`*` |multiplication|
|
||||
// |`/` |quotient |
|
||||
// |`%` |remainder |
|
||||
// |`&` |bitwise and|
|
||||
// |`|` |bitwise or |
|
||||
// |`^` |bitwise xor|
|
||||
// |`&^` |bit clear (and not)|
|
||||
// |`<<` |left shift |
|
||||
// |`>>` |right shift|
|
||||
//
|
||||
// ### Comparison
|
||||
// |Operator|Description|
|
||||
// |--------|-----------|
|
||||
// |`==` |equal |
|
||||
// |`!=` |not equal |
|
||||
// |`<` |less than |
|
||||
// |`<=` |less than or equal|
|
||||
// |`>` |greater than|
|
||||
// |`>=` |greater than or equal|
|
||||
//
|
||||
// ### Logical
|
||||
// |Operator|Description|
|
||||
// |--------|-----------|
|
||||
// |`&&` |logical and|
|
||||
// |`||` |logical or |
|
||||
// |`!` |logical not|
|
||||
//
|
||||
// ### Other
|
||||
// |Operator|Description|
|
||||
// |--------|-----------|
|
||||
// |`&` |address of / create pointer|
|
||||
// |`*` |dereference pointer|
|
||||
// |`<-` |send / receive operator (see 'Channels' below)|
|
||||
|
||||
|
7
sheets/_go/Pointers
Normal file
7
sheets/_go/Pointers
Normal file
@ -0,0 +1,7 @@
|
||||
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
|
||||
// new creates a pointer to a new struct instance
|
||||
var s *Vertex = new(Vertex)
|
38
sheets/_go/Structs
Normal file
38
sheets/_go/Structs
Normal file
@ -0,0 +1,38 @@
|
||||
// There are no classes, only structs. Structs can have methods.
|
||||
// A struct is a type. It's also a collection of fields
|
||||
|
||||
// Declaration
|
||||
type Vertex struct {
|
||||
X, Y int
|
||||
}
|
||||
|
||||
// Creating
|
||||
var v = Vertex{1, 2}
|
||||
var v = Vertex{X: 1, Y: 2} // Creates a struct by defining values with keys
|
||||
var v = []Vertex{{1,2},{5,2},{5,5}} // Initialize a slice of structs
|
||||
|
||||
// Accessing members
|
||||
v.X = 4
|
||||
|
||||
// You can declare methods on structs. The struct you want to declare the
|
||||
// method on (the receiving type) comes between the the func keyword and
|
||||
// the method name. The struct is copied on each method call(!)
|
||||
func (v Vertex) Abs() float64 {
|
||||
return math.Sqrt(v.X*v.X + v.Y*v.Y)
|
||||
}
|
||||
|
||||
// Call method
|
||||
v.Abs()
|
||||
|
||||
// For mutating methods, you need to use a pointer (see below) to the 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
|
||||
}
|
||||
|
||||
// **Anonymous structs:**
|
||||
// Cheaper and safer than using `map[string]interface{}`.
|
||||
point := struct {
|
||||
X, Y int
|
||||
}{1, 2}
|
9
sheets/_go/for
Normal file
9
sheets/_go/for
Normal file
@ -0,0 +1,9 @@
|
||||
// There's only `for`, no `while`, no `until`
|
||||
for i := 1; i < 10; i++ {
|
||||
}
|
||||
for ; i < 10; { // while - loop
|
||||
}
|
||||
for i < 10 { // you can omit semicolons if there is only a condition
|
||||
}
|
||||
for { // you can omit the condition ~ while (true)
|
||||
}
|
84
sheets/_go/func
Normal file
84
sheets/_go/func
Normal file
@ -0,0 +1,84 @@
|
||||
// ### Functions
|
||||
// a simple function
|
||||
func functionName() {}
|
||||
|
||||
// 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) {}
|
||||
|
||||
// return type declaration
|
||||
func functionName() int {
|
||||
return 42
|
||||
}
|
||||
|
||||
// Can return multiple values at once
|
||||
func returnMulti() (int, string) {
|
||||
return 42, "foobar"
|
||||
}
|
||||
var x, str = returnMulti()
|
||||
|
||||
// Return multiple named results simply by return
|
||||
func returnMulti2() (n int, s string) {
|
||||
n = 42
|
||||
s = "foobar"
|
||||
// n and s will be returned
|
||||
return
|
||||
}
|
||||
var x, str = returnMulti2()
|
||||
|
||||
// ### Functions As Values And Closures
|
||||
func main() {
|
||||
// assign a function to a name
|
||||
add := func(a, b int) int {
|
||||
return a + b
|
||||
}
|
||||
// use the name to call the function
|
||||
fmt.Println(add(3, 4))
|
||||
}
|
||||
|
||||
// Closures, lexically scoped: Functions can access values that were
|
||||
// in scope when defining the function
|
||||
func scope() func() int{
|
||||
outer_var := 2
|
||||
foo := func() int { return outer_var}
|
||||
return foo
|
||||
}
|
||||
|
||||
func another_scope() func() int{
|
||||
// won't compile because outer_var and foo not defined in this scope
|
||||
outer_var = 444
|
||||
return foo
|
||||
}
|
||||
|
||||
|
||||
// Closures: don't mutate outer vars, instead redefine them!
|
||||
func outer() (func() int, int) {
|
||||
outer_var := 2
|
||||
inner := func() int {
|
||||
outer_var += 99 // attempt to mutate outer_var from outer scope
|
||||
return outer_var // => 101 (but outer_var is a newly redefined
|
||||
// variable visible only inside inner)
|
||||
}
|
||||
return inner, outer_var // => 101, 2 (outer_var is still 2, not mutated by foo!)
|
||||
}
|
||||
|
||||
// ### Variadic Functions
|
||||
func main() {
|
||||
fmt.Println(adder(1, 2, 3)) // 6
|
||||
fmt.Println(adder(9, 9)) // 18
|
||||
|
||||
nums := []int{10, 20, 30}
|
||||
fmt.Println(adder(nums...)) // 60
|
||||
}
|
||||
// By using ... before the type name of the last parameter you can indicate that it takes zero or more of those parameters.
|
||||
// The function is invoked like any other function except we can pass as many arguments as we want.
|
||||
func adder(args ...int) int {
|
||||
total := 0
|
||||
for _, v := range args { // Iterates over the arguments whatever the number.
|
||||
total += v
|
||||
}
|
||||
return total
|
||||
}
|
||||
|
16
sheets/_go/go
Normal file
16
sheets/_go/go
Normal file
@ -0,0 +1,16 @@
|
||||
// Goroutines are lightweight threads (managed by Go, not OS threads).
|
||||
// `go f(a, b)` starts a new goroutine which runs `f` (given `f` is a function).
|
||||
//
|
||||
// just a function (which can be later started as a goroutine)
|
||||
func doStuff(s string) {
|
||||
}
|
||||
//
|
||||
func main() {
|
||||
// using a named function in a goroutine
|
||||
go doStuff("foobar")
|
||||
|
||||
// using an anonymous inner function in a goroutine
|
||||
go func (x int) {
|
||||
// function body goes here
|
||||
}(42)
|
||||
}
|
11
sheets/_go/hello
Normal file
11
sheets/_go/hello
Normal file
@ -0,0 +1,11 @@
|
||||
// file: hello.go
|
||||
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
fmt.Println("Hello Go")
|
||||
}
|
||||
|
||||
// to run: $ go run hello.go
|
25
sheets/_go/http
Normal file
25
sheets/_go/http
Normal file
@ -0,0 +1,25 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// define a type for the response
|
||||
type Hello struct{}
|
||||
|
||||
// let that type implement the ServeHTTP method (defined in interface http.Handler)
|
||||
func (h Hello) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprint(w, "Hello!")
|
||||
}
|
||||
|
||||
func main() {
|
||||
var h Hello
|
||||
http.ListenAndServe("localhost:4000", h)
|
||||
}
|
||||
|
||||
// Here's the method signature of http.ServeHTTP:
|
||||
// type Handler interface {
|
||||
// ServeHTTP(w http.ResponseWriter, r *http.Request)
|
||||
// }
|
||||
|
23
sheets/_go/if
Normal file
23
sheets/_go/if
Normal file
@ -0,0 +1,23 @@
|
||||
func main() {
|
||||
// Basic one
|
||||
if x > 0 {
|
||||
return x
|
||||
} else {
|
||||
return -x
|
||||
}
|
||||
|
||||
// You can put one statement before the condition
|
||||
if a := b + c; a < 42 {
|
||||
return a
|
||||
} else {
|
||||
return a - 42
|
||||
}
|
||||
|
||||
// Type assertion inside if
|
||||
var val interface{}
|
||||
val = "foo"
|
||||
if str, ok := val.(string); ok {
|
||||
fmt.Println(str)
|
||||
}
|
||||
}
|
||||
|
8
sheets/_go/packages
Normal file
8
sheets/_go/packages
Normal file
@ -0,0 +1,8 @@
|
||||
// ## Packages
|
||||
// * Package declaration at top of every source file
|
||||
// * Executables are in package `main`
|
||||
// * Convention: package name == last name of import path (import path `math/rand` => package `rand`)
|
||||
// * Upper case identifier: exported (visible from other packages)
|
||||
// * Lower case identifier: private (not visible from other packages)
|
||||
|
||||
|
12
sheets/_go/print
Normal file
12
sheets/_go/print
Normal file
@ -0,0 +1,12 @@
|
||||
fmt.Println("Hello, 你好, नमस्ते, Привет, ᎣᏏᏲ") // basic print, plus newline
|
||||
p := struct { X, Y int }{ 17, 2 }
|
||||
fmt.Println( "My point:", p, "x coord=", p.X ) // print structs, ints, etc
|
||||
s := fmt.Sprintln( "My point:", p, "x coord=", p.X ) // print to string variable
|
||||
|
||||
fmt.Printf("%d hex:%x bin:%b fp:%f sci:%e",17,17,17,17.0,17.0) // c-ish format
|
||||
s2 := fmt.Sprintf( "%d %f", 17, 17.0 ) // formatted print to string variable
|
||||
|
||||
hellomsg := `
|
||||
"Hello" in Chinese is 你好 ('Ni Hao')
|
||||
"Hello" in Hindi is नमस्ते ('Namaste')
|
||||
` // multi-line string literal, using back-tick at beginning and end
|
20
sheets/_go/range
Normal file
20
sheets/_go/range
Normal file
@ -0,0 +1,20 @@
|
||||
// loop over an array/a slice
|
||||
for i, e := range a {
|
||||
// i is the index, e the element
|
||||
}
|
||||
|
||||
// if you only need e:
|
||||
for _, e := range a {
|
||||
// e is the element
|
||||
}
|
||||
|
||||
// ...and if you only need the index
|
||||
for i := range a {
|
||||
}
|
||||
|
||||
// In Go pre-1.4, you'll get a compiler error if you're not using i and e.
|
||||
// Go 1.4 introduced a variable-free form, so that you can do this
|
||||
for range time.Tick(time.Second) {
|
||||
// do it once a sec
|
||||
}
|
||||
|
19
sheets/_go/slices
Normal file
19
sheets/_go/slices
Normal file
@ -0,0 +1,19 @@
|
||||
var a []int // declare a slice - similar to an array, but length is unspecified
|
||||
var a = []int {1, 2, 3, 4} // declare and initialize a slice (backed by the array given implicitly)
|
||||
a := []int{1, 2, 3, 4} // shorthand
|
||||
chars := []string{0:"a", 2:"c", 1: "b"} // ["a", "b", "c"]
|
||||
|
||||
var b = a[lo:hi] // creates a slice (view of the array) from index lo to hi-1
|
||||
var b = a[1:4] // slice from index 1 to 3
|
||||
var b = a[:3] // missing low index implies 0
|
||||
var b = a[3:] // missing high index implies len(a)
|
||||
a = append(a,17,3) // append items to slice a
|
||||
c := append(a,b...) // concatenate slices a and b
|
||||
|
||||
// create a slice with make
|
||||
a = make([]byte, 5, 5) // first arg length, second capacity
|
||||
a = make([]byte, 5) // capacity is optional
|
||||
|
||||
// create a slice from an array
|
||||
x := [3]string{"Лайка", "Белка", "Стрелка"}
|
||||
s := x[:] // a slice referencing the storage of x
|
27
sheets/_go/switch
Normal file
27
sheets/_go/switch
Normal file
@ -0,0 +1,27 @@
|
||||
// switch statement
|
||||
switch operatingSystem {
|
||||
case "darwin":
|
||||
fmt.Println("Mac OS Hipster")
|
||||
// cases break automatically, no fallthrough by default
|
||||
case "linux":
|
||||
fmt.Println("Linux Geek")
|
||||
default:
|
||||
// Windows, BSD, ...
|
||||
fmt.Println("Other")
|
||||
}
|
||||
|
||||
// as with for and if, you can have an assignment statement before the switch value
|
||||
switch os := runtime.GOOS; os {
|
||||
case "darwin": ...
|
||||
}
|
||||
|
||||
// you can also make comparisons in switch cases
|
||||
number := 42
|
||||
switch {
|
||||
case number < 42:
|
||||
fmt.Println("Smaller")
|
||||
case number == 42:
|
||||
fmt.Println("Equal")
|
||||
case number > 42:
|
||||
fmt.Println("Greater")
|
||||
}
|
29
sheets/_go/types
Normal file
29
sheets/_go/types
Normal file
@ -0,0 +1,29 @@
|
||||
// ## Built-in Types
|
||||
bool
|
||||
|
||||
string
|
||||
|
||||
int int8 int16 int32 int64
|
||||
uint uint8 uint16 uint32 uint64 uintptr
|
||||
|
||||
byte // alias for uint8
|
||||
|
||||
rune // alias for int32 ~= a character (Unicode code point) - very Viking
|
||||
|
||||
float32 float64
|
||||
|
||||
complex64 complex128
|
||||
|
||||
// ## Type Conversions
|
||||
|
||||
var i int = 42
|
||||
var f float64 = float64(i)
|
||||
var u uint = uint(f)
|
||||
|
||||
// alternative syntax
|
||||
i := 42
|
||||
f := float64(i)
|
||||
u := uint(f)
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user