SlideShare a Scribd company logo
FINDING A USEFUL OUTLET FOR MY
MANY ADVENTURES IN GO
@feyeleanor
I HAVE A PROBLEM
(I'm a physicist, of course I have a problem!)
I TALK ABOUT GO
the exciting life of a jet-setting dilettante
!! BUT I DON'T BLOG !!
SO WRITING A BOOK?
NOT HAPPENING..?
Create a Book
The Book
BOOK TITLE
BOOK URL
MAIN LANGUAGE USED IN THE BOOK
This helps us to set up the fonts that we use in your book. If you are writing with a mixture of languages that
includes Chinese, Japanese or Korean, then you should check out the language switcher section of the
manual. If you have troubles with characters not showing up properly, please let us know at
hello@leanpub.com.
How do you want to write?
The Next Leanpub Bestseller
bookleanpub.com/
English !
"
# $
0 "
LEANPUB
writing a book without working at it
LEANPUB
➤ take existing content and publish it in book form
➤ aimed at bloggers with existing articles
➤ but also works with
➤ slide decks
➤ code repos
➤ word documents
Hello World 62
Exceptions
If we consider these programs for a minute or two it becomes apparent that propagating our errors this
way works very well when we wish to deal with an error immediately, which is usually the case. However
there are occasions when an error will need to be propagated through several layers of function calls, and
when this is the case there’s a lot of boilerplate involved in intermediate functions in the call stack.
We can do away with much of this by rolling our own lightweight equivalent of exceptions using defer
and the panic() and recover() calls. In the next example we’ll do just this, introducing the Exception type
which is an interface with error embedded within it. This means that any error value will also be an
Exception value.
Why doesn’t Go have native exceptions?
A common criticism of Go is its use of inline error handling rather than the kind of exception-
handling mechanism we’re developing here. The language FAQ⁶ has a coherent explanation
which is worth quoting in full:
Why does Go not have exceptions?
We believe that coupling exceptions to a control structure, as in the try-catch-
finally idiom, results in convoluted code. It also tends to encourage programmers
to label too many ordinary errors, such as failing to open a file, as exceptional.
Go takes a different approach. For plain error handling, Go’s multi-value returns
make it easy to report an error without overloading the return value. A canonical
error type, coupled with Go’s other features, makes error handling pleasant but
quite different from that in other languages.
Go also has a couple of built-in functions to signal and recover from truly
exceptional conditions. The recovery mechanism is executed only as part of a
function’s state being torn down after an error, which is sufficient to handle
catastrophe but requires no extra control structures and, when used well, can
result in clean error-handling code.
See the Defer, Panic, and Recover⁷ article for details.
Go is a conservative language with a minimal set of features chosen primarily to avoid
unnecessary magic in code, with all the maintenance problems that can bring. As you’ll
find by the end of this chapter, exception handling is most decidedly magical if it’s to be
elegant, potentially introducing several layers of source-code abstraction between the logic
for performing an operation and the error recovery code which cleans up when it goes wrong.
That’s not to say that exception-style mechanisms aren’t useful for certain tasks, and as I
hope the following examples will demonstrate (as well as those in later chapters) it’s perfectly
reasonable to implement variants which suit your purpose when the need arises.
⁶https://golang.org/doc/faq#exceptions
⁷https://golang.org/doc/articles/defer_panic_recover.html
A Go Developer’s Notebook
or, What I Did During My Holidays
Eleanor McHugh
This book is for sale at http://leanpub.com/GoNotebook
This version was published on 2016-11-01
This is a Leanpub book. Leanpub empowers authors and publishers with the Lean Publishing process.
Lean Publishing is the act of publishing an in-progress ebook using lightweight tools and many
iterations to get reader feedback, pivot until you have the right book and build traction once you do.
© 2014 - 2016 Eleanor McHugh
Contents
Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . i
Hello World . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Packages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
Constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Encapsulation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Generalisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
Startup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
HTTP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
The Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
Handling Signals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
TCP/IP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
UDP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
RSA obfuscated UDP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
Error Handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
Echo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
Arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
Flags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
Command-line Boilerplate and Standard I/O . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
Conditional Flags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
Regular Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
Interactive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
Pipes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
Encryption . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
Software Machines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
Functional Programming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
First-Class and Higher-Order Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
Pure Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
Currying and Partial Application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
Lazy Evaluation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
Recursion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
COOL SALES
PITCH FOR
LEANPUB…
BUT WHAT'S
YOUR DAMN
BOOK
ABOUT?
Hello World
It’s a tradition in programming books to start with a canonical “Hello World” example and whilst I’ve
never felt the usual presentation is particularly enlightening, I know we can spice things up a little to
provide useful insights into how we write Go programs.
Let’s begin with the simplest Go program that will output text to the console.
Example 1.1
1 package main
2
3 func main() {
4 println("hello world")
5 }
The first thing to note is that every Go source file belongs to a package, with the main package defining
an executable program whilst all other packages represent libraries.
1 package main
For the main package to be executable it needs to include a main() function, which will be called following
program initialisation.
3 func main() {
Notice that unlike C/C++ the main() function neither takes parameters nor has a return value. Whenever
a program should interact with command-line parameters or return a value on termination these tasks are
HELLO WORLD?
well… sort of…
IT'S A LIVING BOOK
THOUGH IT'S PRETTY
SLEEPY AT PRESENT
WRITING A LIVING BOOK
➤ inspired by Neal Stephenson's A Young Lady's Illustrated Primer
➤ (every programmer should read The Diamond Age & Cryptonomicon)
➤ only without the interactivity
➤ pick your topic of interest
➤ keep adding new material until you run out
➤ each chapter has a theme
➤ and is structured as an adventure
➤ it should push its subject matter to breaking point
➤ so the reader doesn't only learn solutions to existing problems
➤ they learn how to solve new problems
Hello World
It’s a tradition in programming books to start with a canonical “Hello World” example and whilst I’ve
never felt the usual presentation is particularly enlightening, I know we can spice things up a little to
provide useful insights into how we write Go programs.
Let’s begin with the simplest Go program that will output text to the console.
Example 1.1
1 package main
2
3 func main() {
4 println("hello world")
5 }
The first thing to note is that every Go source file belongs to a package, with the main package defining
an executable program whilst all other packages represent libraries.
1 package main
For the main package to be executable it needs to include a main() function, which will be called following
program initialisation.
3 func main() {
Notice that unlike C/C++ the main() function neither takes parameters nor has a return value. Whenever
a program should interact with command-line parameters or return a value on termination these tasks are
FREE SHOULD BE USEFUL
60+ pages of Hello World examples
Hello World 53
16 func main() {
17 Serve(":1025", func(connection *UDPConn, c *UDPAddr, packet *bytes.Buffer) (n int) {
18 var key rsa.PublicKey
19 if e := gob.NewDecoder(packet).Decode(&key); e == nil {
20 if response, e := rsa.EncryptOAEP(sha1.New(), rand.Reader, &key, HELLO_WORLD, RSA
21 _LABEL); e == nil {
22 n, _ = connection.WriteToUDP(response, c)
23 }
24 }
25 return
26 })
27 }
28
29 func Serve(address string, f func(*UDPConn, *UDPAddr, *bytes.Buffer) int) {
30 Launch(address, func(connection *UDPConn) {
31 for {
32 buffer := make([]byte, 1024)
33 if n, client, e := connection.ReadFromUDP(buffer); e == nil {
34 go func(c *UDPAddr, b []byte) {
35 if n := f(connection, c, bytes.NewBuffer(b)); n != 0 {
36 Println(n, "bytes written to", c)
37 }
38 }(client, buffer[:n])
39 }
40 }
41 })
42 }
43
44 func Launch(address string, f func(*UDPConn)) {
45 if a, e := ResolveUDPAddr("udp", address); e == nil {
FREE SHOULD BE USEFUL
make a sound introduction to network encryption
Hello World 13
In the function signature we use v …interface{} to declare a parameter v which takes any number of
values. These are received by print() as a sequence of values and the subsequent call to Println(v…) uses
this same sequence as this is the sequence expected by Println().
So why did we use …interface{} in defining our parameters instead of the more obvious …string? The
Println() function is itself defined as Println(…interface{}) so to provide a sequence of values en masse
we likewise need to use …interface{} in the type signature of our function. Otherwise we’d have to create
a []interface{} (a slice of interface{} values, a concept we’ll cover in detail in a later chanpter) and copy
each individual element into it before passing it into Println().
Encapsulation
In this chapter we’ll for the most part be using Go’s primitive types and types defined in various
standard packages without any comment on their structure, however a key aspect of modern programming
languages is the encapsulation of related data into structured types and Go supports this via the struct
type. A struct describes an area of allocated memory which is subdivided into slots for holding named
values, where each named value has its own type. A typical example of a struct in action would be
Example 1.17
1 package main
2
3 import "fmt"
4
5 type Message struct {
6 X string
7 y *string
8 }
9
10 func (v Message) Print() {
11 if v.y != nil {
12 fmt.Println(v.X, *v.y)
13 } else {
14 fmt.Println(v.X)
15 }
16 }
17
18 func (v *Message) Store(x, y string) {
19 v.X = x
20 v.y = &y
21 }
22
23 func main() {
24 m := &Message{}
25 m.Print()
26 m.Store("Hello", "world")
27 m.Print()
28 }
ENCAPSULATION
package main
import "fmt"
type Message struct {
X string
y *string
}
func (v Message) Print() {
if v.y != nil {
fmt.Println(v.X, *v.y)
} else {
fmt.Println(v.X)
}
}
func (v *Message) Store(x, y string) {
v.X = x
v.y = &y
}
func main() {
m := &Message{}
m.Print()
m.Store("Hello", "world")
m.Print()
}
ENCAPSULATION
package main
import "fmt"
type Message struct {
X string
y *string
}
func (v Message) Print() {
if v.y != nil {
fmt.Println(v.X, *v.y)
} else {
fmt.Println(v.X)
}
}
func (v *Message) Store(x, y string) {
v.X = x
v.y = &y
}
func main() {
m := &Message{}
m.Print()
m.Store("Hello", "world")
m.Print()
}
package main
import "fmt"
type HelloWorld bool
func (h HelloWorld) String() (r string) {
if h {
r = "Hello world"
}
return
}
type Message struct {
HelloWorld
}
func main() {
m := &Message{ HelloWorld: true }
fmt.Println(m)
m.HelloWorld = false
fmt.Println(m)
m.HelloWorld = true
fmt.Println(m)
}
Hello World 22
Startup
One of the less-discussed aspects of computer programs is the need to initialise many of them to a pre-
determined state before they begin executing. Whilst this is probably the worst place to start discussing
what to many people may appear to be advanced topics, one of my goals in this chapter is to cover all of
the structural elements that we’ll meet when we examine more complex programs.
Every Go package may contain one or more init() functions specifying actions that should be taken during
program initialisation. This is the one case I’m aware of where multiple declarations of the same identifier
can occur without either resulting in a compilation error or the shadowing of a variable. In the following
example we use the init() function to assign a value to our world variable
Example 1.26
1 package main
2 import . "fmt"
3
4 const Hello = "hello"
5 var world string
6
7 func init() {
8 world = "world"
9 }
10
11 func main() {
12 Println(Hello, world)
13 }
However the init() function can contain any valid Go code, allowing us to place the whole of our program
in init() and leaving main() as a stub to convince the compiler that this is indeed a valid Go program.
Example 1.27
1 package main
2 import . "fmt"
3
4 const Hello = "hello"
5 var world string
6
7 func init() {
8 world = "world"
9 Println(Hello, world)
10 }
11
12 func main() {}
When there are multiple init() functions the order in which they’re executed is indeterminate so in general
it’s best not to do this unless you can be certain the init() functions don’t interact in any way. The following
happens to work as expected on my development computer but an implementation of Go could just as
easily arrange it to run in reverse order or even leave deciding the order of execution until runtime.
STARTUP
package main
import . "fmt"
const Hello = "hello"
var world string
func init() {
world = "world"
}
func main() {
Println(Hello, world)
}
Hello World 23
Example 1.28
1 package main
2 import . "fmt"
3
4 const Hello = "hello"
5 var world string
6
7 func init() {
8 Print(Hello, " ")
9 world = "world"
10 }
11
12 func init() {
13 Printf("%vn", world)
14 }
15
16 func main() {}
HTTP
So far our treatment of Hello World has followed the traditional route of printing a preset message to
the console. Anyone would think we were living in the fuddy-duddy mainframe era of the 1970s instead
of the shiny 21st Century, when web and mobile applications rule the world.
Turning Hello World into a web application is surprisingly simple, as the following example demon-
strates.
Example 1.29
1 package main
2 import (
3 . "fmt"
4 "net/http"
5 )
6
7 const MESSAGE = "hello world"
8 const ADDRESS = ":1024"
9
10 func main() {
11 http.HandleFunc("/hello", Hello)
12 if e := http.ListenAndServe(ADDRESS, nil); e != nil {
13 Println(e)
14 }
15 }
16
17 func Hello(w http.ResponseWriter, r *http.Request) {
18 w.Header().Set("Content-Type", "text/plain")
19 Fprintf(w, MESSAGE)
20 }
HTTP
package main
import (
. "fmt"
"net/http"
)
const MESSAGE = "hello world"
const ADDRESS = ":1024"
func main() {
http.HandleFunc("/hello", Hello)
if e := http.ListenAndServe(ADDRESS, nil); e != nil {
Println(e)
}
}
func Hello(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain")
Fprintf(w, MESSAGE)
}
HTTP/S
package main
import (
. "fmt"
. "net/http"
)
const ADDRESS = ":1024"
const SECURE_ADDRESS = ":1025"
func main() {
message := "hello world"
HandleFunc("/hello", func(w ResponseWriter, r *Request) {
w.Header().Set("Content-Type", "text/plain")
Fprintf(w, message)
})
Spawn(
func() { ListenAndServeTLS(SECURE_ADDRESS, "cert.pem", "key.pem", nil) },
func() { ListenAndServe(ADDRESS, nil) },
)
}
func Spawn(f ...func()) {
done := make(chan bool)
for _, s := range f {
go func(server func()) {
server()
done <- true
}(s)
}
for l := len(f); l > 0; l-- {
<- done
}
}
package main
import (
. "fmt"
. "net/http"
"sync"
)
const ADDRESS = ":1024"
const SECURE_ADDRESS = ":1025"
var servers sync.WaitGroup
func main() {
message := "hello world"
HandleFunc("/hello", func(w ResponseWriter, r *Request) {
w.Header().Set("Content-Type", "text/plain")
Fprintf(w, message)
})
Launch(func() {
ListenAndServe(ADDRESS, nil)
})
Launch(func() {
ListenAndServeTLS(SECURE_ADDRESS, "cert.pem", "key.pem", nil)
})
servers.Wait()
}
func Launch(f func()) {
servers.Add(1)
go func() {
defer servers.Done()
f()
}()
}
Hello World 35
The Environment
The main shells used with modern operating systems (Linux, OSX, FreeBSD, Windows, etc.) provide a
persistent environment which can be queried by running programs, allowing a user to store configuration
values in named variables. Go supports reading and writing these variables using the os package functions
Getenv() and Setenv().
In our next example we’re going to query the environment for the variable SERVE_HTTP which we’ll
assume contains the default address on which to serve unencrypted web content.
Example 1.43
1 package main
2 import (
3 . "fmt"
4 . "net/http"
5 "os"
6 "sync"
7 )
8
9 const SECURE_ADDRESS = ":1025"
10
11 var address string
12 var servers sync.WaitGroup
13
14 func init() {
15 if address = os.Getenv("SERVE_HTTP"); address == "" {
16 address = ":1024"
17 }
18 }
19
20 func main() {
21 message := "hello world"
22 HandleFunc("/hello", func(w ResponseWriter, r *Request) {
23 w.Header().Set("Content-Type", "text/plain")
24 Fprintf(w, message)
25 })
26
27 Launch(func() {
28 ListenAndServe(address, nil)
29 })
30
31 Launch(func() {
32 ListenAndServeTLS(SECURE_ADDRESS, "cert.pem", "key.pem", nil)
33 })
34 servers.Wait()
35 }
36
THE ENVIRONMENT
package main
import (
. "fmt"
. "net/http"
"os"
"sync"
)
const SECURE_ADDRESS = ":1025"
var address string
var servers sync.WaitGroup
func init() {
if address = os.Getenv("SERVE_HTTP"); address == "" {
address = ":1024"
}
}
func main() {
message := "hello world"
HandleFunc("/hello", func(w ResponseWriter, r *Request) {
w.Header().Set("Content-Type", "text/plain")
Fprintf(w, message)
})
Launch(func() {
ListenAndServe(address, nil)
})
Launch(func() {
ListenAndServeTLS(SECURE_ADDRESS, "cert.pem", "key.pem", nil)
})
servers.Wait()
}
func Launch(f func()) {
servers.Add(1)
go func() {
defer servers.Done()
f()
}()
}
Hello World 49
UDP
Both TCP/IP and HTTP communications are connection-oriented and this involves a reasonable amount
of handshaking and error-correction to assemble data packets in the correct order. For most applications
this is exactly how we want to organise our network communications but sometimes the size of our
messages is sufficiently small that we can fit them into individual packets, and when this is the case the
UDP protocol is an ideal candidate.
As with our previous examples we still need both server and client applications.
Example 1.53 UDP server
1 package main
2
3 import (
4 . "fmt"
5 "net"
6 )
7
8 var HELLO_WORLD = ([]byte)("Hello Worldn")
9
10 func main() {
11 if address, e := net.ResolveUDPAddr("udp", ":1024"); e == nil {
12 if server, e := net.ListenUDP("udp", address); e == nil {
13 for buffer := MakeBuffer(); ; buffer = MakeBuffer() {
14 if n, client, e := server.ReadFromUDP(buffer); e == nil {
15 go func(c *net.UDPAddr, packet []byte) {
16 if n, e := server.WriteToUDP(HELLO_WORLD, c); e == nil {
17 Printf("%v bytes written to: %vn", n, c)
18 }
19 }(client, buffer[:n])
20 }
21 }
22 }
23 }
24 }
25
26 func MakeBuffer() (r []byte) {
27 return make([]byte, 1024)
28 }
We have a somewhat more complex code pattern here than with TCP/IP to take account of the difference
in underlying semantics: UDP is an unreliable transport dealing in individual packets (datagrams) which
are independent of each other, therefore a server doesn’t maintain streams to any of its clients and these are
responsible for any error-correction or packet ordering which may be necessary to coordinate successive
signals. Because of these differences from TCP/IP we end up with the following generic workflow
• net.ResolveUDPAddr() to resolve the address
• net.ListenUDP() opens a UDP port and listens for traffic
UDP
package main
import (
. "fmt"
"net"
)
var HELLO_WORLD = ([]byte)("Hello Worldn")
func main() {
if address, e := net.ResolveUDPAddr("udp", ":1024"); e == nil {
if server, e := net.ListenUDP("udp", address); e == nil {
for buffer := MakeBuffer(); ; buffer = MakeBuffer() {
if n, client, e := server.ReadFromUDP(buffer); e == nil {
go func(c *net.UDPAddr, packet []byte) {
if n, e := server.WriteToUDP(HELLO_WORLD, c); e == nil {
Printf("%v bytes written to: %vn", n, c)
}
}(client, buffer[:n])
}
}
}
}
}
func MakeBuffer() (r []byte) {
return make([]byte, 1024)
}
UDP SERVER & CLIENT
package main
import (
. "fmt"
"net"
)
var HELLO_WORLD = ([]byte)("Hello Worldn")
func main() {
if address, e := net.ResolveUDPAddr("udp", ":1024"); e == nil {
if server, e := net.ListenUDP("udp", address); e == nil {
for buffer := MakeBuffer(); ; buffer = MakeBuffer() {
if n, client, e := server.ReadFromUDP(buffer); e == nil {
go func(c *net.UDPAddr, packet []byte) {
if n, e := server.WriteToUDP(HELLO_WORLD, c); e == nil {
Printf("%v bytes written to: %vn", n, c)
}
}(client, buffer[:n])
}
}
}
}
}
func MakeBuffer() (r []byte) {
return make([]byte, 1024)
}
package main
import (
"bufio"
. "fmt"
"net"
)
var CRLF = ([]byte)("n")
func main() {
if address, e := net.ResolveUDPAddr("udp", ":1024"); e == nil {
if server, e := net.DialUDP("udp", nil, address); e == nil {
defer server.Close()
for i := 0; i < 3; i++ {
if _, e = server.Write(CRLF); e == nil {
if text, e := bufio.NewReader(server).ReadString('n'); e == nil {
Printf("%v: %v", i, text)
}
}
}
}
}
}
Packages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
Constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Encapsulation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Generalisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
Startup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
HTTP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
The Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
Handling Signals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
TCP/IP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
UDP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
RSA obfuscated UDP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
Error Handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
Echo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
Arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
Flags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
Command-line Boilerplate and Standard I/O . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
Conditional Flags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
Regular Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
Interactive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
Pipes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
Encryption . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
Software Machines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
Functional Programming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
First-Class and Higher-Order Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
BEHIND THE PAYWALL
lots of stuff you can get for free
SLIDE DECKS
http://slideshare.net/feyeleanor
CODE REPOS
http://github.com/feyeleanor
CONFERENCE TALKS
DON'T LIKE MY BOOK?
!! WRITE YOUR OWN !!

More Related Content

What's hot

Java tutorial
Java tutorialJava tutorial
Java tutorial
HarikaReddy115
 
Flash as3 programming
Flash as3 programmingFlash as3 programming
Flash as3 programming
allen cervantes
 
TechBook: EMC Compatibility Features for IBM Copy Services on z/OS
TechBook: EMC Compatibility Features for IBM Copy Services on z/OSTechBook: EMC Compatibility Features for IBM Copy Services on z/OS
TechBook: EMC Compatibility Features for IBM Copy Services on z/OS
EMC
 
Complete book of phone scripts
Complete book of phone scriptsComplete book of phone scripts
Complete book of phone scripts
Dinh Giang Le
 
Java completed assignment
Java completed assignmentJava completed assignment
Java completed assignment
Krishnamohan Ramachandran
 
Zebra Designer PRO - Manual do Software
Zebra Designer PRO - Manual do SoftwareZebra Designer PRO - Manual do Software
Zebra Designer PRO - Manual do Software
UseZ
 
Zrp manual 2
Zrp manual 2Zrp manual 2
Zrp manual 2
Ronald Hutabarat
 
Mikroc pro avr_manual_v100
Mikroc pro avr_manual_v100Mikroc pro avr_manual_v100
Mikroc pro avr_manual_v100
EEMPROM
 
Call pilot call center setup and operation
Call pilot call center setup and operationCall pilot call center setup and operation
Call pilot call center setup and operation
kyawzay htet
 
C++ For Quantitative Finance
C++ For Quantitative FinanceC++ For Quantitative Finance
C++ For Quantitative Finance
ASAD ALI
 
Reinventing the wheel: libmc
Reinventing the wheel: libmcReinventing the wheel: libmc
Reinventing the wheel: libmc
Myautsai PAN
 
Flash as3 programming
Flash as3 programmingFlash as3 programming
Flash as3 programmingsubhash85
 
Video Jet 10 Manual
Video Jet 10 ManualVideo Jet 10 Manual
Video Jet 10 Manualguest0ea020
 

What's hot (15)

Java tutorial
Java tutorialJava tutorial
Java tutorial
 
Flash as3 programming
Flash as3 programmingFlash as3 programming
Flash as3 programming
 
TechBook: EMC Compatibility Features for IBM Copy Services on z/OS
TechBook: EMC Compatibility Features for IBM Copy Services on z/OSTechBook: EMC Compatibility Features for IBM Copy Services on z/OS
TechBook: EMC Compatibility Features for IBM Copy Services on z/OS
 
Complete book of phone scripts
Complete book of phone scriptsComplete book of phone scripts
Complete book of phone scripts
 
Java completed assignment
Java completed assignmentJava completed assignment
Java completed assignment
 
Zebra Designer PRO - Manual do Software
Zebra Designer PRO - Manual do SoftwareZebra Designer PRO - Manual do Software
Zebra Designer PRO - Manual do Software
 
Perl-crash-course
Perl-crash-coursePerl-crash-course
Perl-crash-course
 
Dpu 7910a
Dpu 7910aDpu 7910a
Dpu 7910a
 
Zrp manual 2
Zrp manual 2Zrp manual 2
Zrp manual 2
 
Mikroc pro avr_manual_v100
Mikroc pro avr_manual_v100Mikroc pro avr_manual_v100
Mikroc pro avr_manual_v100
 
Call pilot call center setup and operation
Call pilot call center setup and operationCall pilot call center setup and operation
Call pilot call center setup and operation
 
C++ For Quantitative Finance
C++ For Quantitative FinanceC++ For Quantitative Finance
C++ For Quantitative Finance
 
Reinventing the wheel: libmc
Reinventing the wheel: libmcReinventing the wheel: libmc
Reinventing the wheel: libmc
 
Flash as3 programming
Flash as3 programmingFlash as3 programming
Flash as3 programming
 
Video Jet 10 Manual
Video Jet 10 ManualVideo Jet 10 Manual
Video Jet 10 Manual
 

Similar to Finding a useful outlet for my many Adventures in go

Clean Architectures in Python.pdf
Clean Architectures in Python.pdfClean Architectures in Python.pdf
Clean Architectures in Python.pdf
HonorioCandelario
 
The road-to-learn-react
The road-to-learn-reactThe road-to-learn-react
The road-to-learn-react
imdurgesh
 
Linux kernel module programming guide
Linux kernel module programming guideLinux kernel module programming guide
Linux kernel module programming guide
Dũng Nguyễn
 
Chuck Moore Book 2012 01 26
Chuck Moore Book 2012 01 26Chuck Moore Book 2012 01 26
Chuck Moore Book 2012 01 26
JuergenPintaske
 
plsqladvanced.pdf
plsqladvanced.pdfplsqladvanced.pdf
plsqladvanced.pdf
Thirupathis9
 
Mastering Oracle PL/SQL: Practical Solutions
Mastering Oracle PL/SQL: Practical SolutionsMastering Oracle PL/SQL: Practical Solutions
Mastering Oracle PL/SQL: Practical Solutions
MURTHYVENKAT2
 
Learn python the right way
Learn python the right wayLearn python the right way
Learn python the right way
DianaLaCruz2
 
Borland c++ version_3.0_users_guide_1991
Borland c++ version_3.0_users_guide_1991Borland c++ version_3.0_users_guide_1991
Borland c++ version_3.0_users_guide_1991
praveen188668
 
Cs5 5-final-print-guide
Cs5 5-final-print-guideCs5 5-final-print-guide
Cs5 5-final-print-guide
Trang Đoàn
 
photoshop_reference.pdf
photoshop_reference.pdfphotoshop_reference.pdf
photoshop_reference.pdf
RamaDaoud1
 
10. cutipa portillo, edy dany
10. cutipa portillo, edy dany10. cutipa portillo, edy dany
10. cutipa portillo, edy dany
IESTPTECNOTRONIC
 
Peachpit mastering xcode 4 develop and design sep 2011
Peachpit mastering xcode 4 develop and design sep 2011Peachpit mastering xcode 4 develop and design sep 2011
Peachpit mastering xcode 4 develop and design sep 2011
Jose Erickson
 
E views 9 command ref
E views 9 command refE views 9 command ref
E views 9 command ref
Ibrahima Bakhoum
 
Acro6 js guide
Acro6 js guideAcro6 js guide
Acro6 js guide
Faina Fridman
 
Manual flash
Manual flashManual flash
Manual flashRui Silva
 
Chuck moorebook2012 01_27
Chuck moorebook2012 01_27Chuck moorebook2012 01_27
Chuck moorebook2012 01_27juergenuk
 
Java
JavaJava
In designcs5 scripting tutorial
In designcs5 scripting tutorialIn designcs5 scripting tutorial
In designcs5 scripting tutorial
Mustfeez Rasul
 

Similar to Finding a useful outlet for my many Adventures in go (20)

Clean Architectures in Python.pdf
Clean Architectures in Python.pdfClean Architectures in Python.pdf
Clean Architectures in Python.pdf
 
Cake php cookbook
Cake php cookbookCake php cookbook
Cake php cookbook
 
The road-to-learn-react
The road-to-learn-reactThe road-to-learn-react
The road-to-learn-react
 
Linux kernel module programming guide
Linux kernel module programming guideLinux kernel module programming guide
Linux kernel module programming guide
 
Chuck Moore Book 2012 01 26
Chuck Moore Book 2012 01 26Chuck Moore Book 2012 01 26
Chuck Moore Book 2012 01 26
 
plsqladvanced.pdf
plsqladvanced.pdfplsqladvanced.pdf
plsqladvanced.pdf
 
Mastering Oracle PL/SQL: Practical Solutions
Mastering Oracle PL/SQL: Practical SolutionsMastering Oracle PL/SQL: Practical Solutions
Mastering Oracle PL/SQL: Practical Solutions
 
Learn python the right way
Learn python the right wayLearn python the right way
Learn python the right way
 
Borland c++ version_3.0_users_guide_1991
Borland c++ version_3.0_users_guide_1991Borland c++ version_3.0_users_guide_1991
Borland c++ version_3.0_users_guide_1991
 
Cs5 5-final-print-guide
Cs5 5-final-print-guideCs5 5-final-print-guide
Cs5 5-final-print-guide
 
Tutor Py
Tutor PyTutor Py
Tutor Py
 
photoshop_reference.pdf
photoshop_reference.pdfphotoshop_reference.pdf
photoshop_reference.pdf
 
10. cutipa portillo, edy dany
10. cutipa portillo, edy dany10. cutipa portillo, edy dany
10. cutipa portillo, edy dany
 
Peachpit mastering xcode 4 develop and design sep 2011
Peachpit mastering xcode 4 develop and design sep 2011Peachpit mastering xcode 4 develop and design sep 2011
Peachpit mastering xcode 4 develop and design sep 2011
 
E views 9 command ref
E views 9 command refE views 9 command ref
E views 9 command ref
 
Acro6 js guide
Acro6 js guideAcro6 js guide
Acro6 js guide
 
Manual flash
Manual flashManual flash
Manual flash
 
Chuck moorebook2012 01_27
Chuck moorebook2012 01_27Chuck moorebook2012 01_27
Chuck moorebook2012 01_27
 
Java
JavaJava
Java
 
In designcs5 scripting tutorial
In designcs5 scripting tutorialIn designcs5 scripting tutorial
In designcs5 scripting tutorial
 

More from Eleanor McHugh

[2023] Putting the R! in R&D.pdf
[2023] Putting the R! in R&D.pdf[2023] Putting the R! in R&D.pdf
[2023] Putting the R! in R&D.pdf
Eleanor McHugh
 
Generics, Reflection, and Efficient Collections
Generics, Reflection, and Efficient CollectionsGenerics, Reflection, and Efficient Collections
Generics, Reflection, and Efficient Collections
Eleanor McHugh
 
The Relevance of Liveness - Biometrics and Data Integrity
The Relevance of Liveness - Biometrics and Data IntegrityThe Relevance of Liveness - Biometrics and Data Integrity
The Relevance of Liveness - Biometrics and Data Integrity
Eleanor McHugh
 
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]The Browser Environment - A Systems Programmer's Perspective [sinatra edition]
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]
Eleanor McHugh
 
The Browser Environment - A Systems Programmer's Perspective
The Browser Environment - A Systems Programmer's PerspectiveThe Browser Environment - A Systems Programmer's Perspective
The Browser Environment - A Systems Programmer's Perspective
Eleanor McHugh
 
Go for the paranoid network programmer, 3rd edition
Go for the paranoid network programmer, 3rd editionGo for the paranoid network programmer, 3rd edition
Go for the paranoid network programmer, 3rd edition
Eleanor McHugh
 
An introduction to functional programming with Go [redux]
An introduction to functional programming with Go [redux]An introduction to functional programming with Go [redux]
An introduction to functional programming with Go [redux]
Eleanor McHugh
 
An introduction to functional programming with go
An introduction to functional programming with goAn introduction to functional programming with go
An introduction to functional programming with go
Eleanor McHugh
 
Implementing virtual machines in go & c 2018 redux
Implementing virtual machines in go & c 2018 reduxImplementing virtual machines in go & c 2018 redux
Implementing virtual machines in go & c 2018 redux
Eleanor McHugh
 
Identity & trust in Monitored Spaces
Identity & trust in Monitored SpacesIdentity & trust in Monitored Spaces
Identity & trust in Monitored Spaces
Eleanor McHugh
 
Don't Ask, Don't Tell - The Virtues of Privacy By Design
Don't Ask, Don't Tell - The Virtues of Privacy By DesignDon't Ask, Don't Tell - The Virtues of Privacy By Design
Don't Ask, Don't Tell - The Virtues of Privacy By Design
Eleanor McHugh
 
Don't ask, don't tell the virtues of privacy by design
Don't ask, don't tell   the virtues of privacy by designDon't ask, don't tell   the virtues of privacy by design
Don't ask, don't tell the virtues of privacy by design
Eleanor McHugh
 
Anonymity, identity, trust
Anonymity, identity, trustAnonymity, identity, trust
Anonymity, identity, trust
Eleanor McHugh
 
Going Loopy - Adventures in Iteration with Google Go
Going Loopy - Adventures in Iteration with Google GoGoing Loopy - Adventures in Iteration with Google Go
Going Loopy - Adventures in Iteration with Google Go
Eleanor McHugh
 
Distributed Ledgers: Anonymity & Immutability at Scale
Distributed Ledgers: Anonymity & Immutability at ScaleDistributed Ledgers: Anonymity & Immutability at Scale
Distributed Ledgers: Anonymity & Immutability at Scale
Eleanor McHugh
 
Hello Go
Hello GoHello Go
Hello Go
Eleanor McHugh
 
Go for the paranoid network programmer, 2nd edition
Go for the paranoid network programmer, 2nd editionGo for the paranoid network programmer, 2nd edition
Go for the paranoid network programmer, 2nd edition
Eleanor McHugh
 
Going Loopy: Adventures in Iteration with Go
Going Loopy: Adventures in Iteration with GoGoing Loopy: Adventures in Iteration with Go
Going Loopy: Adventures in Iteration with Go
Eleanor McHugh
 
Anonymity, trust, accountability
Anonymity, trust, accountabilityAnonymity, trust, accountability
Anonymity, trust, accountability
Eleanor McHugh
 
Implementing Virtual Machines in Go & C
Implementing Virtual Machines in Go & CImplementing Virtual Machines in Go & C
Implementing Virtual Machines in Go & C
Eleanor McHugh
 

More from Eleanor McHugh (20)

[2023] Putting the R! in R&D.pdf
[2023] Putting the R! in R&D.pdf[2023] Putting the R! in R&D.pdf
[2023] Putting the R! in R&D.pdf
 
Generics, Reflection, and Efficient Collections
Generics, Reflection, and Efficient CollectionsGenerics, Reflection, and Efficient Collections
Generics, Reflection, and Efficient Collections
 
The Relevance of Liveness - Biometrics and Data Integrity
The Relevance of Liveness - Biometrics and Data IntegrityThe Relevance of Liveness - Biometrics and Data Integrity
The Relevance of Liveness - Biometrics and Data Integrity
 
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]The Browser Environment - A Systems Programmer's Perspective [sinatra edition]
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]
 
The Browser Environment - A Systems Programmer's Perspective
The Browser Environment - A Systems Programmer's PerspectiveThe Browser Environment - A Systems Programmer's Perspective
The Browser Environment - A Systems Programmer's Perspective
 
Go for the paranoid network programmer, 3rd edition
Go for the paranoid network programmer, 3rd editionGo for the paranoid network programmer, 3rd edition
Go for the paranoid network programmer, 3rd edition
 
An introduction to functional programming with Go [redux]
An introduction to functional programming with Go [redux]An introduction to functional programming with Go [redux]
An introduction to functional programming with Go [redux]
 
An introduction to functional programming with go
An introduction to functional programming with goAn introduction to functional programming with go
An introduction to functional programming with go
 
Implementing virtual machines in go & c 2018 redux
Implementing virtual machines in go & c 2018 reduxImplementing virtual machines in go & c 2018 redux
Implementing virtual machines in go & c 2018 redux
 
Identity & trust in Monitored Spaces
Identity & trust in Monitored SpacesIdentity & trust in Monitored Spaces
Identity & trust in Monitored Spaces
 
Don't Ask, Don't Tell - The Virtues of Privacy By Design
Don't Ask, Don't Tell - The Virtues of Privacy By DesignDon't Ask, Don't Tell - The Virtues of Privacy By Design
Don't Ask, Don't Tell - The Virtues of Privacy By Design
 
Don't ask, don't tell the virtues of privacy by design
Don't ask, don't tell   the virtues of privacy by designDon't ask, don't tell   the virtues of privacy by design
Don't ask, don't tell the virtues of privacy by design
 
Anonymity, identity, trust
Anonymity, identity, trustAnonymity, identity, trust
Anonymity, identity, trust
 
Going Loopy - Adventures in Iteration with Google Go
Going Loopy - Adventures in Iteration with Google GoGoing Loopy - Adventures in Iteration with Google Go
Going Loopy - Adventures in Iteration with Google Go
 
Distributed Ledgers: Anonymity & Immutability at Scale
Distributed Ledgers: Anonymity & Immutability at ScaleDistributed Ledgers: Anonymity & Immutability at Scale
Distributed Ledgers: Anonymity & Immutability at Scale
 
Hello Go
Hello GoHello Go
Hello Go
 
Go for the paranoid network programmer, 2nd edition
Go for the paranoid network programmer, 2nd editionGo for the paranoid network programmer, 2nd edition
Go for the paranoid network programmer, 2nd edition
 
Going Loopy: Adventures in Iteration with Go
Going Loopy: Adventures in Iteration with GoGoing Loopy: Adventures in Iteration with Go
Going Loopy: Adventures in Iteration with Go
 
Anonymity, trust, accountability
Anonymity, trust, accountabilityAnonymity, trust, accountability
Anonymity, trust, accountability
 
Implementing Virtual Machines in Go & C
Implementing Virtual Machines in Go & CImplementing Virtual Machines in Go & C
Implementing Virtual Machines in Go & C
 

Recently uploaded

Corporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMSCorporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMS
Tendenci - The Open Source AMS (Association Management Software)
 
Quarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden ExtensionsQuarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden Extensions
Max Andersen
 
RISE with SAP and Journey to the Intelligent Enterprise
RISE with SAP and Journey to the Intelligent EnterpriseRISE with SAP and Journey to the Intelligent Enterprise
RISE with SAP and Journey to the Intelligent Enterprise
Srikant77
 
Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"
Donna Lenk
 
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoamOpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
takuyayamamoto1800
 
First Steps with Globus Compute Multi-User Endpoints
First Steps with Globus Compute Multi-User EndpointsFirst Steps with Globus Compute Multi-User Endpoints
First Steps with Globus Compute Multi-User Endpoints
Globus
 
Understanding Globus Data Transfers with NetSage
Understanding Globus Data Transfers with NetSageUnderstanding Globus Data Transfers with NetSage
Understanding Globus Data Transfers with NetSage
Globus
 
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus
 
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERRORTROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
Tier1 app
 
Prosigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology SolutionsProsigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology Solutions
Prosigns
 
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Globus
 
Lecture 1 Introduction to games development
Lecture 1 Introduction to games developmentLecture 1 Introduction to games development
Lecture 1 Introduction to games development
abdulrafaychaudhry
 
BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024
Ortus Solutions, Corp
 
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdfDominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
AMB-Review
 
Into the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdfInto the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdf
Ortus Solutions, Corp
 
Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024
Globus
 
Enterprise Resource Planning System in Telangana
Enterprise Resource Planning System in TelanganaEnterprise Resource Planning System in Telangana
Enterprise Resource Planning System in Telangana
NYGGS Automation Suite
 
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Shahin Sheidaei
 
2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx
Georgi Kodinov
 
Graphic Design Crash Course for beginners
Graphic Design Crash Course for beginnersGraphic Design Crash Course for beginners
Graphic Design Crash Course for beginners
e20449
 

Recently uploaded (20)

Corporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMSCorporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMS
 
Quarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden ExtensionsQuarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden Extensions
 
RISE with SAP and Journey to the Intelligent Enterprise
RISE with SAP and Journey to the Intelligent EnterpriseRISE with SAP and Journey to the Intelligent Enterprise
RISE with SAP and Journey to the Intelligent Enterprise
 
Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"
 
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoamOpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
 
First Steps with Globus Compute Multi-User Endpoints
First Steps with Globus Compute Multi-User EndpointsFirst Steps with Globus Compute Multi-User Endpoints
First Steps with Globus Compute Multi-User Endpoints
 
Understanding Globus Data Transfers with NetSage
Understanding Globus Data Transfers with NetSageUnderstanding Globus Data Transfers with NetSage
Understanding Globus Data Transfers with NetSage
 
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024
 
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERRORTROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
 
Prosigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology SolutionsProsigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology Solutions
 
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
 
Lecture 1 Introduction to games development
Lecture 1 Introduction to games developmentLecture 1 Introduction to games development
Lecture 1 Introduction to games development
 
BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024
 
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdfDominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
 
Into the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdfInto the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdf
 
Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024
 
Enterprise Resource Planning System in Telangana
Enterprise Resource Planning System in TelanganaEnterprise Resource Planning System in Telangana
Enterprise Resource Planning System in Telangana
 
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
 
2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx
 
Graphic Design Crash Course for beginners
Graphic Design Crash Course for beginnersGraphic Design Crash Course for beginners
Graphic Design Crash Course for beginners
 

Finding a useful outlet for my many Adventures in go

  • 1. FINDING A USEFUL OUTLET FOR MY MANY ADVENTURES IN GO @feyeleanor
  • 2. I HAVE A PROBLEM (I'm a physicist, of course I have a problem!)
  • 4. the exciting life of a jet-setting dilettante
  • 5. !! BUT I DON'T BLOG !!
  • 6. SO WRITING A BOOK?
  • 8. Create a Book The Book BOOK TITLE BOOK URL MAIN LANGUAGE USED IN THE BOOK This helps us to set up the fonts that we use in your book. If you are writing with a mixture of languages that includes Chinese, Japanese or Korean, then you should check out the language switcher section of the manual. If you have troubles with characters not showing up properly, please let us know at hello@leanpub.com. How do you want to write? The Next Leanpub Bestseller bookleanpub.com/ English ! " # $ 0 " LEANPUB writing a book without working at it
  • 9. LEANPUB ➤ take existing content and publish it in book form ➤ aimed at bloggers with existing articles ➤ but also works with ➤ slide decks ➤ code repos ➤ word documents
  • 10.
  • 11.
  • 12. Hello World 62 Exceptions If we consider these programs for a minute or two it becomes apparent that propagating our errors this way works very well when we wish to deal with an error immediately, which is usually the case. However there are occasions when an error will need to be propagated through several layers of function calls, and when this is the case there’s a lot of boilerplate involved in intermediate functions in the call stack. We can do away with much of this by rolling our own lightweight equivalent of exceptions using defer and the panic() and recover() calls. In the next example we’ll do just this, introducing the Exception type which is an interface with error embedded within it. This means that any error value will also be an Exception value. Why doesn’t Go have native exceptions? A common criticism of Go is its use of inline error handling rather than the kind of exception- handling mechanism we’re developing here. The language FAQ⁶ has a coherent explanation which is worth quoting in full: Why does Go not have exceptions? We believe that coupling exceptions to a control structure, as in the try-catch- finally idiom, results in convoluted code. It also tends to encourage programmers to label too many ordinary errors, such as failing to open a file, as exceptional. Go takes a different approach. For plain error handling, Go’s multi-value returns make it easy to report an error without overloading the return value. A canonical error type, coupled with Go’s other features, makes error handling pleasant but quite different from that in other languages. Go also has a couple of built-in functions to signal and recover from truly exceptional conditions. The recovery mechanism is executed only as part of a function’s state being torn down after an error, which is sufficient to handle catastrophe but requires no extra control structures and, when used well, can result in clean error-handling code. See the Defer, Panic, and Recover⁷ article for details. Go is a conservative language with a minimal set of features chosen primarily to avoid unnecessary magic in code, with all the maintenance problems that can bring. As you’ll find by the end of this chapter, exception handling is most decidedly magical if it’s to be elegant, potentially introducing several layers of source-code abstraction between the logic for performing an operation and the error recovery code which cleans up when it goes wrong. That’s not to say that exception-style mechanisms aren’t useful for certain tasks, and as I hope the following examples will demonstrate (as well as those in later chapters) it’s perfectly reasonable to implement variants which suit your purpose when the need arises. ⁶https://golang.org/doc/faq#exceptions ⁷https://golang.org/doc/articles/defer_panic_recover.html A Go Developer’s Notebook or, What I Did During My Holidays Eleanor McHugh This book is for sale at http://leanpub.com/GoNotebook This version was published on 2016-11-01 This is a Leanpub book. Leanpub empowers authors and publishers with the Lean Publishing process. Lean Publishing is the act of publishing an in-progress ebook using lightweight tools and many iterations to get reader feedback, pivot until you have the right book and build traction once you do. © 2014 - 2016 Eleanor McHugh Contents Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . i Hello World . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 Packages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 Constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 Encapsulation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 Generalisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 Startup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 HTTP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 The Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 Handling Signals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 TCP/IP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 UDP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 RSA obfuscated UDP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 Error Handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 Echo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72 Arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72 Flags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 Command-line Boilerplate and Standard I/O . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 Conditional Flags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90 Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 Regular Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 Interactive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 Pipes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 Encryption . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 Software Machines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94 memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94 Functional Programming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95 First-Class and Higher-Order Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95 Pure Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95 Currying and Partial Application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95 Lazy Evaluation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95 Recursion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
  • 13.
  • 16. Hello World It’s a tradition in programming books to start with a canonical “Hello World” example and whilst I’ve never felt the usual presentation is particularly enlightening, I know we can spice things up a little to provide useful insights into how we write Go programs. Let’s begin with the simplest Go program that will output text to the console. Example 1.1 1 package main 2 3 func main() { 4 println("hello world") 5 } The first thing to note is that every Go source file belongs to a package, with the main package defining an executable program whilst all other packages represent libraries. 1 package main For the main package to be executable it needs to include a main() function, which will be called following program initialisation. 3 func main() { Notice that unlike C/C++ the main() function neither takes parameters nor has a return value. Whenever a program should interact with command-line parameters or return a value on termination these tasks are HELLO WORLD? well… sort of…
  • 19. WRITING A LIVING BOOK ➤ inspired by Neal Stephenson's A Young Lady's Illustrated Primer ➤ (every programmer should read The Diamond Age & Cryptonomicon) ➤ only without the interactivity ➤ pick your topic of interest ➤ keep adding new material until you run out ➤ each chapter has a theme ➤ and is structured as an adventure ➤ it should push its subject matter to breaking point ➤ so the reader doesn't only learn solutions to existing problems ➤ they learn how to solve new problems
  • 20. Hello World It’s a tradition in programming books to start with a canonical “Hello World” example and whilst I’ve never felt the usual presentation is particularly enlightening, I know we can spice things up a little to provide useful insights into how we write Go programs. Let’s begin with the simplest Go program that will output text to the console. Example 1.1 1 package main 2 3 func main() { 4 println("hello world") 5 } The first thing to note is that every Go source file belongs to a package, with the main package defining an executable program whilst all other packages represent libraries. 1 package main For the main package to be executable it needs to include a main() function, which will be called following program initialisation. 3 func main() { Notice that unlike C/C++ the main() function neither takes parameters nor has a return value. Whenever a program should interact with command-line parameters or return a value on termination these tasks are FREE SHOULD BE USEFUL 60+ pages of Hello World examples
  • 21. Hello World 53 16 func main() { 17 Serve(":1025", func(connection *UDPConn, c *UDPAddr, packet *bytes.Buffer) (n int) { 18 var key rsa.PublicKey 19 if e := gob.NewDecoder(packet).Decode(&key); e == nil { 20 if response, e := rsa.EncryptOAEP(sha1.New(), rand.Reader, &key, HELLO_WORLD, RSA 21 _LABEL); e == nil { 22 n, _ = connection.WriteToUDP(response, c) 23 } 24 } 25 return 26 }) 27 } 28 29 func Serve(address string, f func(*UDPConn, *UDPAddr, *bytes.Buffer) int) { 30 Launch(address, func(connection *UDPConn) { 31 for { 32 buffer := make([]byte, 1024) 33 if n, client, e := connection.ReadFromUDP(buffer); e == nil { 34 go func(c *UDPAddr, b []byte) { 35 if n := f(connection, c, bytes.NewBuffer(b)); n != 0 { 36 Println(n, "bytes written to", c) 37 } 38 }(client, buffer[:n]) 39 } 40 } 41 }) 42 } 43 44 func Launch(address string, f func(*UDPConn)) { 45 if a, e := ResolveUDPAddr("udp", address); e == nil { FREE SHOULD BE USEFUL make a sound introduction to network encryption
  • 22. Hello World 13 In the function signature we use v …interface{} to declare a parameter v which takes any number of values. These are received by print() as a sequence of values and the subsequent call to Println(v…) uses this same sequence as this is the sequence expected by Println(). So why did we use …interface{} in defining our parameters instead of the more obvious …string? The Println() function is itself defined as Println(…interface{}) so to provide a sequence of values en masse we likewise need to use …interface{} in the type signature of our function. Otherwise we’d have to create a []interface{} (a slice of interface{} values, a concept we’ll cover in detail in a later chanpter) and copy each individual element into it before passing it into Println(). Encapsulation In this chapter we’ll for the most part be using Go’s primitive types and types defined in various standard packages without any comment on their structure, however a key aspect of modern programming languages is the encapsulation of related data into structured types and Go supports this via the struct type. A struct describes an area of allocated memory which is subdivided into slots for holding named values, where each named value has its own type. A typical example of a struct in action would be Example 1.17 1 package main 2 3 import "fmt" 4 5 type Message struct { 6 X string 7 y *string 8 } 9 10 func (v Message) Print() { 11 if v.y != nil { 12 fmt.Println(v.X, *v.y) 13 } else { 14 fmt.Println(v.X) 15 } 16 } 17 18 func (v *Message) Store(x, y string) { 19 v.X = x 20 v.y = &y 21 } 22 23 func main() { 24 m := &Message{} 25 m.Print() 26 m.Store("Hello", "world") 27 m.Print() 28 } ENCAPSULATION package main import "fmt" type Message struct { X string y *string } func (v Message) Print() { if v.y != nil { fmt.Println(v.X, *v.y) } else { fmt.Println(v.X) } } func (v *Message) Store(x, y string) { v.X = x v.y = &y } func main() { m := &Message{} m.Print() m.Store("Hello", "world") m.Print() }
  • 23. ENCAPSULATION package main import "fmt" type Message struct { X string y *string } func (v Message) Print() { if v.y != nil { fmt.Println(v.X, *v.y) } else { fmt.Println(v.X) } } func (v *Message) Store(x, y string) { v.X = x v.y = &y } func main() { m := &Message{} m.Print() m.Store("Hello", "world") m.Print() } package main import "fmt" type HelloWorld bool func (h HelloWorld) String() (r string) { if h { r = "Hello world" } return } type Message struct { HelloWorld } func main() { m := &Message{ HelloWorld: true } fmt.Println(m) m.HelloWorld = false fmt.Println(m) m.HelloWorld = true fmt.Println(m) }
  • 24. Hello World 22 Startup One of the less-discussed aspects of computer programs is the need to initialise many of them to a pre- determined state before they begin executing. Whilst this is probably the worst place to start discussing what to many people may appear to be advanced topics, one of my goals in this chapter is to cover all of the structural elements that we’ll meet when we examine more complex programs. Every Go package may contain one or more init() functions specifying actions that should be taken during program initialisation. This is the one case I’m aware of where multiple declarations of the same identifier can occur without either resulting in a compilation error or the shadowing of a variable. In the following example we use the init() function to assign a value to our world variable Example 1.26 1 package main 2 import . "fmt" 3 4 const Hello = "hello" 5 var world string 6 7 func init() { 8 world = "world" 9 } 10 11 func main() { 12 Println(Hello, world) 13 } However the init() function can contain any valid Go code, allowing us to place the whole of our program in init() and leaving main() as a stub to convince the compiler that this is indeed a valid Go program. Example 1.27 1 package main 2 import . "fmt" 3 4 const Hello = "hello" 5 var world string 6 7 func init() { 8 world = "world" 9 Println(Hello, world) 10 } 11 12 func main() {} When there are multiple init() functions the order in which they’re executed is indeterminate so in general it’s best not to do this unless you can be certain the init() functions don’t interact in any way. The following happens to work as expected on my development computer but an implementation of Go could just as easily arrange it to run in reverse order or even leave deciding the order of execution until runtime. STARTUP package main import . "fmt" const Hello = "hello" var world string func init() { world = "world" } func main() { Println(Hello, world) }
  • 25. Hello World 23 Example 1.28 1 package main 2 import . "fmt" 3 4 const Hello = "hello" 5 var world string 6 7 func init() { 8 Print(Hello, " ") 9 world = "world" 10 } 11 12 func init() { 13 Printf("%vn", world) 14 } 15 16 func main() {} HTTP So far our treatment of Hello World has followed the traditional route of printing a preset message to the console. Anyone would think we were living in the fuddy-duddy mainframe era of the 1970s instead of the shiny 21st Century, when web and mobile applications rule the world. Turning Hello World into a web application is surprisingly simple, as the following example demon- strates. Example 1.29 1 package main 2 import ( 3 . "fmt" 4 "net/http" 5 ) 6 7 const MESSAGE = "hello world" 8 const ADDRESS = ":1024" 9 10 func main() { 11 http.HandleFunc("/hello", Hello) 12 if e := http.ListenAndServe(ADDRESS, nil); e != nil { 13 Println(e) 14 } 15 } 16 17 func Hello(w http.ResponseWriter, r *http.Request) { 18 w.Header().Set("Content-Type", "text/plain") 19 Fprintf(w, MESSAGE) 20 } HTTP package main import ( . "fmt" "net/http" ) const MESSAGE = "hello world" const ADDRESS = ":1024" func main() { http.HandleFunc("/hello", Hello) if e := http.ListenAndServe(ADDRESS, nil); e != nil { Println(e) } } func Hello(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "text/plain") Fprintf(w, MESSAGE) }
  • 26. HTTP/S package main import ( . "fmt" . "net/http" ) const ADDRESS = ":1024" const SECURE_ADDRESS = ":1025" func main() { message := "hello world" HandleFunc("/hello", func(w ResponseWriter, r *Request) { w.Header().Set("Content-Type", "text/plain") Fprintf(w, message) }) Spawn( func() { ListenAndServeTLS(SECURE_ADDRESS, "cert.pem", "key.pem", nil) }, func() { ListenAndServe(ADDRESS, nil) }, ) } func Spawn(f ...func()) { done := make(chan bool) for _, s := range f { go func(server func()) { server() done <- true }(s) } for l := len(f); l > 0; l-- { <- done } } package main import ( . "fmt" . "net/http" "sync" ) const ADDRESS = ":1024" const SECURE_ADDRESS = ":1025" var servers sync.WaitGroup func main() { message := "hello world" HandleFunc("/hello", func(w ResponseWriter, r *Request) { w.Header().Set("Content-Type", "text/plain") Fprintf(w, message) }) Launch(func() { ListenAndServe(ADDRESS, nil) }) Launch(func() { ListenAndServeTLS(SECURE_ADDRESS, "cert.pem", "key.pem", nil) }) servers.Wait() } func Launch(f func()) { servers.Add(1) go func() { defer servers.Done() f() }() }
  • 27. Hello World 35 The Environment The main shells used with modern operating systems (Linux, OSX, FreeBSD, Windows, etc.) provide a persistent environment which can be queried by running programs, allowing a user to store configuration values in named variables. Go supports reading and writing these variables using the os package functions Getenv() and Setenv(). In our next example we’re going to query the environment for the variable SERVE_HTTP which we’ll assume contains the default address on which to serve unencrypted web content. Example 1.43 1 package main 2 import ( 3 . "fmt" 4 . "net/http" 5 "os" 6 "sync" 7 ) 8 9 const SECURE_ADDRESS = ":1025" 10 11 var address string 12 var servers sync.WaitGroup 13 14 func init() { 15 if address = os.Getenv("SERVE_HTTP"); address == "" { 16 address = ":1024" 17 } 18 } 19 20 func main() { 21 message := "hello world" 22 HandleFunc("/hello", func(w ResponseWriter, r *Request) { 23 w.Header().Set("Content-Type", "text/plain") 24 Fprintf(w, message) 25 }) 26 27 Launch(func() { 28 ListenAndServe(address, nil) 29 }) 30 31 Launch(func() { 32 ListenAndServeTLS(SECURE_ADDRESS, "cert.pem", "key.pem", nil) 33 }) 34 servers.Wait() 35 } 36 THE ENVIRONMENT package main import ( . "fmt" . "net/http" "os" "sync" ) const SECURE_ADDRESS = ":1025" var address string var servers sync.WaitGroup func init() { if address = os.Getenv("SERVE_HTTP"); address == "" { address = ":1024" } } func main() { message := "hello world" HandleFunc("/hello", func(w ResponseWriter, r *Request) { w.Header().Set("Content-Type", "text/plain") Fprintf(w, message) }) Launch(func() { ListenAndServe(address, nil) }) Launch(func() { ListenAndServeTLS(SECURE_ADDRESS, "cert.pem", "key.pem", nil) }) servers.Wait() } func Launch(f func()) { servers.Add(1) go func() { defer servers.Done() f() }() }
  • 28. Hello World 49 UDP Both TCP/IP and HTTP communications are connection-oriented and this involves a reasonable amount of handshaking and error-correction to assemble data packets in the correct order. For most applications this is exactly how we want to organise our network communications but sometimes the size of our messages is sufficiently small that we can fit them into individual packets, and when this is the case the UDP protocol is an ideal candidate. As with our previous examples we still need both server and client applications. Example 1.53 UDP server 1 package main 2 3 import ( 4 . "fmt" 5 "net" 6 ) 7 8 var HELLO_WORLD = ([]byte)("Hello Worldn") 9 10 func main() { 11 if address, e := net.ResolveUDPAddr("udp", ":1024"); e == nil { 12 if server, e := net.ListenUDP("udp", address); e == nil { 13 for buffer := MakeBuffer(); ; buffer = MakeBuffer() { 14 if n, client, e := server.ReadFromUDP(buffer); e == nil { 15 go func(c *net.UDPAddr, packet []byte) { 16 if n, e := server.WriteToUDP(HELLO_WORLD, c); e == nil { 17 Printf("%v bytes written to: %vn", n, c) 18 } 19 }(client, buffer[:n]) 20 } 21 } 22 } 23 } 24 } 25 26 func MakeBuffer() (r []byte) { 27 return make([]byte, 1024) 28 } We have a somewhat more complex code pattern here than with TCP/IP to take account of the difference in underlying semantics: UDP is an unreliable transport dealing in individual packets (datagrams) which are independent of each other, therefore a server doesn’t maintain streams to any of its clients and these are responsible for any error-correction or packet ordering which may be necessary to coordinate successive signals. Because of these differences from TCP/IP we end up with the following generic workflow • net.ResolveUDPAddr() to resolve the address • net.ListenUDP() opens a UDP port and listens for traffic UDP package main import ( . "fmt" "net" ) var HELLO_WORLD = ([]byte)("Hello Worldn") func main() { if address, e := net.ResolveUDPAddr("udp", ":1024"); e == nil { if server, e := net.ListenUDP("udp", address); e == nil { for buffer := MakeBuffer(); ; buffer = MakeBuffer() { if n, client, e := server.ReadFromUDP(buffer); e == nil { go func(c *net.UDPAddr, packet []byte) { if n, e := server.WriteToUDP(HELLO_WORLD, c); e == nil { Printf("%v bytes written to: %vn", n, c) } }(client, buffer[:n]) } } } } } func MakeBuffer() (r []byte) { return make([]byte, 1024) }
  • 29. UDP SERVER & CLIENT package main import ( . "fmt" "net" ) var HELLO_WORLD = ([]byte)("Hello Worldn") func main() { if address, e := net.ResolveUDPAddr("udp", ":1024"); e == nil { if server, e := net.ListenUDP("udp", address); e == nil { for buffer := MakeBuffer(); ; buffer = MakeBuffer() { if n, client, e := server.ReadFromUDP(buffer); e == nil { go func(c *net.UDPAddr, packet []byte) { if n, e := server.WriteToUDP(HELLO_WORLD, c); e == nil { Printf("%v bytes written to: %vn", n, c) } }(client, buffer[:n]) } } } } } func MakeBuffer() (r []byte) { return make([]byte, 1024) } package main import ( "bufio" . "fmt" "net" ) var CRLF = ([]byte)("n") func main() { if address, e := net.ResolveUDPAddr("udp", ":1024"); e == nil { if server, e := net.DialUDP("udp", nil, address); e == nil { defer server.Close() for i := 0; i < 3; i++ { if _, e = server.Write(CRLF); e == nil { if text, e := bufio.NewReader(server).ReadString('n'); e == nil { Printf("%v: %v", i, text) } } } } } }
  • 30. Packages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 Constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 Encapsulation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 Generalisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 Startup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 HTTP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 The Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 Handling Signals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 TCP/IP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 UDP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 RSA obfuscated UDP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 Error Handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 Echo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72 Arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72 Flags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 Command-line Boilerplate and Standard I/O . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 Conditional Flags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90 Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 Regular Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 Interactive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 Pipes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 Encryption . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 Software Machines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94 memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94 Functional Programming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95 First-Class and Higher-Order Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95 BEHIND THE PAYWALL lots of stuff you can get for free
  • 34. DON'T LIKE MY BOOK?
  • 35. !! WRITE YOUR OWN !!