![Page 1: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/1.jpg)
7 Common Mistakes
In Go and when to avoid them
![Page 2: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/2.jpg)
@Spf13
Author of Hugo, Cobra, Afero, Viper & more
![Page 3: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/3.jpg)
–Mel Brooks
“As long as the world is turning and spinning, we're gonna be dizzy and we're gonna make
mistakes.”
![Page 4: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/4.jpg)
–Al Franken
“Appreciate your mistakes for what they are: precious life lessons that can only be learned
the hard way. “
![Page 5: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/5.jpg)
– Tallulah Bankhead
“If I had to live my life again, I'd make the same mistakes, only sooner.”
![Page 6: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/6.jpg)
7 Lessons I Wish I Learned Sooner
![Page 7: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/7.jpg)
Mistake 1: Not
Accepting Interfaces
![Page 8: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/8.jpg)
State & Behavior
•Types can express state & behavior
•State = data structure •Behavior = methods
![Page 9: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/9.jpg)
Interfaces•One of Go’s most powerful
features •Permits extensibility •Defined by methods •Adherance is only satisfied by
behavior
![Page 10: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/10.jpg)
![Page 11: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/11.jpg)
type Source struct {
Frontmatter []byte
Content []byte
}
Example : []Byte
![Page 12: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/12.jpg)
func StripHTML(s string) string { output := ""
// Shortcut strings with no tags in them if !strings.ContainsAny(s, "<>") { output = s } else { s = strings.Replace(s, "\n", " ", -1) s = strings.Replace(s, "</p>", "\n", -1) s = strings.Replace(s, "<br>", "\n", -1) s = strings.Replace(s, "<br />", "\n", -1)
…
Func Restricted To String
![Page 13: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/13.jpg)
func (p *Page) Plain() string {
return helpers.StripHTML(string(p.Content))
}
Passes Implementation Details Down The Stack
![Page 14: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/14.jpg)
func StripHTML(r Reader) string { buf := new(bytes.Buffer) buf.ReadFrom(r) by := buf.Bytes() if bytes.ContainsAny(s, []byte("<>")) { by = bytes.Replace(by, []byte("\n"), " ", -1) by = bytes.Replace(by, []byte("</p>"), "\n", -1) by = bytes.Replace(by, []byte("<br>"), "\n", -1) by = bytes.Replace(by, []byte("<br />"), "\n", -1)
…
Any Read() Works
![Page 15: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/15.jpg)
type Source struct { Frontmatter []byte content []byte }
type Reader interface { Read(p []byte) (n int, err error) }
func (s *Source) Content() (Reader) { return bytes.NewReader(content) }
Example : Read
![Page 16: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/16.jpg)
type Source struct { Frontmatter []byte content []byte }
type Reader interface { Read(p []byte) (n int, err error) }
func (s *Source) Content() (Reader) { return bytes.NewReader(content) }
Example : Read
![Page 17: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/17.jpg)
type Source struct { Frontmatter []byte content []byte }
type Reader interface { Read(p []byte) (n int, err error) }
func (s *Source) Content() (Reader) { return bytes.NewReader(content) }
Example : Read
![Page 18: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/18.jpg)
func (p *Page) Plain() string {
return helpers.StripHTML(p.Content())
}
Implementation Details Abstracted With A Method
![Page 19: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/19.jpg)
Mistake 2: Thinking Of
Errors As Strings
![Page 20: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/20.jpg)
type error interface {
Error() string
}
Error Is An Interface
![Page 21: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/21.jpg)
Standard Errors•errors.New(“error here”) is
usually sufficient •Exported Error Variables
can be easily checked
![Page 22: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/22.jpg)
Custom Errors•Can provide context to
guarantee consistent feedback •Provide a type which can be
different from the error value •Can provide dynamic values
(based on internal error state)
![Page 23: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/23.jpg)
func NewPage(name string) (p *Page, err error) {
if len(name) == 0 {
return nil, errors.New("Zero length page name")
}
Standard Error
![Page 24: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/24.jpg)
var ErrNoName = errors.New("Zero length page name")func NewPage(name string) (*Page, error) {
if len(name) == 0 {
return nil, ErrNoName
}
Exported Error Var
![Page 25: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/25.jpg)
var ErrNoName = errors.New("Zero length page name") func Foo(name string) (error) {
err := NewPage("bar")
if err == ErrNoName {
newPage("default")
} else {
log.FatalF(err)
}
}
Exported Error Var
![Page 26: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/26.jpg)
// Portable analogs of some common system call errors. var ErrInvalid = errors.New("invalid argument") var ErrPermission = errors.New("permission denied")
// PathError records an error and // the operation and file path that caused it. type PathError struct { Op string Path string Err error }
func (e *PathError) Error() string { return e.Op + " " + e.Path + ": " + e.Err.Error() }
Custom Errors : Os
![Page 27: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/27.jpg)
// Portable analogs of some common system call errors. var ErrInvalid = errors.New("invalid argument") var ErrPermission = errors.New("permission denied")
// PathError records an error and // the operation and file path that caused it. type PathError struct { Op string Path string Err error }
func (e *PathError) Error() string { return e.Op + " " + e.Path + ": " + e.Err.Error() }
Custom Errors : Os
![Page 28: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/28.jpg)
func (f *File) WriteAt(b []byte, off int64) (n int, err error) { if f == nil { return 0, ErrInvalid } for len(b) > 0 { m, e := f.pwrite(b, off) if e != nil { err = &PathError{"write", f.name, e} break } n += m b = b[m:] off += int64(m) } return }
Custom Errors : Os
![Page 29: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/29.jpg)
func (f *File) WriteAt(b []byte, off int64) (n int, err error) { if f == nil { return 0, ErrInvalid } for len(b) > 0 { m, e := f.pwrite(b, off) if e != nil { err = &PathError{"write", f.name, e} break } n += m b = b[m:] off += int64(m) } return }
Custom Errors : Os
![Page 30: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/30.jpg)
func (f *File) WriteAt(b []byte, off int64) (n int, err error) { if f == nil { return 0, ErrInvalid } for len(b) > 0 { m, e := f.pwrite(b, off) if e != nil { err = &PathError{"write", f.name, e} break } n += m b = b[m:] off += int64(m) } return }
Custom Errors : Os
![Page 31: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/31.jpg)
func baa(f *file) error { … n, err := f.WriteAt(x, 3) if _, ok := err.(*PathError) { … } else { log.Fatalf(err) } }
Custom Errors : Os
![Page 32: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/32.jpg)
…
if serr != nil {
if serr, ok := serr.(*PathError); ok && serr.Err == syscall.ENOTDIR {
return nil
}
return serr
…
Custom Errors : Os
![Page 33: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/33.jpg)
…
if serr != nil {
if serr, ok := serr.(*PathError); ok &&
serr.Err == syscall.ENOTDIR { return nil
}
return serr
…
Custom Errors : Os
![Page 34: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/34.jpg)
Mistake 3: Requring
Broad Interfaces
![Page 35: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/35.jpg)
Interfaces Are Composable
•Functions should only accept interfaces that require the methods they need
•Functions should not accept a broad interface when a narrow one would work
•Compose broad interfaces made from narrower ones
![Page 36: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/36.jpg)
![Page 37: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/37.jpg)
type File interface { io.Closer io.Reader io.ReaderAt io.Seeker io.Writer io.WriterAt }
Composing Interfaces
![Page 38: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/38.jpg)
func ReadIn(f File) { b := []byte{} n, err := f.Read(b) ... }
Requiring Broad Interfaces
![Page 39: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/39.jpg)
type File interface { io.Closer io.Reader io.ReaderAt io.Seeker io.Writer io.WriterAt }
Composing Interfaces
![Page 40: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/40.jpg)
func ReadIn(r Reader) { b := []byte{} n, err := r.Read(b) ... }
Requiring Narrow Interfaces
![Page 41: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/41.jpg)
Mistake 4: Methods Vs Functions
![Page 42: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/42.jpg)
Too Many Methods
•A lot of people from OO backgrounds overuse methods
•Natural draw to define everything via structs and methods
![Page 43: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/43.jpg)
What Is A Function?
•Operations performed on N1 inputs that results in N2 outputs
•The same inputs will always result in the same outputs
•Functions should not depend on state
![Page 44: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/44.jpg)
What Is A Method?
•Defines the behavior of a type •A function that operates
against a value •Should use state •Logically connected
![Page 45: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/45.jpg)
Functions Can Be Used With Interfaces
•Methods, by definition, are bound to a specific type
•Functions can accept interfaces as input
![Page 46: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/46.jpg)
![Page 47: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/47.jpg)
func extractShortcodes(s string, p *Page, t Template) (string, map[string]shortcode, error) { ... for { switch currItem.typ { ... case tError: err := fmt.Errorf("%s:%d: %s", p.BaseFileName(), (p.lineNumRawContentStart() + pt.lexer.lineNum() - 1), currItem) } } ... }
Example From Hugo
![Page 48: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/48.jpg)
func extractShortcodes(s string, p *Page, t Template) (string, map[string]shortcode, error) { ... for { switch currItem.typ { ... case tError: err := fmt.Errorf("%s:%d: %s", p.BaseFileName(), (p.lineNumRawContentStart() + pt.lexer.lineNum() - 1), currItem) } } ... }
Example From Hugo
![Page 49: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/49.jpg)
Mistake 5: Pointers Vs
Values
![Page 50: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/50.jpg)
Pointers Vs Values
•It’s not a question of performance (generally), but one of shared access
•If you want to share the value with a function or method, then use a pointer
•If you don’t want to share it, then use a value (copy)
![Page 51: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/51.jpg)
Pointer Receivers
•If you want to share a value with it’s method, use a pointer receiver
•Since methods commonly manage state, this is the common usage
•Not safe for concurrent access
![Page 52: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/52.jpg)
Value Receivers•If you want the value copied
(not shared), use values •If the type is an empty struct
(stateless, just behavior)… then just use value
•Safe for concurrent access
![Page 53: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/53.jpg)
type InMemoryFile struct { at int64 name string data []byte closed bool }
func (f *InMemoryFile) Close() error { atomic.StoreInt64(&f.at, 0) f.closed = true return nil }
Afero File
![Page 54: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/54.jpg)
type Time struct {
sec int64
nsec uintptr
loc *Location
}
func (t Time) IsZero() bool {
return t.sec == 0 && t.nsec == 0
}
Time
![Page 55: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/55.jpg)
Mistake 6: Not Using
Io.Reader & Io.Writer
![Page 56: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/56.jpg)
Io.Reader & Io.Writer
•Simple & flexible interfaces for many operations around input and output
•Provides access to a huge wealth of functionality
•Keeps operations extensible
![Page 57: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/57.jpg)
type Reader interface {
Read(p []byte) (n int, err error)
}
type Writer interface {
Write(p []byte) (n int, err error)
}
Io.Reader & Io.Writer
![Page 58: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/58.jpg)
![Page 59: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/59.jpg)
func (page *Page) saveSourceAs(path string) {
b := new(bytes.Buffer)
b.Write(page.Source.Content)
page.saveSource(b.Bytes(), path)
}
func (page *Page) saveSource(by []byte, inpath string) {
WriteToDisk(inpath, bytes.NewReader(by))
}
Stop Doing This!!
![Page 60: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/60.jpg)
func (page *Page) saveSourceAs(path string) {
b := new(bytes.Buffer)
b.Write(page.Source.Content)
page.saveSource(b.Bytes(), path)
}
func (page *Page) saveSource(by []byte, inpath string) {
WriteToDisk(inpath, bytes.NewReader(by))
}
Stop Doing This!!
![Page 61: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/61.jpg)
func (page *Page) saveSourceAs(path string) {
b := new(bytes.Buffer)
b.Write(page.Source.Content)
page.saveSource(b.Bytes(), path)
}
func (page *Page) saveSource(by []byte, inpath string) {
WriteToDisk(inpath, bytes.NewReader(by))
}
Stop Doing This!!
https://github.com/spf13/hugo/blob/master/hugolib/page.go#L582
![Page 62: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/62.jpg)
func (page *Page) saveSourceAs(path string) {
b := new(bytes.Buffer)
b.Write(page.Source.Content)
page.saveSource(b, path)
}
func (page *Page) saveSource(b io.Reader, inpath string) {
WriteToDisk(inpath, b)
}
Instead
![Page 63: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/63.jpg)
Mistake 7: Ignoring
Concurrent Access
![Page 64: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/64.jpg)
Consider Concurrency
•If you provide a library someone will use it concurrently
•Data structures are not safe for concurrent access
•Values aren’t safe, you need to create safe behavior around them
![Page 65: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/65.jpg)
Making It Safe•Sync package provides behavior
to make a value safe (Atomic/Mutex)
•Channels cordinate values across go routines by permitting one go routine to access at a time
![Page 66: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/66.jpg)
![Page 67: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/67.jpg)
func (m *MMFs) Create(name string) (File, error) {
m.getData()[name] = MemFileCreate(name)
m.registerDirs(m.getData()[name])
return m.getData()[name], nil
}
Maps Are Not Safe
![Page 68: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/68.jpg)
func (m *MMFS) Create(name string) (File, error) {
m.getData()[name] = MemFileCreate(name)
m.registerDirs(m.getData()[name])
return m.getData()[name], nil
}
Maps Are Not Safe
![Page 69: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/69.jpg)
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x28 pc=0x1691a7]
goroutine 90 [running]:
runtime.panic(0x501ea0, 0x86b104)
/usr/local/Cellar/go/1.3.3/libexec/src/pkg/runtime/panic.c:279 +0xf5
github.com/spf13/afero.(*MemMapFs).registerDirs(0xc208000860, 0x0, 0x0)
/Users/spf13/gopath/src/github.com/spf13/afero/memmap.go:88 +0x27
Maps Are Not Safe
![Page 70: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/70.jpg)
func (m *MMFS) Create(name string) (File, error) {
m.lock()
m.getData()[name] = MemFileCreate(name)
m.unlock()
m.registerDirs(m.getData()[name])
return m.getData()[name], nil
}
Maps Can Be Used Safely
![Page 71: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/71.jpg)
Biggsest Mistake:
Not Makimg Mistakes
![Page 72: 7 Common mistakes in Go and when to avoid them](https://reader033.vdocuments.us/reader033/viewer/2022042607/559445511a28abfa2f8b4808/html5/thumbnails/72.jpg)
@Spf13Author of Hugo, Cobra, Afero, Viper & more