Created
June 24, 2019 11:33
-
-
Save sachinsmc/c2098141af36e20104400c351a46cc5c to your computer and use it in GitHub Desktop.
learn go cheat.sh
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import( | |
"fmt" | |
m "math" | |
"os" | |
"io/ioutil" | |
"net/http" | |
"strconv" | |
) | |
func main() { | |
fmt.Println("start where you left off other day.") | |
beyondHello() | |
} | |
// Functions have parameters in parentheses. | |
// If there are no parameters, empty parentheses are still required. | |
func beyondHello() { | |
var x int // Variable declaration. Variables must be declared before use. | |
x = 3 // Variable assignment. | |
// "Short" declarations use := to infer the type, declare, and assign. | |
y := 4 | |
sum, prod := learnMultiple(x, y) // Function returns two values. | |
fmt.Println("sum:", sum, "prod:", prod) // Simple output. | |
learnTypes() // < y minutes, learn more! | |
} | |
/* <- multiline comment | |
Functions can have parameters and (multiple!) return values. | |
Here `x`, `y` are the arguments and `sum`, `prod` is the signature (what's returned). | |
Note that `x` and `sum` receive the type `int`. | |
*/ | |
func learnMultiple(x, y int) (sum, prod int) { | |
return x + y, x * y // Return two values. | |
} | |
// Some built-in types and literals. | |
func learnTypes() { | |
// Short declaration usually gives you what you want. | |
str := "Learn Go!" // string type. | |
s2 := `A "raw" string literal | |
can include line breaks.` // Same string type. | |
// Non-ASCII literal. Go source is UTF-8. | |
g := 'Σ' // rune type, an alias for int32, holds a unicode code point. | |
f := 3.14195 // float64, an IEEE-754 64-bit floating point number. | |
c := 3 + 4i // complex128, represented internally with two float64's. | |
// var syntax with initializers. | |
var u uint = 7 // Unsigned, but implementation dependent size as with int. | |
var pi float32 = 22. / 7 | |
// Conversion syntax with a short declaration. | |
n := byte('\n') // byte is an alias for uint8. | |
// Arrays have size fixed at compile time. | |
var a4 [4]int // An array of 4 ints, initialized to all 0. | |
a5 := [...]int{3, 1, 5, 10, 100} // An array initialized with a fixed size of five | |
// elements, with values 3, 1, 5, 10, and 100. | |
// Slices have dynamic size. Arrays and slices each have advantages | |
// but use cases for slices are much more common. | |
s3 := []int{4, 5, 9} // Compare to a5. No ellipsis here. | |
s4 := make([]int, 4) // Allocates slice of 4 ints, initialized to all 0. | |
var d2 [][]float64 // Declaration only, nothing allocated here. | |
bs := []byte("a slice") // Type conversion syntax. | |
// Because they are dynamic, slices can be appended to on-demand. | |
// To append elements to a slice, the built-in append() function is used. | |
// First argument is a slice to which we are appending. Commonly, | |
// the array variable is updated in place, as in example below. | |
s := []int{1, 2, 3} // Result is a slice of length 3. | |
s = append(s, 4, 5, 6) // Added 3 elements. Slice now has length of 6. | |
fmt.Println(s) // Updated slice is now [1 2 3 4 5 6] | |
// To append another slice, instead of list of atomic elements we can | |
// pass a reference to a slice or a slice literal like this, with a | |
// trailing ellipsis, meaning take a slice and unpack its elements, | |
// appending them to slice s. | |
s = append(s, []int{7, 8, 9}...) // Second argument is a slice literal. | |
fmt.Println(s) // Updated slice is now [1 2 3 4 5 6 7 8 9] | |
p, q := learnMemory() // Declares p, q to be type pointer to int. | |
fmt.Println(*p, *q) // * follows a pointer. This prints two ints. | |
// Maps are a dynamically growable associative array type, like the | |
// hash or dictionary types of some other languages. | |
m := map[string]int{"three": 3, "four": 4} | |
m["one"] = 1 | |
// Unused variables are an error in Go. | |
// The underscore lets you "use" a variable but discard its value. | |
_, _, _, _, _, _, _, _, _, _ = str, s2, g, f, u, pi, n, a5, s4, bs | |
// Usually you use it to ignore one of the return values of a function | |
// For example, in a quick and dirty script you might ignore the | |
// error value returned from os.Create, and expect that the file | |
// will always be created. | |
file, _ := os.Create("output.txt") | |
fmt.Fprint(file, "This is how you write to a file, by the way") | |
file.Close() | |
// Output of course counts as using a variable. | |
fmt.Println(s, c, a4, s3, d2, m) | |
learnFlowControl() // Back in the flow. | |
} | |
// Go is fully garbage collected. It has pointers but no pointer arithmetic. | |
// You can make a mistake with a nil pointer, but not by incrementing a pointer. | |
func learnMemory() (p, q *int) { | |
// Named return values p and q have type pointer to int. | |
p = new(int) // Built-in function new allocates memory. | |
// The allocated int is initialized to 0, p is no longer nil. | |
s := make([]int, 20) // Allocate 20 ints as a single block of memory. | |
s[3] = 7 // Assign one of them. | |
r := -2 // Declare another local variable. | |
return &s[3], &r // & takes the address of an object. | |
} | |
func learnFlowControl() { | |
if true { | |
fmt.Println("no parentheses required in if condition") | |
} | |
if false { | |
} else { | |
} | |
x := 42.0 | |
switch x { | |
case 1: | |
case 42: | |
// cases don't fall through without fallthrough | |
case 43: | |
// Unreachable | |
default: | |
// Dafault case is optional | |
} | |
// like if, for doesn't require parenthesis | |
for i := 0; i < 3; i++ { | |
fmt.Println("Iteration : ", x) | |
} | |
// GO doesn't have while do or any other loops | |
// for { // Infinite loop | |
// continue | |
// break | |
// } | |
// using range to iterate over an array, a slice, a string, a map or a channel | |
// range returns one value(channel) or two vlaues (array, slice, sting and map) | |
for key, value := range map[string]int{"one":1, "two":2, "three":3} { | |
fmt.Printf("key=%s , value=%d]\n", key, value) | |
} | |
for _, name := range []string{"Bob", "Bill", "Joe"} { | |
fmt.Printf("Hello, %s\n", name) | |
} | |
if y:= expensiveComputation(); y>x{ | |
x=y | |
} | |
// function literals are clousures | |
xBig := func () bool { | |
return x>10000 | |
} | |
x = 99999 | |
fmt.Println("xBig : ", xBig()) | |
x = 1.3e3 | |
fmt.Println("xBig : ", xBig(), x) | |
fmt.Println("Add + double two numbers : ", | |
func(a, b int) int { | |
return (a+b) * 2 | |
}(10, 2)) | |
goto love | |
love: | |
learnFunctionFactory() // funct returning func | |
learnDefer() | |
learnInterfaces() | |
} | |
func expensiveComputation() float64 { | |
return m.Exp(10) | |
} | |
func learnFunctionFactory() { | |
fmt.Println(sentenceFactory("summer")("A bueatiful", "day")) | |
} | |
func sentenceFactory(mystring string) func (before, after string) string { | |
return func (before, after string) string{ | |
return fmt.Sprintf("%s %s %s", before, mystring,after) | |
} | |
} | |
// defer statement put off the statement for later time, until surrounding function returns | |
func learnDefer() (ok bool) { | |
// A defer statement pushes a function call onto a list. The list of saved | |
// calls is executed AFTER surrrounding function returns | |
defer fmt.Println("deferred statements execute in reverse (LIFO) order.") | |
defer fmt.Println("\n This line is being printed first because") | |
// defer is commonly used to dicsonnect db/close a file, so the function closing | |
// files stays close to the function opening the file | |
return true | |
} | |
// Define Stringer as interface type with one method, String | |
type Stringer interface { | |
String() string | |
} | |
// Define pair as struct with two fields, ints names x and y. | |
type pair struct { | |
x, y int | |
} | |
// Define a method on pair, Pair now implements Stringer becaue Pair has defined all the methods in the interface. | |
func (p pair) String() string { // p is called the receiver | |
// Spintf is another public funcitonin package fmt | |
// Dot syntax references fileds of p. | |
return fmt.Sprintf("(%d, %d)", p.x, p.y) | |
} | |
func learnInterfaces() { | |
// intialize p to this struct | |
p := pair{3, 4} | |
fmt.Println(p.String()) | |
var i Stringer | |
i = p | |
fmt.Println(i.String()) | |
fmt.Println(p) | |
fmt.Println(i) | |
learnVariadicParams("great","learning", "here") | |
} | |
func learnVariadicParams(myStrings...interface{}) { | |
for _, param := range myStrings { | |
fmt.Println("param:", param) | |
} | |
fmt.Println("params:", fmt.Sprintln(myStrings...)) | |
learnErrorHandling() | |
} | |
func learnErrorHandling() { | |
// ", ok" idioms used to tell if something worked or not | |
m := map[int]string{3: "three", 4: "four"} | |
if x, ok := m[1]; !ok { | |
fmt.Println("no one there") | |
} else { | |
fmt.Print(x) | |
} | |
if _, err := strconv.Atoi("non-int"); err != nil { | |
fmt.Println(err) | |
} | |
learnConcurrency() | |
} | |
func inc(i int, c chan int) { | |
c <- i+1 // <- is a send operator when a channel appears on the left | |
} | |
// we'll use inc to increment some numbers concurrently | |
func learnConcurrency() { | |
// make allocates and intializes slices, maps and channel. | |
c := make(chan int) | |
// Start three concurrenyt goroutines. Numbers will be incremented concurrently | |
go inc(0, c) // go statement starts a goroutine. | |
go inc(10, c) | |
go inc(-805, c) | |
fmt.Println(<-c, <-c, <-c) | |
cs := make(chan string) | |
ccs := make(chan chan string) | |
go func () { c<-84 }() | |
go func () { cs<-"wordy"}() | |
select { | |
case i := <-c: // received value can be assigned to a variable | |
fmt.Printf("it's a %T", i) | |
case <-cs:// or the value received can be discarded. | |
fmt.Println("it's a string") | |
case <- ccs: // empty chnnedl not ready for communication | |
fmt.Println("didn't happen.") | |
} | |
learnWebProgramming() | |
} | |
func learnWebProgramming() { | |
// First parameter of ListerAndServe is TCP address to listen to | |
// second param is an interface, specifically http.handler | |
go func () { | |
err := http.ListenAndServe(":8080", pair{}) | |
fmt.Println(err) | |
}() | |
requestServer() | |
} | |
func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) { | |
w.Write([]byte("You learned GO in Y minutes!")) | |
} | |
func requestServer() { | |
resp, err := http.Get("http://localhost:8080") | |
fmt.Println(err) | |
defer resp.Body.Close() | |
body, err := ioutil.ReadAll(resp.Body) | |
fmt.Printf("\nWebserver said : `%s`", string(body)) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment