Created
January 31, 2014 05:53
-
-
Save mtrythall/8727235 to your computer and use it in GitHub Desktop.
My notes from the Intro to Go class held at Codefellows Jan 30 2014
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
# Intro to Go | |
Go is opinionated. | |
## Performance | |
Go is extremely fast. "100x faster than the heavily cached Ruby option" | |
"1% of memory footprint" | |
Go is best at JSON serialization | |
## History | |
1. Compiled language | |
2. Statically typed | |
3. Concurrent | |
4. Garbage collected | |
5. Simple - classically defined | |
Invented by Rob Pike, Ken Thompson, Robert Griesemer | |
~2007. OSS in Nov 2009. 464 contributors ("Not Google owned, very open") | |
## Problem 1 - Development Speed | |
"Fast to develop, fast to compile" | |
"Feel like dynamically typed interpreted language." | |
### Fast has its Tradeoffs | |
* No generics - may come later, no fast way to do now | |
* Inheritance - doesn't have traditional inheritance | |
Has its quirks... Manages your imports - complains if you have imports that you don't use | |
## Make it Modern | |
### Modern means multicore == Concurrency | |
Takes care of the routines for you. You talk to processes ("Not objects") | |
### Modern means Internet | |
* Batteries included, e.g. net/http | |
* std-lib has most of what you need | |
## Complexity | |
Webscale - Large programs, big teams | |
* Designed to be C-like for early career programmers | |
* Simplified syntax | |
### Examples of Simplicity | |
* 1 keyword `for` looping | |
* Garbage collection | |
* 25 keywords total (50 in Java, 48 in C++, ~42 Ruby) | |
* No inheritance - Composition is easier to get right, defers design decisions | |
* CSP concurrency | |
### Ask when Confused | |
"When Go is confusing, have to ask..." | |
* Is it because the language is young? Go is young, it will be missing some stuff. | |
* Is it because Go wants to be simple? | |
* Is it because Go wants to be fast? | |
# Code | |
Have to have a main() | |
## Functions | |
Lowercase functions are private (?) | |
Capital function names are 'exported functions' (public?) | |
func Divide(a, b int) (variables here are created) | |
## Variables | |
Long form | |
var foo string = "whatever" | |
Short form | |
var geddy, alex, neil string = "lee", "lifeson", "peart" | |
thing := "value" // I guess this picks up the type by value? | |
### Constants | |
const pi = 3.14 | |
## Loops | |
// C-Style | |
for i : = 1, 1 <= 10; i++ | |
// Compact C-style | |
for x < 10 | |
// infinite | |
for { | |
} | |
## Flow Control | |
if i%2 == 0 { // no parans needed | |
} else { | |
} | |
if x : = math.Exp(i); x == math.E // with example | |
switch i%2 == 0 { // no fall through, stops when match | |
case true: | |
// stuff | |
default: | |
// stuff 2 | |
} | |
## Structs | |
type Muscian struct { | |
Name string | |
Instrument string | |
} | |
geddy := Musician{"Geddy Lee", "Bass"} | |
neil := new(Musician) | |
neil.Name, neil.Instrument = "Neil Peart", "Drums" | |
There is no `nil` in Go | |
## Arrays | |
Not that important in Go | |
Array is an inmuttable structure. Go beyond it, it will blow up. | |
// Only has 2 slots | |
var x [2]string | |
x[0] = "only" | |
x[1] = "two" | |
x[2] = "foo" // will break | |
## Slices | |
x := []string{"A", "B"} | |
x = append(x, "C") // space is not limited | |
#v in string output depicts Go type (?) | |
x := make([]string, 2) | |
x[0] = "A" | |
### Range over Slice | |
things := []int{0, 1, 1, 2, 3, 5, 8} | |
for i, thing := range things { | |
// whatever | |
} | |
## Maps | |
make(map[string]string) | |
rush{"keytar"} = "Geddy Lee" | |
delete(rush, "keytar") // removes from map | |
_, ok := rush["keytar"] // _ suppresses error (?) | |
Pretend that it's there and check to see if it is | |
ok is bool, common language for this scenario. | |
## Functions as Values | |
prefix := "Prefixed" | |
customLogger := func(message, string) string { | |
// functions have closures | |
return fmt.Sprintf("%v: %v", prefix, message) | |
} | |
Don't have to worry about pointers (except in 1 instance, explained later) | |
## Methods | |
// No real classes | |
type Band struct { | |
Name string | |
} | |
// methods go on the type | |
func (b *Band) Play() string { | |
return fmt.Sprintf("%v plays!", b.Name) | |
} | |
... | |
// want a pointer to this (&), pointer allows mutation of type | |
b := &Band{"Rush"} | |
fmt.Println(b.Play()) | |
Methods live outside of "classes". | |
## Interfaces | |
"This is how Go does inheritance type stuff" | |
Collection of methods - "Not a real thing, not concrete" | |
// Players play. In order to be a player, you must Play. | |
// Your playing must return a string | |
type Player interface { | |
Play() string | |
} | |
NOTE: Look into this again. Looks like we're using receivers. | |
Benefit here is that you can declare interfaces after you've learned more about your system. "Neat way to organize when you're smarter". | |
Don't have to write `implements` everywhere, faster development. | |
Q: Can a method be overidden? | |
A: Use embedding - Advanced topic, look it up. "Inbetween interface" | |
## Errors | |
Standard way of dealing with errors is inline. | |
"Errors get caught right where they happen" | |
Error() function | |
if err := run(); err .. // Note: Presenter flipped too fast | |
# Goroutines | |
"Go enables people to do concurrency where they wouldn't even try it in their current language" | |
package main | |
import ( | |
"fmt" | |
"time" | |
) | |
func say(s string) { | |
for i := 0; i < 5; i++ { | |
time.Sleep(100 * time.Millisecond) | |
fmt.Println(s) | |
} | |
} | |
func main() { | |
go say("World") | |
say("Hello") | |
} | |
Go encourages you to use goroutines. | |
## Channels | |
Talking between goroutines | |
NOTE: Too much to type, look this topic up | |
Ping pong example. 2 players. Channel is process between players. | |
One player says 'ping', the other 'pong'. Communicate through "table" channel. | |
<- table // channels are directional, pulls `table` off | |
ball := <-table | |
ball.hits++ | |
... | |
table <- ball // puts "ball back on table" | |
"It's OK to block your goroutine, the others will keep going" | |
### Buffered Channel | |
"You probably won't use these often" | |
func main() { | |
// holds two before blocking | |
c := main(chan int, 2) // only 2 things | |
c <- 1 | |
c <- 2 | |
// c <- 3 would deadlock | |
fmt.Println(<-c) // grabs 1st thing | |
fmt.Println(<-c) // grabs 2nd thing | |
} | |
"all goroutines are asleep - deadlock!" | |
NOTE: Look up Dying philosopher problem | |
### Range over Channel | |
"Lazy evaluated functions" | |
NOTE: Example too long to jot down | |
### Select over multiple Channels | |
`select` allows you to pull across multiple channels | |
Will keep pulling until one channel has a message to send | |
NOTE: Example too long to jot down. "Very complicated example". |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment