Go runtime. To run a function in a new goroutine, just put "go" before the function call. package main import ( "fmt" "time" ) func main() { go say("let's go!", 3*time.Second) go say("ho!", 2*time.Second) go say("hey!", 1*time.Second) time.Sleep(4 * time.Second) } func say(text string, delay time.Duration) { time.Sleep(delay) fmt.Println(text) } Run
a better fit. The sync package provides mutexes, condition variables, and more useful primitives. func main() { wg := new(sync.WaitGroup) wg.Add(3) go say(wg, "let's go!", 3*time.Second) go say(wg, "ho!", 2*time.Second) go say(wg, "hey!", 1*time.Second) wg.Wait() } func say(wg *sync.WaitGroup, text string, delay time.Duration) { time.Sleep(delay) fmt.Println(text) wg.Done() } Run
expressing instants in time and periods of time. It also provides a Location type for expressing time zones. And, as we've already seen, it provides functions related to sleeping. birthday, _ := time.Parse("Jan 2 2006", "Nov 10 2009") // time.Time age := time.Since(birthday) // time.Duration fmt.Printf("Go is %d days old\n", age/(time.Hour*24)) Run t := time.Now() fmt.Println(t.In(time.UTC)) home, _ := time.LoadLocation("Australia/Sydney") fmt.Println(t.In(home)) Run
client handles HTTP Keep-Alive using a pool of connections, by default. (This is configurable, of course.) func main() { r, err := http.Get("http://www.golang.org/") if err != nil { log.Fatal(err) } if r.StatusCode != http.StatusOK { log.Fatal(r.Status) } io.Copy(os.Stdout, r.Body) } Run
This is a high-performance, DoS-hardened, production-ready web server. It serves dl.google.com. func main() { http.HandleFunc("/", handler) err := http.ListenAndServe("localhost:8080", nil) if err != nil { log.Fatal(err) } } func handler(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, "Hello, web") } Run
command-line flags. Example invocation (a little different than GNU getopt): $ flag -message 'Hold on...' -delay 5m var ( message = flag.String("message", "Hello!", "what to say") delay = flag.Duration("delay", 2*time.Second, "how long to wait") ) func main() { flag.Parse() fmt.Println(*message) time.Sleep(*delay) } Run
between the repo poller and the user interface. This global struct variable contains a sync.RWMutex and a boolean value: var state struct { sync.RWMutex yes bool // whether Go 1.1 has been tagged. } To read, take the read lock (multiple goroutines can do this simultaneously): state.RLock() yes := state.yes state.RUnlock() To write, take the write lock (only one goroutine can do this at a time): state.Lock() state.yes = true state.Unlock()
repository this URL will return a "200 OK" response: const changeURL = "https://code.google.com/p/go/source/detail?r=go1.1" The isTagged function returns true if the go1.1 tag exists. func isTagged() bool { r, err := http.Head(changeURL) if err != nil { log.Print(err) return false } return r.StatusCode == http.StatusOK }
Then it updates the state ("Go 1.1 is out!") and returns. func poll(period time.Duration) { for !isTagged() { time.Sleep(period) } state.Lock() state.yes = true state.Unlock() }
request. It puts the state.yes and changeURL values into a struct, and uses the struct to render the template as the HTTP response. func handler(w http.ResponseWriter, r *http.Request) { state.RLock() data := struct { Yes bool URL string }{ Yes: state.yes, URL: changeURL, } state.RUnlock() err := tmpl.Execute(w, data) if err != nil { log.Print(err) } }
that provides the HTML UI. It is a global variable, so the template is parsed just once at init time. var tmpl = template.Must(template.New("root").Parse(` <!DOCTYPE html><html><body><center> <h2>Is Go 1.1 out yet?</h2> <h1> {{if .Yes}} <a href="{{.URL}}">YES!</a> {{else}} No. {{end}} </h1> </center></body></html> `))
a new goroutine and sets up the web server. Some command-line flags enable run time configuration. var ( httpAddr = flag.String("http", "localhost:8080", "Listen address") pollPeriod = flag.Duration("poll", 5*time.Second, "Poll period") ) func main() { flag.Parse() go poll(*pollPeriod) http.HandleFunc("/", handler) log.Fatal(http.ListenAndServe(*httpAddr, nil)) } The whole program is just 68 lines of code.
The Go blog blog.golang.org (http://blog.golang.org) Go talks talks.golang.org (http://talks.golang.org) A Tour of Go tour.golang.org (http://tour.golang.org)