Skip to content

Instantly share code, notes, and snippets.

@sachinsmc
Created June 24, 2019 11:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sachinsmc/c2098141af36e20104400c351a46cc5c to your computer and use it in GitHub Desktop.
Save sachinsmc/c2098141af36e20104400c351a46cc5c to your computer and use it in GitHub Desktop.
learn go cheat.sh
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