| 10 things you (probably) don't know about Go |
| |
| Andrew Gerrand |
| Gopher |
| https://plus.google.com/106356964679457436995 |
| @enneff |
| http://golang.org |
| |
| * 1. Anonymous structs |
| |
| - Grouped globals |
| |
| var config struct { |
| APIKey string |
| OAuthConfig oauth.Config |
| } |
| |
| config.APIKey = "BADC0C0A" |
| |
| - Template data |
| |
| data := struct { |
| Title string |
| Users []*User |
| }{ |
| title, |
| users, |
| } |
| err := tmpl.Execute(w, data) |
| |
| (Cheaper and safer than using `map[string]interface{}`.) |
| |
| * 1b. Anonymous structs |
| |
| - Test tables |
| |
| var indexRuneTests = []struct { |
| s string |
| rune rune |
| out int |
| }{ |
| {"a A x", 'A', 2}, |
| {"some_text=some_value", '=', 9}, |
| {"☺a", 'a', 3}, |
| {"a☻☺b", '☺', 4}, |
| } |
| |
| - Embedded lock |
| |
| var hits struct { |
| sync.Mutex |
| n int |
| } |
| |
| hits.Lock() |
| hits.n++ |
| hits.Unlock() |
| |
| |
| * 2. Nested structs |
| |
| - Decoding deeply nested JSON data |
| |
| {"data": {"children": [ |
| {"data": { |
| "title": "The Go homepage", |
| "url": "http://golang.org/" |
| }}, |
| ... |
| ]}} |
| |
| type Item struct { |
| Title string |
| URL string |
| } |
| |
| type Response struct { |
| Data struct { |
| Children []struct { |
| Data Item |
| } |
| } |
| } |
| |
| |
| * 3. Command-line godoc |
| |
| % godoc sync Mutex |
| PACKAGE |
| |
| package sync |
| import "sync" |
| |
| TYPES |
| |
| type Mutex struct { |
| // contains filtered or unexported fields |
| } |
| A Mutex is a mutual exclusion lock. Mutexes can be created as part of |
| other structures; the zero value for a Mutex is an unlocked mutex. |
| |
| func (m *Mutex) Lock() |
| Lock locks m. If the lock is already in use, the calling goroutine |
| blocks until the mutex is available. |
| |
| func (m *Mutex) Unlock() |
| Unlock unlocks m. It is a run-time error if m is not locked on entry to |
| Unlock. |
| |
| A locked Mutex is not associated with a particular goroutine. It is |
| allowed for one goroutine to lock a Mutex and then arrange for another |
| goroutine to unlock it. |
| |
| |
| * 4. godoc -src |
| |
| % godoc -src sync Mutex |
| // A Mutex is a mutual exclusion lock. |
| // Mutexes can be created as part of other structures; |
| // the zero value for a Mutex is an unlocked mutex. |
| type Mutex struct { |
| state int32 |
| sema uint32 |
| } |
| |
| Also shows unexported state! Great for digging around. |
| |
| |
| * 5. go get supports custom domains |
| |
| Yep: |
| |
| go get camlistore.org/pkg/netutil |
| |
| See `go help importpath` for the details. |
| |
| |
| * 6. Mock out the file system |
| |
| Got a package that works with the file system, but don't want your tests to actually use the disk? |
| |
| var fs fileSystem = osFS{} |
| |
| type fileSystem interface { |
| Open(name string) (file, error) |
| Stat(name string) (os.FileInfo, error) |
| } |
| |
| type file interface { |
| io.Closer |
| io.Reader |
| io.ReaderAt |
| io.Seeker |
| Stat() (os.FileInfo, error) |
| } |
| |
| // osFS implements fileSystem using the local disk. |
| type osFS struct{} |
| |
| func (osFS) Open(name string) (file, error) { return os.Open(name) } |
| func (osFS) Stat(name string) (os.FileInfo, error) { return os.Stat(name) } |
| |
| Implement your own fake `fileSystem` in and put it in `fs` while testing. |
| |
| |
| * 7. Method expressions |
| |
| type T struct {} |
| func (T) Foo(s string) { println(s) } |
| |
| var fn func(T, string) = T.Foo |
| |
| Real example from `os/exec`: |
| |
| func (c *Cmd) stdin() (f *os.File, err error) |
| func (c *Cmd) stdout() (f *os.File, err error) |
| func (c *Cmd) stderr() (f *os.File, err error) |
| |
| type F func(*Cmd) (*os.File, error) |
| for _, setupFd := range []F{(*Cmd).stdin, (*Cmd).stdout, (*Cmd).stderr} { |
| fd, err := setupFd(c) |
| if err != nil { |
| c.closeDescriptors(c.closeAfterStart) |
| c.closeDescriptors(c.closeAfterWait) |
| return err |
| } |
| c.childFiles = append(c.childFiles, fd) |
| } |
| |
| |
| * 8. Send and receive on the same channel |
| |
| .play 10things/8.go |
| |
| |
| * 9. Using close to broadcast |
| |
| .play 10things/9.go /func.waiter/,/endmain/ |
| |
| |
| * 9b. Using close to broadcast |
| |
| .play 10things/9b.go /func.worker/,/endmain/ |
| |
| |
| * 10. Nil channel in select |
| |
| .play 10things/10.go /func.worker/,/endmain/ |
| |
| |
| * 11. The gopher's name |
| |
| .image 10things/gopher.jpg |
| |