pdf文档 Real World Go

595.19 KB 49 页 0 评论
语言
英语
格式
.pdf
评分
3
摘要
Real World Go Andrew Gerrand May 9, 2011 Background 3 Google Confidential Why Go? • Statically typed languages are efficient, but typically bureaucratic and overly complex. • Dynamic languages can be easy to use, but are error-prone, inefficient, and break down at scale. • Concurrent programming is hard (threads, locks, headache). • “Speed, reliability, or simplicity: pick two.” (sometimes just one) • Can’t we do better? 3 Google Confidential What is Go? • Go is a modern, general purpose language. • Compiles to native machine code (32-bit and 64-bit x86, ARM). • Statically typed. • Lightweight syntax. • Simple type system. • Concurrency primitives. 3 Google Confidential Tenets of Go’s design • Simplicity – Each language feature should be easy to understand. • Orthogonality – Go’s features should interact in predictable and consistent ways. • Readability – What is written on the page should be comprehensible with little context. “Consensus drove the design. Nothing went into the language until [Ken Thompson, Robert Griesemer, and myself] all agreed that it was right. Some features didn’t get resolved until after a year or more of discussion.” Rob Pike 3 Google Confidential Hello, world package main import "fmt" func main() { fmt.Println("Hello, 世界") } 3 Google Confidential Hello, world 2.0 Serving “Hello, world” at http://localhost:8080/world package main import ( "fmt" "http" ) func handler(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, "Hello, "+r.URL.Path[1:]) } func main() { http.HandleFunc("/", handler) http.ListenAndServe(":8080", nil) } A simple type system 3 Google Confidential Simple type system Go is statically typed, but type inference saves repetition. Java: Integer i = new Integer(1); C/C++: int i = 1; Go: i := 1 // type int pi := 3.142 // type float64 greeting := "Hello, Bootcamp!" // type string mul := func(x, y int) int { return x * y } // type func(int, int) int 3 Google Confidential Types and methods You can define methods on any type: type Point struct { X, Y float64 } func (p Point) Abs() float64 { return math.Sqrt(p.X*p.X + p.Y*p.Y) } p := Point{4, 3} // type Point p.Abs() // == 5.0 3 Google Confidential Types and methods You can define methods on any type: type MyFloat float64 func (m MyFloat) Abs() float64 { f := float64(m) if f < 0 { return -f } return f } f := MyFloat(-42) f.Abs() // == 42.0 Go “objects” are just values. There is no “box”. 3 Google Confidential Interfaces Interfaces specify behaviors. An interface type defines a set of methods: type Abser interface { Abs() float64 } A type that implements those methods implements the interface: func PrintAbs(a Abser) { fmt.Printf("Absolute value: %.2f\n", a.Abs()) } PrintAbs(MyFloat(-10)) PrintAbs(Point{3, 4}) Types implement interfaces implicitly. There is no “implements” declaration. 3 Google Confidential Interfaces in practice From the io package in the standard library: type Writer interface { Write(p []byte) (n int, err os.Error) } There are many Writer implementations throughout the standard library and other Go code. We’ve already seen an example: func handler(w http.ResponseWriter, r ...) { fmt.Fprint(w, "Hello, "+r.URL.Path[1:]) } The fmt.Fprint function takes an io.Writer as its first argument, and http.ResponseWriter implements the Write method. The fmt package doesn’t know http. It just works. Concurrency 3 Google Confidential Concurrency In UNIX we think about processes connected by pipes: find ~/go/src/pkg | grep _test.go$ | xargs wc -l Each tool designed to do one thing and to do it well. The Go analogue: goroutines connected by channels. 3 Google Confidential Concurrency: goroutines Goroutines are like threads: • They share memory. But cheaper: • Smaller, segmented stacks. • Many goroutines per operating system thread. Start a new goroutine with the go keyword: i := pivot(s) go sort(s[:i]) go sort(s[i:]) 3 Google Confidential Concurrency: channels Channels are a typed conduit for: • Synchronization. • Communication. The channel operator <- is used to send and receive values: func compute(ch chan int) { ch <- someComputation() } func main() { ch := make(chan int) go compute(ch) result := <-ch } 3 Google Confidential Concurrency: synchronization Look back at the sort example - how to tell when it’s done? Use a channel to synchronize goroutines: done := make(chan bool) doSort := func(s []int) { sort(s) done <- true } i := pivot(s) go doSort(s[:i]) go doSort(s[i:]) <-done <-done Unbuffered channel operations are synchronous; the send/receive happens only when both sides are ready. 3 Google Confidential Concurrency: communication A common task: many workers feeding from task pool. Traditionally, worker threads contend over a lock for work: type Task struct { // some state } type Pool struct { Mu sync.Mutex Tasks []Task } func worker(pool *Pool) { // many of these run concurrently for { pool.Mu.Lock() task := pool.Tasks[0] pool.Tasks = pool.Tasks[1:] pool.mu.Unlock() process(task) } } 3 Google Confidential Concurrency: communication A Go idiom: many worker goroutines receive tasks from a channel. type Task struct { // some state } func worker(in, out chan *Task) { for { t := <-in process(t) out <- t } } func main() { pending, done := make(chan *Task), make(chan *Task) go sendWork(pending) for i := 0; i < 10; i++ { go worker(pending, done) } consumeWork(done) } 3 Google Confidential Concurrency: philosophy • Goroutines give the efficiency of an asynchronous model, but you can write code in a synchronous style. • Easier to reason about: write goroutines that do their specific jobs well, and connect them with channels. – In practice, this yields simpler and more maintainable code. • Think about the concurrency issues that matter: “Don’t communicate by sharing memory. In...
来源go.dev
Real World Go 第2页
Real World Go 第3页
下载文档到本地,方便使用
共 49 页, 还有 5 页可预览, 继续阅读
文档评分
请文明评论,理性发言.