"Go is for the essentialist"
- Language
- Libraries
- Tooling
Go programs can be of two types - commands and packages. Commands usually have a main function where execution starts.
go build
- builds the executable in the same directorygo install
- builds the executable and puts it in the $GOtripleATH/bingo run
- runs the program
go fmt
is the standard way to format your code.godoc -http=:8080
is how you can serve up a local copy of docsgodoc.org
for all the documentation
var greeting string = "Hello world"
You can drop the string here since greeting is being initialized - go can infer that it is of type string. So
var greeting = "Hello world"
var d, e, f = 1, 2.0, "hello"
Drop var
and use :=
course := "Essential Go"
x, y, z := 1, 3, 2
In go, any identifier that starts with an uppercase is public and available for use by other packages. Example: fmt.Println
In this example, Version and author are global variables
package main
var Version = "0.0.1"
var author = "@anant90"
func main() {
...
}
You can also group variables or constants together:
var (
author = "@anant90"
Version = "0.0.1"
)
const (
CCVisa = "Visa"
)
if true == true {
fmt.Println("true is true")
} else {
fmt.Println("true is false")
}
for i := 0; i < 20; i++ {
fmt.Println("Go!")
}
for {
fmt.Println("Infinite Loops")
break
}
j := true
for j {
fmt.Println("This should happen only once")
j = false
}
func double(n int) int {
return n + n
}
func function_name(argument type) return_type {}
func parseName (name string) (first, last string) {
parsed := string.Split(name, " ")
return parsed[0], parsed[1]
}
use _
in function calls to discard a result.
first, _ := parseName("Anant Jain")
Anonymous function:
greet := func(name string) {
fmt.Println("Hello", name)
}
greet("Anant")
func triple( n*int) {
*n = *n * 3
}
num := 5
triple(&num)
fmt.Println(num)
package main
import (
"flag"
"fmt"
"log"
"net/http"
)
var port int
func main() {
// We will get the port through a cli flag
flag.IntVar(&port, "port", 3000, "The port to run the file server on")
flag.Parse()
fmt.Printf("Serving files on localhost:%v\n", port)
err := ServeStatic(port)
if err != nil {
log.Fatalln(err)
}
}
func ServeStatic(port int) error {
host := fmt.Sprintf("localhost:%v", port)
return http.ListenAndServe(host, http.FileServer(http.Dir(".")))
}
var nums [5]int
fmt.Println("empty:", nums)
nums[4] = 100
Slices are abstractions on top of arrays
ints := []int{1,2,3,4,5}
ints = append(ints, 6)
ints[:2]
ints[4:]
ints [2:4]
for i, val := range ints {
fmt.Println(i, val)
}
Maps can be initialized with the make builtin
age := male(map[string]int)
age["jeremy"] = 24
age["jordie"] = 21
age["josh"] = 27
fmt.Println(age)
delete(age, "jeremy")
m := map[string] int {
"jeremy": 24,
"jordie": 21,
}
for n, a := range m {
fmt.Prinf("%v is %v years old", n ,a)
}
Specify interface as type when you do not know the return type - it may act like the void
type
panic
is another way to tell go to stop executing. Discouraged for use in libraries. It is like throwing an exception.
Check out how to define a type as well
c["name"].(string)
explicitly tries to convert c["name"]
to string
type
// To make use of some of our collections knowledge, we will parse some JSON
// configuration into our application.
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
)
// we will create a function called LoadConfig that will load up our JSON
// configuration file
func LoadConfig(path string) (map[string]interface{}, error) {
var m map[string]interface{}
data, err := ioutil.ReadFile(path)
if err != nil {
return m, err
}
err = json.Unmarshal(data, &m)
return m, err
}
func main() {
config, err := LoadConfig("config.json")
if err != nil {
panic(err)
}
fmt.Println(config)
}
type point struct {
x, y int
}
p := point{20, 40}
p.x
p.y
type rect struct {
pos point
width int
height int
}
##Constructor:
func newPoint(x, y int) point {
return point{x, y}
}
r := rect {
pos: NewPoint(20,40),
width: 100
height: 200
}
##Method on a struct:
func (r rect) area() int {
return r.width * r.height
}
fmt.Println(r.area())
Animal is an interface. Any type which implements the Pet and Name function can be considered an Animal.
package main
import "fmt"
type Animal interface {
Pet()
Name() string
}
type Cat struct {
name string
}
func (c Cat) Pet() {
fmt.Println("prrrrrr")
}
func (c Cat) Name() string {
return c.name
}
type Dog struct {
name string
}
func (d Dog) Pet() {
fmt.Println("woof woof")
}
func (d Dog) Name() string {
return d.name
}
func Compliment(a Animal) {
fmt.Println("Great Job", a.Name())
a.Pet()
}
func main() {
c := Cat{"johnny larry"}
Compliment(c)
d := Dog{"trixie belle"}
Compliment(d)
}
os.Args[0]
is always the path of the binary being run.
https://github.com/codegangsta/essential-go/tree/master/pub
Key things:
- Generating markdown
- Package Building
- Go Templates
- Concurrency != Parallelism
- Go by default runs on one core
- The scheduler is really smart
Primitives: Goroutines, Channels, Select statement
say
is a function which prints a string, then sleeps for 100 ms
go say("go")
go say("for it")
c := make(chan string, 4)
c <- "Hello"
c <- "world"
v := <-c
fmt.Println(v)
Select
======
Multiplex channel results (Events from Goroutines)
func main() {
done := make(chan bool)
go func() {
fmt.Println("Running...")
time.Sleep(250 * time.Millisecond)
done <- true
}()
<- done
}
func waiton(done chan bool) {
select {
case <-done:
fmt.Println("Finished")
case <- time.After(500 * time.Millisecond):
fmt.Println("Timeout")
}
}
https://www.kajabinext.com/courses/1-essential-go/lessons/16273-example-job-queue