Upload
mayflower-gmbh
View
241
Download
0
Embed Size (px)
Citation preview
...OF PLAN 9 FAME
The worst sci-fi movie everAn experimental OS developed at BellHeritage visible in Go (toolchain!)
THE AUTHORITATIVEDOCUMENT
Go at Google: Language Design in the Service of SoftwareEngineering.
[https://talks.golang.org/2012/splash.article]
(And you'll be stumbling over Plan 9 more than once)
SOME DESIGN GOALS
Fast compilation cyclesSimple and concise syntax: easy to read, easy to parseFamiliarity for new developersScales well to large code basesPromote robust and maintainable designKeep large codebases robust in face of changeOffer maintainable paradigms for multithreading
STATICALLY TYPED// Variable declaration var someint int var somestring string var somemap map[string]int // Type inference someint := 10 somestring := "Hello world" somemap := make(map[string]int) // Type definition type Sometype struct { Field1 int Field2 []bool } // Function declaration func Fooinator(param1 int, param2 SomeStruct) string { // Do something }
IMPLICIT INTERFACES,BUT NO CLASSES
package main import ( "fmt" "log" "os" ) type Doc interface {} type DocumentStorage interface { Store(int, Doc) (error) Get(int) (Doc, error) } type MemoryStorage struct { docs map[int]Doc
GARBAGE COLLECTED...type SomeStruct struct { Field1 string Field2 string } func Generator() SomeStruct { return SomeStruct{ Field1: "Hello", Field2: "World", } }
... WITH POINTERS ...type SomeStruct struct { Field1 string Field2 string } func Generator() *SomeStruct { return &SomeStruct{ Field1: "Hello", Field2: "World", } }
... AND CLOSURESfunc FibonacciGenerator() (func() int) { f0 := 0 f1 := 1 return func() { oldF0 := f0 f0 = f1 f1 = oldF0 + f1 return f1 } } // ... f := FibonacciGenerator() fmt.Println(f(), f(), f(), f(), f(), f()) // 1 2 3 5 8 13
LIGHTWEIGHT THREADS-> GOROUTINES
Scheduling (cooperative multithreading with multiplethreads)BlockingCommunication (channels)Races & mutexesEmbed code from golang/samples/interfaces.go
LIGHTWEIGHT THREADS ->GOROUTINES
package main import ( "fmt" "time" ) func saySomething(s string, times int) { for i := 0; i < times; i++ { time.Sleep(100 * time.Millisecond) fmt.Println(s) } } func main() { go saySomething("hello", 3) go saySomething("world", 3) saySomething("!", 3) } // output: world hello ! world hello ! world ! hello
LIGHTWEIGHT THREADS ->GOROUTINES
package main import ( "fmt" ) func sayHello(times int, outputChannel chan<- string) { for i := 0; i < times; i++ { outputChannel <- "Hello" } } func sayWorld(times int, inputChannel <-chan string, outputChannel chan<- string for i := 0; i < times; i++ { output := <- inputChannel + " World!" outputChannel <- output } } func printString(times int, inputChannel <-chan string, outputChannel chan<- bool for i := 0; i < times; i++ { output := <- inputChannel
NO EXCEPTION HANDLING, BUT... package main import ( "os" "flag" "log" ) func FileSize(path string) (int64, error) { fileInfo, err := os.Stat(path) if err != nil { return 0, err } return fileInfo.Size(), nil } func main() { var filePath string flag.StringVar(&filePath, "filePath", "", "the file to get the size of" flag.Parse()
HTTP SERVERtype handler int func (h *handler) ServeHTTP( response http.ResponseWriter, request *http.Request, ) { response.WriteHeader(http.StatusOK) fmt.Fprintf(response, "this is request #%v\n", *h) *h++ } func main() { i := 0 http.ListenAndServe(":8888", (*handler)(&i)) }
HTTP CLIENTresp, err := http.Get("http://www.mayflower.de") var responseBuffer []byte if err == nil { responseBuffer, err = ioutil.ReadAll(resp.Body) } if err == nil { fmt.Println(string(responseBuffer)) } else { fmt.Printf("ERROR: %v\n", err) }
STREAM COMPRESSIONresp, err := http.Get("http://www.mayflower.de") if err == nil { writer := gzip.NewWriter(os.Stdout) _, err = io.Copy(writer, resp.Body) if err == nil { writer.Close() } } if err != nil { fmt.Fprintf(os.Stderr, "ERROR: %v\n", err) }
AND MUCH, MUCH MORE...
Crypto, hashingMarshalling / Unmarshalling (JSON, Base64, XML, ...)Command line parsingComplex numbersJSON RPCReflectionGolang lexer and parser!
SWISS KNIVE: GOgo as interface to complete toolchaingo getgo build -xgo installgo test -racego test -coverprofile=c.outgo tool cover -html=c.out
"NATIVE" TOOLCHAINThis is the toolchain referred to in golang releaseRooted in Plan 9 toolchain (assembler, linker)Used to be C, now Golang (converted from C)Produces static binaries (not quite true anymore)OS: Win, Linux, OSX, BSD and friends, Plan 9 (!), ...Arch: x86, x86-64, ARM(v5678), ppcDead simple cross compilation
GOARCH=x86 GOOS=windows go install some/package
GCC FRONTEND
Lags behind native toolchain (currently 1.4 in GCC5)Relies on GCC & friends for optimization, codegeneration and linkingGenerates dynamic binariesSupports anything supported by GCC (MIPS anybody)Cross compilation: PITA
INTERFACING C
Works with CGO: generates glue codeDynamic dependencies: breaks cross compiling badly :(BUT: Lots of native go out there :)
TESTING, PROFILINGAND CODE COVERAGE
[MARCO]Testing files located by convention main.go ->main_test.gogo test -cover -cpuprofile cpu.out -memprofile mem.out
TESTING, PROFILING AND CODECOVERAGE
package main import "testing" func TestDivide(t *testing.T) { v, _ := Divide(10, 5) if v != 2 { t.Error("Expected 2, got:", v) } }
DEPENDENCYMANAGEMENT
import "github.com/googollee/go-socket.io"
DEPENDENCIES CAN BEAUTOMATICALLY IMPORTED
FROM GITHUB?
AWESOME!
SOLUTION 1: GOPKG.INimport "gopkg.in/yaml.v1"
$ curl http://gopkg.in/yaml.v1?go-get=1 <html> <head> <meta name="go-import" content="gopkg.in/yaml.v1 git https://gopkg.in/yaml.v1"><meta name="go-source" content="gopkg.in/yaml.v1 _ https://github.com/go-yaml/yaml/tree/v1{/dir} https://github.com/go-yaml/yaml/blob/v1{/dir}/{file}#L{line}"> </head> <body> go get gopkg.in/yaml.v1 </body> </html>
Redirects to fixed tags on githubWorks well for small libraries
SOLUTION 2:VENDORING
Record and pin dependencies in per-package manifestRecursively download deps before buildNeeds external tooling and per-package support :(Popular specimen: glide
PERFORMANT SERVERSEvent loop AND threadsCompiled and statically typedStandard lib covers most networking stuffCommunity frameworks for services: go-micro, go-kit
DEPENDENCY-LESSUNIX-STYLE CLI TOOLS
Direct access to syscallsHuge standard librarySupports script-like code styleStatic binaries
THANK YOU FORLISTENINGQUESTIONS?
Christian Speckner <[email protected]>Marco Jantke <[email protected]>