SlideShare une entreprise Scribd logo
1  sur  80
Télécharger pour lire hors ligne
f
e
h
W U
w k
M
w
P n
I
v
ZA
S
U
G
k
C
w
P
U
7
and when to avoid them
Common

Mistakes 

In Go
f
e
h
W U
w k
M
w
P n
I
v
ZA
S
U
G
k
C
w
P
U
@Spf13
Docker 

Chief Operator

&
Author of Hugo,
Cobra, Afero, Viper

f
e
h
W U
w k
M
w
P n
I
v
ZA
S
U
G
k
C
w
P
U
f
e
h
W U
w k
M
w
P n
I
v
ZA
S
U
G
k
C
w
P
U
“Do you want to know the
difference between a
master and a beginner?
The master has failed
more times than the
beginner has tried.”
f
e
h
W U
w k
M
w
P n
I
v
ZA
S
U
G
k
C
w
P
U
–Ed Catmull
“We need to think about failure
differently.
Most people think mistakes are a
necessary evil. Mistakes aren't a
necessary evil, they aren't evil at
all. They are an inevitable
consequence of doing something
new and as such should be seen
as valuable. “
f
e
h
W U
w k
M
w
P n
I
v
ZA
S
U
G
k
C
w
P
U
Mistake . 



Not Accepting
Interfaces
1
f
e
h
W U
w k
M
w
P n
I
v
ZA
S
U
G
k
C
w
P
U
State & Behavior
•Types can express state &
behavior
•State = data structure
•Behavior = methods
f
e
h
W U
w k
M
w
P n
I
v
ZA
S
U
G
k
C
w
P
U
Interfaces
•One of Go’s most powerful
features
•Permits extensibility
•Defined by methods
•Adherence is only satisfied by
behavior
f
e
h
W U
w k
M
w
P n
I
v
ZA
S
U
G
k
C
w
P
U
•Fastest static site
generator
•Native Go
•35+ themes
•Flexible
•100s of contributors
•Powers GopherAcademy
gohugo.io
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!!
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!!
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
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
f
e
h
W U
w k
M
w
P n
I
v
ZA
S
U
G
k
C
w
P
U
Mistake . 



Not Using
Io.Reader &
Io.Writer
2
f
e
h
W U
w k
M
w
P n
I
v
ZA
S
U
G
k
C
w
P
U
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
type Reader interface {
Read(p []byte) (n int, err error)
}
type Writer interface {
Write(p []byte) (n int, err error)
}
Io.Reader & Io.Writer
f
e
h
W U
w k
M
w
P n
I
v
ZA
S
U
G
k
C
w
P
U
Cobra Cli
Commander
•Fast and flexible
•Powers 

Kubernetes & Hugo
•Provides subcommands, help,
man pages, bash autocomplete
github.com/spf13/cobra
// SetOutput sets the destination for
usage and error messages.
// If output is nil, os.Stderr is used.
func (c *Command) SetOutput(o io.Writer) {
c.output = o
}
Cobra Apps Enabled
f
e
h
W U
w k
M
w
P n
I
v
ZA
S
U
G
k
C
w
P
U
Viper
•Configuration management
•Supports json, yaml, toml,
defaults, flags, env vars &
remote key value
•Supports nesting, cascading
& aliases
github.com/spf13/viper
func (v *Viper) ReadBufConfig(buf *bytes.Buffer) error {
v.config = make(map[string]interface{})
v.marshalReader(buf, v.config)
return nil
}
Really Stop Doing This!!
func (v *Viper) ReadConfig(in io.Reader) error {
v.config = make(map[string]interface{})
v.marshalReader(in, v.config)
return nil
}
Instead
f
e
h
W U
w k
M
w
P n
I
v
ZA
S
U
G
k
C
w
P
U
Mistake .



Requiring Broad
Interfaces
3
f
e
h
W U
w k
M
w
P n
I
v
ZA
S
U
G
k
C
w
P
U
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
f
e
h
W U
w k
M
w
P n
I
v
ZA
S
U
G
k
C
w
P
U
Afero Fs
•File system abstraction
•Uses standard OS interfaces
•Drop in replacement for OS
•Great for testing & mocking
•Cross platform memory
backed filesystem
github.com/spf13/afero
type File interface {
io.Closer
io.Reader
io.ReaderAt
io.Seeker
io.Writer
io.WriterAt
}
Composing Interfaces
func ReadIn(f File) {
b := []byte{}
n, err := f.Read(b)
...
}
Requiring Broad Interfaces
func ReadIn(r Reader) {
b := []byte{}
n, err := r.Read(b)
...
}
Requiring Narrow Interfaces
f
e
h
W U
w k
M
w
P n
I
v
ZA
S
U
G
k
C
w
P
U
Mistake .



Methods Vs
Functions
4
f
e
h
W U
w k
M
w
P n
I
v
ZA
S
U
G
k
C
w
P
U
Too Many Methods
•A lot of people from OO
backgrounds overuse
methods
•Natural draw to define
everything via structs and
methods
f
e
h
W U
w k
M
w
P n
I
v
ZA
S
U
G
k
C
w
P
U
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
f
e
h
W U
w k
M
w
P n
I
v
ZA
S
U
G
k
C
w
P
U
What Is A Method?
•Defines the behavior of a type
•A function that operates
against a value
•Should use state
•Logically connected
f
e
h
W U
w k
M
w
P n
I
v
ZA
S
U
G
k
C
w
P
U
Functions Can Be Used With
Interfaces
•Methods, by definition, are
bound to a specific type
•Functions can accept
interfaces as input
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
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
f
e
h
W U
w k
M
w
P n
I
v
ZA
S
U
G
k
C
w
P
U
Mistake . 



Pointers Vs
Values
5
f
e
h
W U
w k
M
w
P n
I
v
ZA
S
U
G
k
C
w
P
U
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)
func (page *Page)
saveSource(b io.Reader)

func (page Page)
saveSource(b io.Reader)
Pointer Vs Value Receivers
f
e
h
W U
w k
M
w
P n
I
v
ZA
S
U
G
k
C
w
P
U
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
f
e
h
W U
w k
M
w
P n
I
v
ZA
S
U
G
k
C
w
P
U
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
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
type Time struct {
sec int64
nsec uintptr
loc *Location
}
func (t Time) IsZero() bool {
return t.sec == 0 && t.nsec == 0
}
Time
f
e
h
W U
w k
M
w
P n
I
v
ZA
S
U
G
k
C
w
P
U
Mistake . 



Thinking Of
Errors As Strings
6
type error interface {
Error() string
}
Error Is An Interface
f
e
h
W U
w k
M
w
P n
I
v
ZA
S
U
G
k
C
w
P
U
Standard Errors
•errors.New(“error here”) is
usually sufficient
•Exported Error Variables
can be easily checked
func NewPage(name string) (p *Page,
err error) {
if len(name) == 0 {
return nil, 

errors.New("Zero length page name")
}



Standard Error
var ErrNoName = errors.New("Zero length
page name")



func NewPage(name string) (*Page, error)
{
if len(name) == 0 {
return nil, ErrNoName
}



Exported Error Var
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
f
e
h
W U
w k
M
w
P n
I
v
ZA
S
U
G
k
C
w
P
U
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)
f
e
h
W U
w k
M
w
P n
I
v
ZA
S
U
G
k
C
w
P
U
•Container runtime
& image format
•Native Go
•22k stars
•1000+ contributors
docker.com
type Error struct {
Code ErrorCode
Message string
Detail interface{}
}
// Error returns a human readable representation of the error.
func (e Error) Error() string {
return fmt.Sprintf("%s: %s",
strings.ToLower(strings.Replace(e.Code.String(), "_", " ",
-1)), e.Message)
}
Internationalization Of Errors
f
e
h
W U
w k
M
w
P n
I
v
ZA
S
U
G
k
C
w
P
U
Go StdLib
•Standard Go 

Libraries
•Comprehensive and 

powerful
•Great examples of “good” Go
http://golang.org/pkg/
// 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
// 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
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
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
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
func baa(f *file) error {
…
n, err := f.WriteAt(x, 3)
if _, ok := err.(*PathError) {
…

} else {
log.Fatalf(err)
}
}
Custom Errors : Os
…
if serr != nil {
if serr, ok := serr.(*PathError); ok &&
serr.Err == syscall.ENOTDIR {
return nil
}
return serr
…
Custom Errors : Os
…
if serr != nil {
if serr, ok := serr.(*PathError); ok &&
serr.Err == syscall.ENOTDIR {
return nil
}
return serr
…
Custom Errors : Os
f
e
h
W U
w k
M
w
P n
I
v
ZA
S
U
G
k
C
w
P
U
Mistake . 



To Be Safe
Or Not To Be
7
f
e
h
W U
w k
M
w
P n
I
v
ZA
S
U
G
k
C
w
P
U
You Can’t Make
Everyone Happy

You Aren’t A Jar
Of Nutella
f
e
h
W U
w k
M
w
P n
I
v
ZA
S
U
G
k
C
w
P
U
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
f
e
h
W U
w k
M
w
P n
I
v
ZA
S
U
G
k
C
w
P
U
Making It Safe
•Sync package provides behavior
to make a value safe (Atomic/
Mutex)
•Channels coordinate values
across go routines by permitting
one go routine to access at a
time
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
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
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
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
}
Safe Maps With Mutex
f
e
h
W U
w k
M
w
P n
I
v
ZA
S
U
G
k
C
w
P
U
Keeping It Unsafe
•Safety comes at a cost
•Imposes behaviors on consumer
•Proper API allows consumers to
add safety as needed
•Consumers can use channels or
mutexes
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
}
Safe Maps With Mutex
f
e
h
W U
w k
M
w
P n
I
v
ZA
S
U
G
k
C
w
P
U
Maps Are Unsafe By Design
•Often safety is unnecessary
•Enables consumers to
implement safety as needed
•Enables consumers to
implement safety as desired
f
e
h
W U
w k
M
w
P n
I
v
ZA
S
U
G
k
C
w
P
U
Biggsest
Mistake;
Not Makimg
Mistakes
f
e
h
W U
w k
M
w
P n
I
v
ZA
S
U
G
k
C
w
P
U
–Ed Catmull
Failure is a manifestation of learning
and exploration. 



If you aren't experiencing failure
than you are making a far worse
mistake. 



You are being driven by the desire
to avoid it.
f
e
h
W U
w k
M
w
P n
I
v
ZA
S
U
G
k
C
w
P
U
@Spf13
Docker 

Chief of Operations

&
Author of Hugo,
Cobra, Afero, Viper


Contenu connexe

Tendances

Functional Design Patterns (DevTernity 2018)
Functional Design Patterns (DevTernity 2018)Functional Design Patterns (DevTernity 2018)
Functional Design Patterns (DevTernity 2018)Scott Wlaschin
 
Why TypeScript?
Why TypeScript?Why TypeScript?
Why TypeScript?FITC
 
Functional Programming in Swift
Functional Programming in SwiftFunctional Programming in Swift
Functional Programming in SwiftSaugat Gautam
 
Лекция 8. Графы. Обходы графов
Лекция 8. Графы. Обходы графовЛекция 8. Графы. Обходы графов
Лекция 8. Графы. Обходы графовMikhail Kurnosov
 
JavaScript Control Statements II
JavaScript Control Statements IIJavaScript Control Statements II
JavaScript Control Statements IIReem Alattas
 
Managing input and output operations in c
Managing input and output operations in cManaging input and output operations in c
Managing input and output operations in cniyamathShariff
 
Angular & RXJS: examples and use cases
Angular & RXJS: examples and use casesAngular & RXJS: examples and use cases
Angular & RXJS: examples and use casesFabio Biondi
 
ZIO: Powerful and Principled Functional Programming in Scala
ZIO: Powerful and Principled Functional Programming in ScalaZIO: Powerful and Principled Functional Programming in Scala
ZIO: Powerful and Principled Functional Programming in ScalaWiem Zine Elabidine
 
Functional Programming 101 with Scala and ZIO @FunctionalWorld
Functional Programming 101 with Scala and ZIO @FunctionalWorldFunctional Programming 101 with Scala and ZIO @FunctionalWorld
Functional Programming 101 with Scala and ZIO @FunctionalWorldJorge Vásquez
 
The aggregate function - from sequential and parallel folds to parallel aggre...
The aggregate function - from sequential and parallel folds to parallel aggre...The aggregate function - from sequential and parallel folds to parallel aggre...
The aggregate function - from sequential and parallel folds to parallel aggre...Philip Schwarz
 
이미지 프로세싱 in Python Open Source - PYCON KOREA 2020
이미지 프로세싱 in Python Open Source - PYCON KOREA 2020이미지 프로세싱 in Python Open Source - PYCON KOREA 2020
이미지 프로세싱 in Python Open Source - PYCON KOREA 2020Kenneth Ceyer
 
Introduction to RxJS
Introduction to RxJSIntroduction to RxJS
Introduction to RxJSAbul Hasan
 
JavaScript - Chapter 6 - Basic Functions
 JavaScript - Chapter 6 - Basic Functions JavaScript - Chapter 6 - Basic Functions
JavaScript - Chapter 6 - Basic FunctionsWebStackAcademy
 
3.2 javascript regex
3.2 javascript regex3.2 javascript regex
3.2 javascript regexJalpesh Vasa
 
Redux Saga - Under the hood
Redux Saga - Under the hoodRedux Saga - Under the hood
Redux Saga - Under the hoodWaqqas Jabbar
 
Comparison between runtime polymorphism and compile time polymorphism
Comparison between runtime polymorphism and compile time polymorphismComparison between runtime polymorphism and compile time polymorphism
Comparison between runtime polymorphism and compile time polymorphismCHAITALIUKE1
 
Advanced Javascript
Advanced JavascriptAdvanced Javascript
Advanced JavascriptAdieu
 

Tendances (20)

Vulkan 1.1 Reference Guide
Vulkan 1.1 Reference GuideVulkan 1.1 Reference Guide
Vulkan 1.1 Reference Guide
 
Functional Design Patterns (DevTernity 2018)
Functional Design Patterns (DevTernity 2018)Functional Design Patterns (DevTernity 2018)
Functional Design Patterns (DevTernity 2018)
 
Why TypeScript?
Why TypeScript?Why TypeScript?
Why TypeScript?
 
Functional Programming in Swift
Functional Programming in SwiftFunctional Programming in Swift
Functional Programming in Swift
 
Лекция 8. Графы. Обходы графов
Лекция 8. Графы. Обходы графовЛекция 8. Графы. Обходы графов
Лекция 8. Графы. Обходы графов
 
JavaScript Control Statements II
JavaScript Control Statements IIJavaScript Control Statements II
JavaScript Control Statements II
 
Managing input and output operations in c
Managing input and output operations in cManaging input and output operations in c
Managing input and output operations in c
 
Angular & RXJS: examples and use cases
Angular & RXJS: examples and use casesAngular & RXJS: examples and use cases
Angular & RXJS: examples and use cases
 
ZIO: Powerful and Principled Functional Programming in Scala
ZIO: Powerful and Principled Functional Programming in ScalaZIO: Powerful and Principled Functional Programming in Scala
ZIO: Powerful and Principled Functional Programming in Scala
 
Functional Programming 101 with Scala and ZIO @FunctionalWorld
Functional Programming 101 with Scala and ZIO @FunctionalWorldFunctional Programming 101 with Scala and ZIO @FunctionalWorld
Functional Programming 101 with Scala and ZIO @FunctionalWorld
 
The aggregate function - from sequential and parallel folds to parallel aggre...
The aggregate function - from sequential and parallel folds to parallel aggre...The aggregate function - from sequential and parallel folds to parallel aggre...
The aggregate function - from sequential and parallel folds to parallel aggre...
 
이미지 프로세싱 in Python Open Source - PYCON KOREA 2020
이미지 프로세싱 in Python Open Source - PYCON KOREA 2020이미지 프로세싱 in Python Open Source - PYCON KOREA 2020
이미지 프로세싱 in Python Open Source - PYCON KOREA 2020
 
Introduction to RxJS
Introduction to RxJSIntroduction to RxJS
Introduction to RxJS
 
JS Event Loop
JS Event LoopJS Event Loop
JS Event Loop
 
JavaScript - Chapter 6 - Basic Functions
 JavaScript - Chapter 6 - Basic Functions JavaScript - Chapter 6 - Basic Functions
JavaScript - Chapter 6 - Basic Functions
 
3.2 javascript regex
3.2 javascript regex3.2 javascript regex
3.2 javascript regex
 
Redux Saga - Under the hood
Redux Saga - Under the hoodRedux Saga - Under the hood
Redux Saga - Under the hood
 
Comparison between runtime polymorphism and compile time polymorphism
Comparison between runtime polymorphism and compile time polymorphismComparison between runtime polymorphism and compile time polymorphism
Comparison between runtime polymorphism and compile time polymorphism
 
Advanced Javascript
Advanced JavascriptAdvanced Javascript
Advanced Javascript
 
Regular Expression
Regular ExpressionRegular Expression
Regular Expression
 

Similaire à 7 Common Mistakes in Go (2015)

golang_getting_started.pptx
golang_getting_started.pptxgolang_getting_started.pptx
golang_getting_started.pptxGuy Komari
 
Kamil witecki asynchronous, yet readable, code
Kamil witecki asynchronous, yet readable, codeKamil witecki asynchronous, yet readable, code
Kamil witecki asynchronous, yet readable, codeKamil Witecki
 
To GO or not to GO
To GO or not to GOTo GO or not to GO
To GO or not to GOsuperstas88
 
Go 1.10 Release Party - PDX Go
Go 1.10 Release Party - PDX GoGo 1.10 Release Party - PDX Go
Go 1.10 Release Party - PDX GoRodolfo Carvalho
 
7 Common mistakes in Go and when to avoid them
7 Common mistakes in Go and when to avoid them7 Common mistakes in Go and when to avoid them
7 Common mistakes in Go and when to avoid themSteven Francia
 
Beauty and Power of Go
Beauty and Power of GoBeauty and Power of Go
Beauty and Power of GoFrank Müller
 
Building resilient services in go
Building resilient services in goBuilding resilient services in go
Building resilient services in goJaehue Jang
 
printf("%s from %c to Z, in %d minutes!\n", "printf", 'A', 45);
printf("%s from %c to Z, in %d minutes!\n", "printf", 'A', 45);printf("%s from %c to Z, in %d minutes!\n", "printf", 'A', 45);
printf("%s from %c to Z, in %d minutes!\n", "printf", 'A', 45);Joel Porquet
 
88 c programs 15184
88 c programs 1518488 c programs 15184
88 c programs 15184Sumit Saini
 
Bologna Developer Zone - About Kotlin
Bologna Developer Zone - About KotlinBologna Developer Zone - About Kotlin
Bologna Developer Zone - About KotlinMarco Vasapollo
 
05 pig user defined functions (udfs)
05 pig user defined functions (udfs)05 pig user defined functions (udfs)
05 pig user defined functions (udfs)Subhas Kumar Ghosh
 
Incredible Machine with Pipelines and Generators
Incredible Machine with Pipelines and GeneratorsIncredible Machine with Pipelines and Generators
Incredible Machine with Pipelines and Generatorsdantleech
 
Geeks Anonymes - Le langage Go
Geeks Anonymes - Le langage GoGeeks Anonymes - Le langage Go
Geeks Anonymes - Le langage GoGeeks Anonymes
 
The Perl API for the Mortally Terrified (beta)
The Perl API for the Mortally Terrified (beta)The Perl API for the Mortally Terrified (beta)
The Perl API for the Mortally Terrified (beta)Mike Friedman
 
Introduction to source{d} Engine and source{d} Lookout
Introduction to source{d} Engine and source{d} Lookout Introduction to source{d} Engine and source{d} Lookout
Introduction to source{d} Engine and source{d} Lookout source{d}
 

Similaire à 7 Common Mistakes in Go (2015) (20)

golang_getting_started.pptx
golang_getting_started.pptxgolang_getting_started.pptx
golang_getting_started.pptx
 
Kamil witecki asynchronous, yet readable, code
Kamil witecki asynchronous, yet readable, codeKamil witecki asynchronous, yet readable, code
Kamil witecki asynchronous, yet readable, code
 
Presentation1
Presentation1Presentation1
Presentation1
 
To GO or not to GO
To GO or not to GOTo GO or not to GO
To GO or not to GO
 
Go 1.10 Release Party - PDX Go
Go 1.10 Release Party - PDX GoGo 1.10 Release Party - PDX Go
Go 1.10 Release Party - PDX Go
 
2 data and c
2 data and c2 data and c
2 data and c
 
7 Common mistakes in Go and when to avoid them
7 Common mistakes in Go and when to avoid them7 Common mistakes in Go and when to avoid them
7 Common mistakes in Go and when to avoid them
 
Beauty and Power of Go
Beauty and Power of GoBeauty and Power of Go
Beauty and Power of Go
 
Building resilient services in go
Building resilient services in goBuilding resilient services in go
Building resilient services in go
 
printf("%s from %c to Z, in %d minutes!\n", "printf", 'A', 45);
printf("%s from %c to Z, in %d minutes!\n", "printf", 'A', 45);printf("%s from %c to Z, in %d minutes!\n", "printf", 'A', 45);
printf("%s from %c to Z, in %d minutes!\n", "printf", 'A', 45);
 
88 c programs 15184
88 c programs 1518488 c programs 15184
88 c programs 15184
 
88 c-programs
88 c-programs88 c-programs
88 c-programs
 
Go Lang Tutorial
Go Lang TutorialGo Lang Tutorial
Go Lang Tutorial
 
Bologna Developer Zone - About Kotlin
Bologna Developer Zone - About KotlinBologna Developer Zone - About Kotlin
Bologna Developer Zone - About Kotlin
 
05 pig user defined functions (udfs)
05 pig user defined functions (udfs)05 pig user defined functions (udfs)
05 pig user defined functions (udfs)
 
Incredible Machine with Pipelines and Generators
Incredible Machine with Pipelines and GeneratorsIncredible Machine with Pipelines and Generators
Incredible Machine with Pipelines and Generators
 
Geeks Anonymes - Le langage Go
Geeks Anonymes - Le langage GoGeeks Anonymes - Le langage Go
Geeks Anonymes - Le langage Go
 
The Perl API for the Mortally Terrified (beta)
The Perl API for the Mortally Terrified (beta)The Perl API for the Mortally Terrified (beta)
The Perl API for the Mortally Terrified (beta)
 
Txjs
TxjsTxjs
Txjs
 
Introduction to source{d} Engine and source{d} Lookout
Introduction to source{d} Engine and source{d} Lookout Introduction to source{d} Engine and source{d} Lookout
Introduction to source{d} Engine and source{d} Lookout
 

Plus de Steven Francia

State of the Gopher Nation - Golang - August 2017
State of the Gopher Nation - Golang - August 2017State of the Gopher Nation - Golang - August 2017
State of the Gopher Nation - Golang - August 2017Steven Francia
 
The Future of the Operating System - Keynote LinuxCon 2015
The Future of the Operating System -  Keynote LinuxCon 2015The Future of the Operating System -  Keynote LinuxCon 2015
The Future of the Operating System - Keynote LinuxCon 2015Steven Francia
 
What every successful open source project needs
What every successful open source project needsWhat every successful open source project needs
What every successful open source project needsSteven Francia
 
Painless Data Storage with MongoDB & Go
Painless Data Storage with MongoDB & Go Painless Data Storage with MongoDB & Go
Painless Data Storage with MongoDB & Go Steven Francia
 
Getting Started with Go
Getting Started with GoGetting Started with Go
Getting Started with GoSteven Francia
 
Build your first MongoDB App in Ruby @ StrangeLoop 2013
Build your first MongoDB App in Ruby @ StrangeLoop 2013Build your first MongoDB App in Ruby @ StrangeLoop 2013
Build your first MongoDB App in Ruby @ StrangeLoop 2013Steven Francia
 
Modern Database Systems (for Genealogy)
Modern Database Systems (for Genealogy)Modern Database Systems (for Genealogy)
Modern Database Systems (for Genealogy)Steven Francia
 
Introduction to MongoDB and Hadoop
Introduction to MongoDB and HadoopIntroduction to MongoDB and Hadoop
Introduction to MongoDB and HadoopSteven Francia
 
MongoDB, Hadoop and humongous data - MongoSV 2012
MongoDB, Hadoop and humongous data - MongoSV 2012MongoDB, Hadoop and humongous data - MongoSV 2012
MongoDB, Hadoop and humongous data - MongoSV 2012Steven Francia
 
Big data for the rest of us
Big data for the rest of usBig data for the rest of us
Big data for the rest of usSteven Francia
 
OSCON 2012 MongoDB Tutorial
OSCON 2012 MongoDB TutorialOSCON 2012 MongoDB Tutorial
OSCON 2012 MongoDB TutorialSteven Francia
 
Replication, Durability, and Disaster Recovery
Replication, Durability, and Disaster RecoveryReplication, Durability, and Disaster Recovery
Replication, Durability, and Disaster RecoverySteven Francia
 
Multi Data Center Strategies
Multi Data Center StrategiesMulti Data Center Strategies
Multi Data Center StrategiesSteven Francia
 
NoSQL databases and managing big data
NoSQL databases and managing big dataNoSQL databases and managing big data
NoSQL databases and managing big dataSteven Francia
 
MongoDB, Hadoop and Humongous Data
MongoDB, Hadoop and Humongous DataMongoDB, Hadoop and Humongous Data
MongoDB, Hadoop and Humongous DataSteven Francia
 
Hybrid MongoDB and RDBMS Applications
Hybrid MongoDB and RDBMS ApplicationsHybrid MongoDB and RDBMS Applications
Hybrid MongoDB and RDBMS ApplicationsSteven Francia
 
Building your first application w/mongoDB MongoSV2011
Building your first application w/mongoDB MongoSV2011Building your first application w/mongoDB MongoSV2011
Building your first application w/mongoDB MongoSV2011Steven Francia
 

Plus de Steven Francia (20)

State of the Gopher Nation - Golang - August 2017
State of the Gopher Nation - Golang - August 2017State of the Gopher Nation - Golang - August 2017
State of the Gopher Nation - Golang - August 2017
 
The Future of the Operating System - Keynote LinuxCon 2015
The Future of the Operating System -  Keynote LinuxCon 2015The Future of the Operating System -  Keynote LinuxCon 2015
The Future of the Operating System - Keynote LinuxCon 2015
 
What every successful open source project needs
What every successful open source project needsWhat every successful open source project needs
What every successful open source project needs
 
Painless Data Storage with MongoDB & Go
Painless Data Storage with MongoDB & Go Painless Data Storage with MongoDB & Go
Painless Data Storage with MongoDB & Go
 
Getting Started with Go
Getting Started with GoGetting Started with Go
Getting Started with Go
 
Build your first MongoDB App in Ruby @ StrangeLoop 2013
Build your first MongoDB App in Ruby @ StrangeLoop 2013Build your first MongoDB App in Ruby @ StrangeLoop 2013
Build your first MongoDB App in Ruby @ StrangeLoop 2013
 
Modern Database Systems (for Genealogy)
Modern Database Systems (for Genealogy)Modern Database Systems (for Genealogy)
Modern Database Systems (for Genealogy)
 
Introduction to MongoDB and Hadoop
Introduction to MongoDB and HadoopIntroduction to MongoDB and Hadoop
Introduction to MongoDB and Hadoop
 
Future of data
Future of dataFuture of data
Future of data
 
MongoDB, Hadoop and humongous data - MongoSV 2012
MongoDB, Hadoop and humongous data - MongoSV 2012MongoDB, Hadoop and humongous data - MongoSV 2012
MongoDB, Hadoop and humongous data - MongoSV 2012
 
Big data for the rest of us
Big data for the rest of usBig data for the rest of us
Big data for the rest of us
 
OSCON 2012 MongoDB Tutorial
OSCON 2012 MongoDB TutorialOSCON 2012 MongoDB Tutorial
OSCON 2012 MongoDB Tutorial
 
Replication, Durability, and Disaster Recovery
Replication, Durability, and Disaster RecoveryReplication, Durability, and Disaster Recovery
Replication, Durability, and Disaster Recovery
 
Multi Data Center Strategies
Multi Data Center StrategiesMulti Data Center Strategies
Multi Data Center Strategies
 
NoSQL databases and managing big data
NoSQL databases and managing big dataNoSQL databases and managing big data
NoSQL databases and managing big data
 
MongoDB, Hadoop and Humongous Data
MongoDB, Hadoop and Humongous DataMongoDB, Hadoop and Humongous Data
MongoDB, Hadoop and Humongous Data
 
MongoDB and hadoop
MongoDB and hadoopMongoDB and hadoop
MongoDB and hadoop
 
MongoDB for Genealogy
MongoDB for GenealogyMongoDB for Genealogy
MongoDB for Genealogy
 
Hybrid MongoDB and RDBMS Applications
Hybrid MongoDB and RDBMS ApplicationsHybrid MongoDB and RDBMS Applications
Hybrid MongoDB and RDBMS Applications
 
Building your first application w/mongoDB MongoSV2011
Building your first application w/mongoDB MongoSV2011Building your first application w/mongoDB MongoSV2011
Building your first application w/mongoDB MongoSV2011
 

Dernier

+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...Health
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionSolGuruz
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerThousandEyes
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsAndolasoft Inc
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...MyIntelliSource, Inc.
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsJhone kinadey
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfkalichargn70th171
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...ICS
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxbodapatigopi8531
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...panagenda
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...OnePlan Solutions
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AIABDERRAOUF MEHENNI
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️anilsa9823
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 

Dernier (20)

+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS LiveVip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptx
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 

7 Common Mistakes in Go (2015)

  • 1. f e h W U w k M w P n I v ZA S U G k C w P U 7 and when to avoid them Common
 Mistakes 
 In Go
  • 2. f e h W U w k M w P n I v ZA S U G k C w P U @Spf13 Docker 
 Chief Operator
 & Author of Hugo, Cobra, Afero, Viper

  • 3. f e h W U w k M w P n I v ZA S U G k C w P U
  • 4. f e h W U w k M w P n I v ZA S U G k C w P U “Do you want to know the difference between a master and a beginner? The master has failed more times than the beginner has tried.”
  • 5. f e h W U w k M w P n I v ZA S U G k C w P U –Ed Catmull “We need to think about failure differently. Most people think mistakes are a necessary evil. Mistakes aren't a necessary evil, they aren't evil at all. They are an inevitable consequence of doing something new and as such should be seen as valuable. “
  • 6.
  • 7.
  • 8. f e h W U w k M w P n I v ZA S U G k C w P U Mistake . 
 
 Not Accepting Interfaces 1
  • 9. f e h W U w k M w P n I v ZA S U G k C w P U State & Behavior •Types can express state & behavior •State = data structure •Behavior = methods
  • 10. f e h W U w k M w P n I v ZA S U G k C w P U Interfaces •One of Go’s most powerful features •Permits extensibility •Defined by methods •Adherence is only satisfied by behavior
  • 11. f e h W U w k M w P n I v ZA S U G k C w P U •Fastest static site generator •Native Go •35+ themes •Flexible •100s of contributors •Powers GopherAcademy gohugo.io
  • 12. 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!!
  • 13. 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!!
  • 14. 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
  • 15. 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
  • 16. f e h W U w k M w P n I v ZA S U G k C w P U Mistake . 
 
 Not Using Io.Reader & Io.Writer 2
  • 17. f e h W U w k M w P n I v ZA S U G k C w P U 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
  • 18. type Reader interface { Read(p []byte) (n int, err error) } type Writer interface { Write(p []byte) (n int, err error) } Io.Reader & Io.Writer
  • 19. f e h W U w k M w P n I v ZA S U G k C w P U Cobra Cli Commander •Fast and flexible •Powers 
 Kubernetes & Hugo •Provides subcommands, help, man pages, bash autocomplete github.com/spf13/cobra
  • 20. // SetOutput sets the destination for usage and error messages. // If output is nil, os.Stderr is used. func (c *Command) SetOutput(o io.Writer) { c.output = o } Cobra Apps Enabled
  • 21. f e h W U w k M w P n I v ZA S U G k C w P U Viper •Configuration management •Supports json, yaml, toml, defaults, flags, env vars & remote key value •Supports nesting, cascading & aliases github.com/spf13/viper
  • 22. func (v *Viper) ReadBufConfig(buf *bytes.Buffer) error { v.config = make(map[string]interface{}) v.marshalReader(buf, v.config) return nil } Really Stop Doing This!!
  • 23. func (v *Viper) ReadConfig(in io.Reader) error { v.config = make(map[string]interface{}) v.marshalReader(in, v.config) return nil } Instead
  • 24. f e h W U w k M w P n I v ZA S U G k C w P U Mistake .
 
 Requiring Broad Interfaces 3
  • 25. f e h W U w k M w P n I v ZA S U G k C w P U 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
  • 26. f e h W U w k M w P n I v ZA S U G k C w P U Afero Fs •File system abstraction •Uses standard OS interfaces •Drop in replacement for OS •Great for testing & mocking •Cross platform memory backed filesystem github.com/spf13/afero
  • 27. type File interface { io.Closer io.Reader io.ReaderAt io.Seeker io.Writer io.WriterAt } Composing Interfaces
  • 28. func ReadIn(f File) { b := []byte{} n, err := f.Read(b) ... } Requiring Broad Interfaces
  • 29. func ReadIn(r Reader) { b := []byte{} n, err := r.Read(b) ... } Requiring Narrow Interfaces
  • 30. f e h W U w k M w P n I v ZA S U G k C w P U Mistake .
 
 Methods Vs Functions 4
  • 31. f e h W U w k M w P n I v ZA S U G k C w P U Too Many Methods •A lot of people from OO backgrounds overuse methods •Natural draw to define everything via structs and methods
  • 32. f e h W U w k M w P n I v ZA S U G k C w P U 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
  • 33. f e h W U w k M w P n I v ZA S U G k C w P U What Is A Method? •Defines the behavior of a type •A function that operates against a value •Should use state •Logically connected
  • 34. f e h W U w k M w P n I v ZA S U G k C w P U Functions Can Be Used With Interfaces •Methods, by definition, are bound to a specific type •Functions can accept interfaces as input
  • 35.
  • 36. 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
  • 37. 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
  • 38. f e h W U w k M w P n I v ZA S U G k C w P U Mistake . 
 
 Pointers Vs Values 5
  • 39. f e h W U w k M w P n I v ZA S U G k C w P U 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)
  • 40. func (page *Page) saveSource(b io.Reader)
 func (page Page) saveSource(b io.Reader) Pointer Vs Value Receivers
  • 41. f e h W U w k M w P n I v ZA S U G k C w P U 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
  • 42. f e h W U w k M w P n I v ZA S U G k C w P U 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
  • 43.
  • 44. 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
  • 45. type Time struct { sec int64 nsec uintptr loc *Location } func (t Time) IsZero() bool { return t.sec == 0 && t.nsec == 0 } Time
  • 46. f e h W U w k M w P n I v ZA S U G k C w P U Mistake . 
 
 Thinking Of Errors As Strings 6
  • 47. type error interface { Error() string } Error Is An Interface
  • 48. f e h W U w k M w P n I v ZA S U G k C w P U Standard Errors •errors.New(“error here”) is usually sufficient •Exported Error Variables can be easily checked
  • 49.
  • 50. func NewPage(name string) (p *Page, err error) { if len(name) == 0 { return nil, 
 errors.New("Zero length page name") }
 
 Standard Error
  • 51. var ErrNoName = errors.New("Zero length page name")
 
 func NewPage(name string) (*Page, error) { if len(name) == 0 { return nil, ErrNoName }
 
 Exported Error Var
  • 52. 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
  • 53. f e h W U w k M w P n I v ZA S U G k C w P U 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)
  • 54. f e h W U w k M w P n I v ZA S U G k C w P U •Container runtime & image format •Native Go •22k stars •1000+ contributors docker.com
  • 55. type Error struct { Code ErrorCode Message string Detail interface{} } // Error returns a human readable representation of the error. func (e Error) Error() string { return fmt.Sprintf("%s: %s", strings.ToLower(strings.Replace(e.Code.String(), "_", " ", -1)), e.Message) } Internationalization Of Errors
  • 56. f e h W U w k M w P n I v ZA S U G k C w P U Go StdLib •Standard Go 
 Libraries •Comprehensive and 
 powerful •Great examples of “good” Go http://golang.org/pkg/
  • 57. // 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
  • 58. // 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
  • 59. 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
  • 60. 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
  • 61. 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
  • 62. func baa(f *file) error { … n, err := f.WriteAt(x, 3) if _, ok := err.(*PathError) { …
 } else { log.Fatalf(err) } } Custom Errors : Os
  • 63. … if serr != nil { if serr, ok := serr.(*PathError); ok && serr.Err == syscall.ENOTDIR { return nil } return serr … Custom Errors : Os
  • 64. … if serr != nil { if serr, ok := serr.(*PathError); ok && serr.Err == syscall.ENOTDIR { return nil } return serr … Custom Errors : Os
  • 65. f e h W U w k M w P n I v ZA S U G k C w P U Mistake . 
 
 To Be Safe Or Not To Be 7
  • 66. f e h W U w k M w P n I v ZA S U G k C w P U You Can’t Make Everyone Happy
 You Aren’t A Jar Of Nutella
  • 67. f e h W U w k M w P n I v ZA S U G k C w P U 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
  • 68. f e h W U w k M w P n I v ZA S U G k C w P U Making It Safe •Sync package provides behavior to make a value safe (Atomic/ Mutex) •Channels coordinate values across go routines by permitting one go routine to access at a time
  • 69.
  • 70. 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
  • 71. 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
  • 72. 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
  • 73. 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 } Safe Maps With Mutex
  • 74. f e h W U w k M w P n I v ZA S U G k C w P U Keeping It Unsafe •Safety comes at a cost •Imposes behaviors on consumer •Proper API allows consumers to add safety as needed •Consumers can use channels or mutexes
  • 75. 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 } Safe Maps With Mutex
  • 76. f e h W U w k M w P n I v ZA S U G k C w P U Maps Are Unsafe By Design •Often safety is unnecessary •Enables consumers to implement safety as needed •Enables consumers to implement safety as desired
  • 77. f e h W U w k M w P n I v ZA S U G k C w P U Biggsest Mistake; Not Makimg Mistakes
  • 78. f e h W U w k M w P n I v ZA S U G k C w P U –Ed Catmull Failure is a manifestation of learning and exploration. 
 
 If you aren't experiencing failure than you are making a far worse mistake. 
 
 You are being driven by the desire to avoid it.
  • 79.
  • 80. f e h W U w k M w P n I v ZA S U G k C w P U @Spf13 Docker 
 Chief of Operations
 & Author of Hugo, Cobra, Afero, Viper