@@ -31,6 +30,7 @@ encoding/decoding.
+
|
@@ -40,6 +40,7 @@ encoding/decoding.
+
@@ -54,6 +55,7 @@ save us some space below.
|
+
import b64 "encoding/base64"
import "fmt"
@@ -66,6 +68,7 @@ save us some space below.
|
+
@@ -78,6 +81,7 @@ save us some space below.
|
+
data := "abc123!?$*&()'-=@~"
@@ -93,6 +97,7 @@ cast our string to that type.
|
+
sEnc := b64.StdEncoding.EncodeToString([]byte(data))
fmt.Println(sEnc)
@@ -108,6 +113,7 @@ well-formed.
|
+
sDec, _ := b64.StdEncoding.DecodeString(sEnc)
fmt.Println(string(sDec))
fmt.Println()
@@ -123,6 +129,7 @@ format.
|
+
uEnc := b64.URLEncoding.EncodeToString([]byte(data))
fmt.Println(uEnc)
uDec, _ := b64.URLEncoding.DecodeString(uEnc)
@@ -145,6 +152,7 @@ but they both decode to the original string as desired.
|
+
$ go run base64-encoding.go
YWJjMTIzIT8kKiYoKSctPUB+
abc123!?$*&()'-=@~
@@ -158,6 +166,7 @@ but they both decode to the original string as desired.
|
+
YWJjMTIzIT8kKiYoKSctPUB-
abc123!?$*&()'-=@~
diff --git a/public/channel-buffering b/public/channel-buffering
index afff1d0..5893c33 100644
--- a/public/channel-buffering
+++ b/public/channel-buffering
@@ -20,7 +20,6 @@
-
@@ -35,6 +34,7 @@ those values.
+
|
@@ -44,6 +44,7 @@ those values.
+
@@ -55,6 +56,7 @@ those values.
|
+
@@ -66,6 +68,7 @@ those values.
|
+
@@ -79,6 +82,7 @@ those values.
|
+
messages := make(chan string, 2)
@@ -93,6 +97,7 @@ concurrent receive.
|
+
messages <- "buffered"
messages <- "channel"
@@ -106,6 +111,7 @@ concurrent receive.
|
+
fmt.Println(<-messages)
fmt.Println(<-messages)
}
@@ -123,6 +129,7 @@ concurrent receive.
|
+
$ go run channel-buffering.go
buffered
channel
diff --git a/public/channel-directions b/public/channel-directions
index 6b94688..c1171ae 100644
--- a/public/channel-directions
+++ b/public/channel-directions
@@ -20,7 +20,6 @@
-
@@ -33,6 +32,7 @@ the program.
+
|
@@ -42,6 +42,7 @@ the program.
+
@@ -53,6 +54,7 @@ the program.
|
+
@@ -67,6 +69,7 @@ receive on this channel.
|
+
func ping(pings chan<- string, msg string) {
pings <- msg
}
@@ -82,6 +85,7 @@ receive on this channel.
|
+
func pong(pings <-chan string, pongs chan<- string) {
msg := <-pings
pongs <- msg
@@ -96,6 +100,7 @@ receive on this channel.
|
+
func main() {
pings := make(chan string, 1)
pongs := make(chan string, 1)
@@ -117,6 +122,7 @@ receive on this channel.
|
+
$ go run channel-directions.go
passed message
diff --git a/public/channel-synchronization b/public/channel-synchronization
index 011169f..ed359f3 100644
--- a/public/channel-synchronization
+++ b/public/channel-synchronization
@@ -20,7 +20,6 @@
-
@@ -32,6 +31,7 @@ blocking receive to wait for a goroutine to finish.
+
|
@@ -41,6 +41,7 @@ blocking receive to wait for a goroutine to finish.
+
@@ -52,6 +53,7 @@ blocking receive to wait for a goroutine to finish.
|
+
import "fmt"
import "time"
@@ -67,6 +69,7 @@ goroutine that this function’s work is done.
|
+
func worker(done chan bool) {
fmt.Print("working...")
time.Sleep(time.Second)
@@ -82,6 +85,7 @@ goroutine that this function’s work is done.
|
+
@@ -94,6 +98,7 @@ goroutine that this function’s work is done.
|
+
@@ -107,6 +112,7 @@ notify on.
|
+
done := make(chan bool, 1)
go worker(done)
@@ -121,6 +127,7 @@ worker on the channel.
|
+
@@ -137,6 +144,7 @@ worker on the channel.
|
+
$ go run channel-synchronization.go
working...done
@@ -152,6 +160,7 @@ started.
|
+
|
diff --git a/public/channels b/public/channels
index 83656f1..fbb9329 100644
--- a/public/channels
+++ b/public/channels
@@ -20,7 +20,6 @@
-
@@ -34,6 +33,7 @@ underly much of Go’s functionality.
+
|
@@ -43,6 +43,7 @@ underly much of Go’s functionality.
+
@@ -54,6 +55,7 @@ underly much of Go’s functionality.
|
+
@@ -65,6 +67,7 @@ underly much of Go’s functionality.
|
+
@@ -78,6 +81,7 @@ Channels are typed by the values they convey.
|
+
messages := make(chan string)
@@ -92,6 +96,7 @@ channel we made above, from a new goroutine.
|
+
go func() { messages <- "ping" }()
@@ -106,6 +111,7 @@ we sent above and print it out.
|
+
msg := <-messages
fmt.Println(msg)
}
@@ -126,6 +132,7 @@ channel.
|
+
$ go run channels.go
ping
@@ -142,6 +149,7 @@ message without having to use any other synchronization.
|
+
|
diff --git a/public/closing-channels b/public/closing-channels
index 2a7fa83..c614498 100644
--- a/public/closing-channels
+++ b/public/closing-channels
@@ -20,7 +20,6 @@
-
@@ -32,6 +31,7 @@ completion to the channel’s receivers.
+
|
@@ -41,6 +41,7 @@ completion to the channel’s receivers.
+
@@ -52,6 +53,7 @@ completion to the channel’s receivers.
|
+
@@ -67,6 +69,7 @@ the worker we’ll close the jobs channel.
|
+
func main() {
jobs := make(chan int, 5)
done := make(chan bool)
@@ -87,6 +90,7 @@ all our jobs.
|
+
go func() {
for {
j, more := <-jobs
@@ -111,6 +115,7 @@ channel, then closes it.
|
+
for j := 1; j <= 3; j++ {
jobs <- j
fmt.Println("sent job", j)
@@ -130,6 +135,7 @@ we saw earlier.
|
+
@@ -146,6 +152,7 @@ we saw earlier.
|
+
$ go run closing-channels.go
sent job 1
received job 1
@@ -167,6 +174,7 @@ example: range over channels.
|
+
|
diff --git a/public/closures b/public/closures
index 2e1372c..fcc0b6d 100644
--- a/public/closures
+++ b/public/closures
@@ -20,7 +20,6 @@
-
@@ -33,6 +32,7 @@ a function inline without having to name it.
+
|
@@ -42,6 +42,7 @@ a function inline without having to name it.
+
@@ -53,6 +54,7 @@ a function inline without having to name it.
|
+
@@ -68,6 +70,7 @@ form a closure.
|
+
func intSeq() func() int {
i := 0
return func() int {
@@ -85,6 +88,7 @@ form a closure.
|
+
@@ -100,6 +104,7 @@ we call nextInt .
|
+
@@ -113,6 +118,7 @@ a few times.
|
+
fmt.Println(nextInt())
fmt.Println(nextInt())
fmt.Println(nextInt())
@@ -128,6 +134,7 @@ particular function, create and test a new one.
|
+
newInts := intSeq()
fmt.Println(newInts())
}
@@ -145,6 +152,7 @@ particular function, create and test a new one.
|
+
$ go run closures.go
1
2
@@ -162,6 +170,7 @@ recursion.
|
+
|
diff --git a/public/collection-functions b/public/collection-functions
index c8b070e..e692eb7 100644
--- a/public/collection-functions
+++ b/public/collection-functions
@@ -20,7 +20,6 @@
-
@@ -33,6 +32,7 @@ collection with a custom function.
+
|
@@ -47,6 +47,7 @@ your program and data types.
+
|
@@ -62,6 +63,7 @@ helper function.
+
|
@@ -71,6 +73,7 @@ helper function.
+
@@ -82,6 +85,7 @@ helper function.
|
+
import "strings"
import "fmt"
@@ -96,6 +100,7 @@ helper function.
|
+
func Index(vs []string, t string) int {
for i, v := range vs {
if v == t {
@@ -116,6 +121,7 @@ slice.
|
+
func Include(vs []string, t string) bool {
return Index(vs, t) >= 0
}
@@ -131,6 +137,7 @@ satisfies the predicate f .
|
+
func Any(vs []string, f func(string) bool) bool {
for _, v := range vs {
if f(v) {
@@ -151,6 +158,7 @@ satisfy the predicate f .
|
+
func All(vs []string, f func(string) bool) bool {
for _, v := range vs {
if !f(v) {
@@ -171,6 +179,7 @@ slice that satisfy the predicate f .
|
+
func Filter(vs []string, f func(string) bool) []string {
vsf := make([]string, 0)
for _, v := range vs {
@@ -192,6 +201,7 @@ the function f to each string in the original slice.
|
+
func Map(vs []string, f func(string) string) []string {
vsm := make([]string, len(vs))
for i, v := range vs {
@@ -209,6 +219,7 @@ the function f to each string in the original slice.
|
+
@@ -221,6 +232,7 @@ the function f to each string in the original slice.
|
+
var strs = []string{"peach", "apple", "pear", "plum"}
@@ -232,6 +244,7 @@ the function f to each string in the original slice.
|
+
fmt.Println(Index(strs, "pear"))
@@ -243,6 +256,7 @@ the function f to each string in the original slice.
|
+
fmt.Println(Include(strs, "grape"))
@@ -254,6 +268,7 @@ the function f to each string in the original slice.
|
+
fmt.Println(Any(strs, func(v string) bool {
return strings.HasPrefix(v, "p")
}))
@@ -267,6 +282,7 @@ the function f to each string in the original slice.
|
+
fmt.Println(All(strs, func(v string) bool {
return strings.HasPrefix(v, "p")
}))
@@ -280,6 +296,7 @@ the function f to each string in the original slice.
|
+
fmt.Println(Filter(strs, func(v string) bool {
return strings.Contains(v, "e")
}))
@@ -296,6 +313,7 @@ type.
|
+
fmt.Println(Map(strs, strings.ToUpper))
@@ -307,6 +325,7 @@ type.
|
+
@@ -322,6 +341,7 @@ type.
|
+
$ go run collection-functions.go
2
false
diff --git a/public/command-line-arguments b/public/command-line-arguments
index 6d80fed..8067ee8 100644
--- a/public/command-line-arguments
+++ b/public/command-line-arguments
@@ -20,7 +20,6 @@
-
@@ -33,6 +32,7 @@ For example, go run hello.go uses run and
+
|
@@ -42,6 +42,7 @@ For example, go run hello.go uses run and
+
@@ -53,6 +54,7 @@ For example, go run hello.go uses run and
|
+
@@ -65,6 +67,7 @@ For example, go run hello.go uses run and
|
+
@@ -80,6 +83,7 @@ holds the arguments to the program.
|
+
argsWithProg := os.Args
argsWithoutProg := os.Args[1:]
@@ -93,6 +97,7 @@ holds the arguments to the program.
|
+
@@ -104,6 +109,7 @@ holds the arguments to the program.
|
+
fmt.Println(argsWithProg)
fmt.Println(argsWithoutProg)
fmt.Println(arg)
@@ -124,6 +130,7 @@ build a binary with go build first.
|
+
$ go build command-line-arguments.go
$ ./command-line-arguments a b c d
[./command-line-arguments a b c d]
@@ -141,6 +148,7 @@ with flags.
|
+
|
diff --git a/public/command-line-flags b/public/command-line-flags
index cf2ca8a..6b0bb4b 100644
--- a/public/command-line-flags
+++ b/public/command-line-flags
@@ -20,7 +20,6 @@
-
@@ -33,6 +32,7 @@ command-line flag.
+
|
@@ -42,6 +42,7 @@ command-line flag.
+
@@ -56,6 +57,7 @@ implement our example command-line program.
|
+
import "flag"
import "fmt"
@@ -68,6 +70,7 @@ implement our example command-line program.
|
+
@@ -85,6 +88,7 @@ we’ll see how to use this pointer below.
|
+
wordPtr := flag.String("word", "foo", "a string")
@@ -98,6 +102,7 @@ similar approach to the word flag.
|
+
numbPtr := flag.Int("numb", 42, "an int")
boolPtr := flag.Bool("fork", false, "a bool")
@@ -114,6 +119,7 @@ declaration function.
|
+
var svar string
flag.StringVar(&svar, "svar", "bar", "a string var")
@@ -128,6 +134,7 @@ to execute the command-line parsing.
|
+
@@ -143,6 +150,7 @@ to get the actual option values.
|
+
fmt.Println("word:", *wordPtr)
fmt.Println("numb:", *numbPtr)
fmt.Println("fork:", *boolPtr)
@@ -166,6 +174,7 @@ binary directly.
|
+
$ go build command-line-flags.go
@@ -179,6 +188,7 @@ all flags.
|
+
$ ./command-line-flags -word=opt -numb=7 -fork -svar=flag
word: opt
numb: 7
@@ -197,6 +207,7 @@ their default values.
|
+
$ ./command-line-flags -word=opt
word: opt
numb: 42
@@ -215,6 +226,7 @@ any flags.
|
+
$ ./command-line-flags -word=opt a1 a2 a3
word: opt
...
@@ -232,6 +244,7 @@ will be interpreted as positional arguments).
|
+
$ ./command-line-flags -word=opt a1 a2 a3 -numb=7
word: opt
numb: 42
@@ -250,6 +263,7 @@ generated help text for the command-line program.
|
+
$ ./command-line-flags -h
Usage of ./command-line-flags:
-fork=false: a bool
@@ -269,6 +283,7 @@ an show the help text again.
|
+
$ ./command-line-flags -wat
flag provided but not defined: -wat
Usage of ./command-line-flags:
@@ -285,6 +300,7 @@ way to parameterize programs.
|
+
|
diff --git a/public/constants b/public/constants
index 73053dc..f9c1320 100644
--- a/public/constants
+++ b/public/constants
@@ -20,7 +20,6 @@
-
@@ -31,6 +30,7 @@ and numeric values.
+
|
@@ -40,6 +40,7 @@ and numeric values.
+
@@ -51,6 +52,7 @@ and numeric values.
|
+
import "fmt"
import "math"
@@ -64,6 +66,7 @@ and numeric values.
|
+
const s string = "constant"
@@ -75,6 +78,7 @@ and numeric values.
|
+
func main() {
fmt.Println(s)
@@ -89,6 +93,7 @@ statement can.
|
+
@@ -102,6 +107,7 @@ arbitrary precision.
|
+
const d = 3e20 / n
fmt.Println(d)
@@ -116,6 +122,7 @@ one, such as by an explicit cast.
|
+
@@ -131,6 +138,7 @@ assignment or function call. For example, here
|
+
fmt.Println(math.Sin(n))
}
@@ -147,6 +155,7 @@ assignment or function call. For example, here
|
+
$ go run constant.go
constant
6e+11
diff --git a/public/defer b/public/defer
index 95462ed..130870b 100644
--- a/public/defer
+++ b/public/defer
@@ -20,7 +20,6 @@
-
@@ -33,6 +32,7 @@ purposes of cleanup. defer is often used where e.g.
+
|
@@ -42,6 +42,7 @@ purposes of cleanup. defer is often used where e.g.
+
@@ -53,6 +54,7 @@ purposes of cleanup. defer is often used where e.g.
|
+
@@ -68,6 +70,7 @@ do that with defer .
|
+
@@ -84,6 +87,7 @@ of the enclosing function (main ), after
|
+
f := createFile("/tmp/defer.txt")
defer closeFile(f)
writeFile(f)
@@ -98,6 +102,7 @@ of the enclosing function (main ), after
|
+
func createFile(p string) *os.File {
fmt.Println("creating")
f, err := os.Create(p)
@@ -116,6 +121,7 @@ of the enclosing function (main ), after
|
+
func writeFile(f *os.File) {
fmt.Println("writing")
fmt.Fprintln(f, "data")
@@ -129,6 +135,7 @@ of the enclosing function (main ), after
|
+
@@ -140,6 +147,7 @@ of the enclosing function (main ), after
|
+
func closeFile(f *os.File) {
fmt.Println("closing")
f.Close()
@@ -160,6 +168,7 @@ after being written.
|
+
$ go run defer.go
creating
writing
diff --git a/public/environment-variables b/public/environment-variables
index 63ebeca..cb61053 100644
--- a/public/environment-variables
+++ b/public/environment-variables
@@ -20,7 +20,6 @@
-
@@ -33,6 +32,7 @@ Let’s look at how to set, get, and list environment variables.
+
|
@@ -42,6 +42,7 @@ Let’s look at how to set, get, and list environment variables.
+
@@ -53,6 +54,7 @@ Let’s look at how to set, get, and list environment variables.
|
+
import "os"
import "strings"
import "fmt"
@@ -66,6 +68,7 @@ Let’s look at how to set, get, and list environment variables.
|
+
@@ -81,6 +84,7 @@ environment.
|
+
os.Setenv("FOO", "1")
fmt.Println("FOO:", os.Getenv("FOO"))
fmt.Println("BAR:", os.Getenv("BAR"))
@@ -98,6 +102,7 @@ get the key and value. Here we print all the keys.
|
+
fmt.Println()
for _, e := range os.Environ() {
pair := strings.Split(e, "=")
@@ -121,6 +126,7 @@ value for FOO that we set in the program, but that
|
+
$ go run environment-variables.go
FOO: 1
BAR:
@@ -136,6 +142,7 @@ particular machine.
|
+
TERM_PROGRAM
PATH
SHELL
@@ -152,6 +159,7 @@ program picks that value up.
|
+
$ BAR=2 go run environment-variables.go
FOO: 1
BAR: 2
diff --git a/public/epoch b/public/epoch
index cc5161b..9f2ec37 100644
--- a/public/epoch
+++ b/public/epoch
@@ -20,7 +20,6 @@
-
@@ -33,6 +32,7 @@ Here’s how to do it in Go.
+
|
@@ -42,6 +42,7 @@ Here’s how to do it in Go.
+
@@ -53,6 +54,7 @@ Here’s how to do it in Go.
|
+
import "fmt"
import "time"
@@ -65,6 +67,7 @@ Here’s how to do it in Go.
|
+
@@ -79,6 +82,7 @@ nanoseconds, respectively.
|
+
now := time.Now()
secs := now.Unix()
nanos := now.UnixNano()
@@ -96,6 +100,7 @@ dive from nanoseconds.
|
+
millis := nanos / 1000000
fmt.Println(secs)
fmt.Println(millis)
@@ -112,6 +117,7 @@ since the epoch into the corresponding time .
|
+
fmt.Println(time.Unix(secs, 0))
fmt.Println(time.Unix(0, nanos))
}
@@ -129,6 +135,7 @@ since the epoch into the corresponding time .
|
+
$ go run epoch.go
2012-10-31 16:13:58.292387 +0000 UTC
1351700038
@@ -148,6 +155,7 @@ parsing and formatting.
|
+
|
diff --git a/public/errors b/public/errors
index dc25155..b07e219 100644
--- a/public/errors
+++ b/public/errors
@@ -20,7 +20,6 @@
-
@@ -37,6 +36,7 @@ non-error tasks.
+
|
@@ -46,6 +46,7 @@ non-error tasks.
+
@@ -57,6 +58,7 @@ non-error tasks.
|
+
import "errors"
import "fmt"
@@ -71,6 +73,7 @@ have type error , a built-in interface.
|
+
func f1(arg int) (int, error) {
if arg == 42 {
@@ -85,6 +88,7 @@ with the given error message.
|
+
return -1, errors.New("can't work with 42")
@@ -96,6 +100,7 @@ with the given error message.
|
+
@@ -109,6 +114,7 @@ there was no error.
|
+
@@ -125,6 +131,7 @@ to explicitly represent an argument error.
|
+
type argError struct {
arg int
prob string
@@ -139,6 +146,7 @@ to explicitly represent an argument error.
|
+
func (e *argError) Error() string {
return fmt.Sprintf("%d - %s", e.arg, e.prob)
}
@@ -152,6 +160,7 @@ to explicitly represent an argument error.
|
+
func f2(arg int) (int, error) {
if arg == 42 {
@@ -167,6 +176,7 @@ fields arg and prob .
|
+
return -1, &argError{arg, "can't work with it"}
}
return arg + 3, nil
@@ -181,6 +191,7 @@ fields arg and prob .
|
+
@@ -196,6 +207,7 @@ idiom in Go code.
|
+
for _, i := range []int{7, 42} {
if r, e := f1(i); e != nil {
fmt.Println("f1 failed:", e)
@@ -224,6 +236,7 @@ assertion.
|
+
_, e := f2(42)
if ae, ok := e.(*argError); ok {
fmt.Println(ae.arg)
@@ -244,6 +257,7 @@ assertion.
|
+
$ go run errors.go
f1 worked: 10
f1 failed: can't work with 42
@@ -263,6 +277,7 @@ on the Go blog for more on error handling.
|
+
|
diff --git a/public/execing-processes b/public/execing-processes
index 2700243..baa501a 100644
--- a/public/execing-processes
+++ b/public/execing-processes
@@ -20,7 +20,6 @@
-
@@ -38,6 +37,7 @@ function.
+
|
@@ -47,6 +47,7 @@ function.
+
@@ -58,6 +59,7 @@ function.
|
+
import "syscall"
import "os"
import "os/exec"
@@ -71,6 +73,7 @@ function.
|
+
@@ -86,6 +89,7 @@ we’ll use exec.LookPath to find it (probably
|
+
binary, lookErr := exec.LookPath("ls")
if lookErr != nil {
panic(lookErr)
@@ -104,6 +108,7 @@ be the program name.
|
+
args := []string{"ls", "-a", "-l", "-h"}
@@ -118,6 +123,7 @@ environment.
|
+
@@ -134,6 +140,7 @@ value.
|
+
execErr := syscall.Exec(binary, args, env)
if execErr != nil {
panic(execErr)
@@ -154,6 +161,7 @@ value.
|
+
$ go run execing-processes.go
total 16
drwxr-xr-x 4 mark 136B Oct 3 16:29 .
@@ -173,6 +181,7 @@ processes covers most use cases for fork .
|
+
|
diff --git a/public/exit b/public/exit
index 3b61b94..3188ddb 100644
--- a/public/exit
+++ b/public/exit
@@ -20,7 +20,6 @@
-
@@ -31,6 +30,7 @@ status.
+
|
@@ -40,6 +40,7 @@ status.
+
@@ -51,6 +52,7 @@ status.
|
+
@@ -63,6 +65,7 @@ status.
|
+
@@ -76,6 +79,7 @@ this fmt.Println will never be called.
|
+
@@ -88,6 +92,7 @@ this fmt.Println will never be called.
|
+
@@ -104,6 +109,7 @@ use os.Exit .
|
+
|
@@ -119,6 +125,7 @@ will be picked up by go and printed.
+
$ go run exit.go
exit status 3
@@ -133,6 +140,7 @@ the status in the terminal.
|
+
$ go build exit.go
$ ./exit
$ echo $?
@@ -148,6 +156,7 @@ the status in the terminal.
|
+
|
diff --git a/public/for b/public/for
index 2bb0487..83e76a3 100644
--- a/public/for
+++ b/public/for
@@ -20,7 +20,6 @@
-
@@ -31,6 +30,7 @@ three basic types of for loops.
+
|
@@ -40,6 +40,7 @@ three basic types of for loops.
+
@@ -51,6 +52,7 @@ three basic types of for loops.
|
+
@@ -62,6 +64,7 @@ three basic types of for loops.
|
+
@@ -74,6 +77,7 @@ three basic types of for loops.
|
+
i := 1
for i <= 3 {
fmt.Println(i)
@@ -90,6 +94,7 @@ three basic types of for loops.
|
+
for j := 7; j <= 9; j++ {
fmt.Println(j)
}
@@ -106,6 +111,7 @@ the enclosing function.
|
+
for {
fmt.Println("loop")
break
@@ -125,6 +131,7 @@ the enclosing function.
|
+
$ go run for.go
1
2
@@ -146,6 +153,7 @@ structures.
|
+
|
diff --git a/public/functions b/public/functions
index ddb42f4..267ae28 100644
--- a/public/functions
+++ b/public/functions
@@ -20,7 +20,6 @@
-
@@ -31,6 +30,7 @@ functions with a few different examples.
+
|
@@ -40,6 +40,7 @@ functions with a few different examples.
+
@@ -51,6 +52,7 @@ functions with a few different examples.
|
+
@@ -64,6 +66,7 @@ their sum as an int .
|
+
func plus(a int, b int) int {
@@ -78,6 +81,7 @@ expression.
|
+
@@ -90,6 +94,7 @@ expression.
|
+
@@ -103,6 +108,7 @@ expression.
|
+
res := plus(1, 2)
fmt.Println("1+2 =", res)
}
@@ -120,6 +126,7 @@ expression.
|
+
$ go run functions.go
1+2 = 3
@@ -134,6 +141,7 @@ multiple return values, which we’ll look at next.
|
+
|
diff --git a/public/goroutines b/public/goroutines
index 1b03964..67fe18b 100644
--- a/public/goroutines
+++ b/public/goroutines
@@ -20,7 +20,6 @@
-
@@ -30,6 +29,7 @@
+
|
@@ -39,6 +39,7 @@
+
@@ -50,6 +51,7 @@
|
+
@@ -61,6 +63,7 @@
|
+
func f(from string) {
for i := 0; i < 3; i++ {
fmt.Println(from, ":", i)
@@ -76,6 +79,7 @@
|
+
@@ -90,6 +94,7 @@ synchronously.
|
+
@@ -104,6 +109,7 @@ concurrently with the calling one.
|
+
@@ -117,6 +123,7 @@ function call.
|
+
go func(msg string) {
fmt.Println(msg)
}("going")
@@ -134,6 +141,7 @@ before the program exits.
|
+
var input string
fmt.Scanln(&input)
fmt.Println("done")
@@ -156,6 +164,7 @@ goroutines being run concurrently by the Go runtime.
|
+
$ go run goroutines.go
direct : 0
direct : 1
@@ -178,6 +187,7 @@ concurrent Go programs: channels.
|
+
|
diff --git a/public/hello-world b/public/hello-world
index afea790..bfb0c69 100644
--- a/public/hello-world
+++ b/public/hello-world
@@ -20,7 +20,6 @@
-
@@ -31,6 +30,7 @@ message. Here’s the full source code.
+
@@ -42,6 +42,7 @@ message. Here’s the full source code.
|
+
@@ -53,6 +54,7 @@ message. Here’s the full source code.
|
+
func main() {
fmt.Println("hello world")
}
@@ -72,6 +74,7 @@ use go run .
|
+
$ go run hello-world.go
hello world
@@ -86,6 +89,7 @@ binaries. We can do this using go build .
|
+
$ go build hello-world.go
$ ls
hello-world hello-world.go
@@ -100,6 +104,7 @@ binaries. We can do this using go build .
|
+
$ ./hello-world
hello world
@@ -114,6 +119,7 @@ learn more about the language.
|
+
|
diff --git a/public/if-else b/public/if-else
index 8c1ee77..c54f82e 100644
--- a/public/if-else
+++ b/public/if-else
@@ -20,7 +20,6 @@
-
@@ -31,6 +30,7 @@ straight-forward.
+
|
@@ -40,6 +40,7 @@ straight-forward.
+
@@ -51,6 +52,7 @@ straight-forward.
|
+
@@ -62,6 +64,7 @@ straight-forward.
|
+
@@ -74,6 +77,7 @@ straight-forward.
|
+
if 7%2 == 0 {
fmt.Println("7 is even")
} else {
@@ -90,6 +94,7 @@ straight-forward.
|
+
if 8%4 == 0 {
fmt.Println("8 is divisible by 4")
}
@@ -106,6 +111,7 @@ branches.
|
+
if num := 9; num < 0 {
fmt.Println(num, "is negative")
} else if num < 10 {
@@ -126,6 +132,7 @@ in Go, but that the brackets are required.
|
+
|
@@ -139,6 +146,7 @@ in Go, but that the brackets are required.
+
$ go run if-else.go
7 is odd
8 is divisible by 4
@@ -156,6 +164,7 @@ for basic conditions.
|
+
|
diff --git a/public/interfaces b/public/interfaces
index 2c6efc6..3330a70 100644
--- a/public/interfaces
+++ b/public/interfaces
@@ -20,7 +20,6 @@
-
@@ -31,6 +30,7 @@ signatures.
+
|
@@ -40,6 +40,7 @@ signatures.
+
@@ -51,6 +52,7 @@ signatures.
|
+
import "fmt"
import "math"
@@ -64,6 +66,7 @@ signatures.
|
+
type geometry interface {
area() float64
perim() float64
@@ -80,6 +83,7 @@ signatures.
|
+
type square struct {
width, height float64
}
@@ -99,6 +103,7 @@ implement geometry on square s.
|
+
func (s square) area() float64 {
return s.width * s.height
}
@@ -116,6 +121,7 @@ implement geometry on square s.
|
+
func (c circle) area() float64 {
return math.Pi * c.radius * c.radius
}
@@ -136,6 +142,7 @@ to work on any geometry .
|
+
func measure(g geometry) {
fmt.Println(g)
fmt.Println(g.area())
@@ -151,6 +158,7 @@ to work on any geometry .
|
+
func main() {
s := square{width: 3, height: 4}
c := circle{radius: 5}
@@ -168,6 +176,7 @@ these structs as arguments to measure.
|
+
measure(s)
measure(c)
}
@@ -185,6 +194,7 @@ these structs as arguments to measure.
|
+
$ go run interfaces.go
{3 4}
12
@@ -204,6 +214,7 @@ these structs as arguments to measure.
|
+
|
diff --git a/public/json b/public/json
index 1928d21..ebe459d 100644
--- a/public/json
+++ b/public/json
@@ -20,7 +20,6 @@
-
@@ -32,6 +31,7 @@ data types.
+
|
@@ -41,6 +41,7 @@ data types.
+
@@ -52,6 +53,7 @@ data types.
|
+
import "encoding/json"
import "fmt"
import "os"
@@ -67,6 +69,7 @@ decoding of custom types below.
|
+
type Response1 struct {
Page int
Fruits []string
@@ -85,6 +88,7 @@ decoding of custom types below.
|
+
@@ -99,6 +103,7 @@ values.
|
+
bolB, _ := json.Marshal(true)
fmt.Println(string(bolB))
@@ -111,6 +116,7 @@ values.
|
+
intB, _ := json.Marshal(1)
fmt.Println(string(intB))
@@ -123,6 +129,7 @@ values.
|
+
fltB, _ := json.Marshal(2.34)
fmt.Println(string(fltB))
@@ -135,6 +142,7 @@ values.
|
+
strB, _ := json.Marshal("gopher")
fmt.Println(string(strB))
@@ -149,6 +157,7 @@ to JSON arrays and objects as you’d expect.
|
+
slcD := []string{"apple", "peach", "pear"}
slcB, _ := json.Marshal(slcD)
fmt.Println(string(slcB))
@@ -162,6 +171,7 @@ to JSON arrays and objects as you’d expect.
|
+
mapD := map[string]int{"apple": 5, "lettuce": 7}
mapB, _ := json.Marshal(mapD)
fmt.Println(string(mapB))
@@ -179,6 +189,7 @@ use those names as the JSON keys.
|
+
res1D := &Response1{
Page: 1,
Fruits: []string{"apple", "peach", "pear"}}
@@ -198,6 +209,7 @@ of such tags.
|
+
res2D := &Response2{
Page: 1,
Fruits: []string{"apple", "peach", "pear"}}
@@ -216,6 +228,7 @@ structure.
|
+
byt := []byte(`{"num":6.0,"strs":["a","b"]}`)
@@ -231,6 +244,7 @@ to arbitrary data types.
|
+
var dat map[string]interface{}
@@ -244,6 +258,7 @@ associated errors.
|
+
if err := json.Unmarshal(byt, &dat); err != nil {
panic(err)
}
@@ -262,6 +277,7 @@ the expected float64 type.
|
+
num := dat["num"].(float64)
fmt.Println(num)
@@ -276,6 +292,7 @@ casts.
|
+
strs := dat["strs"].([]interface{})
str1 := strs[0].(string)
fmt.Println(str1)
@@ -294,6 +311,7 @@ data.
|
+
str := `{"page": 1, "fruits": ["apple", "peach"]}`
res := &Response2{}
json.Unmarshal([]byte(str), &res)
@@ -314,6 +332,7 @@ stream JSON encodings directly to os.Writer s like
|
+
enc := json.NewEncoder(os.Stdout)
d := map[string]int{"apple": 5, "lettuce": 7}
enc.Encode(d)
@@ -332,6 +351,7 @@ stream JSON encodings directly to os.Writer s like
|
+
$ go run json.go
true
1
@@ -361,6 +381,7 @@ for more.
|
+
|
diff --git a/public/line-filters b/public/line-filters
index 51a6c3c..b0dd210 100644
--- a/public/line-filters
+++ b/public/line-filters
@@ -20,7 +20,6 @@
-
@@ -33,6 +32,7 @@ line filters.
+
|
@@ -45,6 +45,7 @@ pattern to write your own Go line filters.
+
@@ -56,6 +57,7 @@ pattern to write your own Go line filters.
|
+
import (
"bufio"
"fmt"
@@ -73,6 +75,7 @@ pattern to write your own Go line filters.
|
+
@@ -87,6 +90,7 @@ that we’ll use to read input line-by-line.
|
+
rdr := bufio.NewReader(os.Stdin)
out := os.Stdout
@@ -103,6 +107,7 @@ successive input lines.
|
+
for {
switch line, err := rdr.ReadString('\n'); err {
@@ -118,6 +123,7 @@ error on this write as we do on the read.
|
+
case nil:
ucl := strings.ToUpper(line)
if _, err = out.WriteString(ucl); err != nil {
@@ -136,6 +142,7 @@ end of input, so exit gracefully in that case.
|
+
@@ -150,6 +157,7 @@ error and exit with non-zero status.
|
+
default:
fmt.Fprintln(os.Stderr, "error:", err)
os.Exit(1)
@@ -172,6 +180,7 @@ lowercase lines.
|
+
$ echo 'hello' > /tmp/lines
$ echo 'filter' >> /tmp/lines
@@ -185,6 +194,7 @@ lowercase lines.
|
+
$ cat /tmp/lines | go run line-filters.go
HELLO
FILTER
diff --git a/public/maps b/public/maps
index 0ddf290..f08cdb9 100644
--- a/public/maps
+++ b/public/maps
@@ -20,7 +20,6 @@
-
@@ -31,6 +30,7 @@
+
|
@@ -40,6 +40,7 @@
+
@@ -51,6 +52,7 @@
|
+
@@ -62,6 +64,7 @@
|
+
@@ -75,6 +78,7 @@
|
+
m := make(map[string]int)
@@ -88,6 +92,7 @@ syntax.
|
+
@@ -102,6 +107,7 @@ its key/value pairs.
|
+
@@ -114,6 +120,7 @@ its key/value pairs.
|
+
v1 := m["k1"]
fmt.Println("v1: ", v1)
@@ -128,6 +135,7 @@ pairs when called on a map.
|
+
fmt.Println("len:", len(m))
@@ -141,6 +149,7 @@ a map.
|
+
delete(m, "k2")
fmt.Println("map:", m)
@@ -158,6 +167,7 @@ like 0 or "" .
|
+
_, prs := m["k2"]
fmt.Println("prs:", prs)
@@ -172,6 +182,7 @@ the same line with this syntax.
|
+
n := map[string]int{"foo": 1, "bar": 2}
fmt.Println("map:", n)
}
@@ -191,6 +202,7 @@ printed with fmt.Println .
|
+
$ go run maps.go
map: map[k1:7 k2:13]
v1: 7
diff --git a/public/methods b/public/methods
index 701f331..1d2a96c 100644
--- a/public/methods
+++ b/public/methods
@@ -20,7 +20,6 @@
-
@@ -30,6 +29,7 @@
+
|
@@ -39,6 +39,7 @@
+
@@ -50,6 +51,7 @@
|
+
@@ -61,6 +63,7 @@
|
+
type rect struct {
width, height int
}
@@ -75,6 +78,7 @@
|
+
func (r *rect) area() int {
return r.width * r.height
}
@@ -90,6 +94,7 @@ receiver types. Here’s an example of a value receiver.
|
+
func (r rect) perim() int {
return 2*r.width + 2*r.height
}
@@ -103,6 +108,7 @@ receiver types. Here’s an example of a value receiver.
|
+
func main() {
r := rect{width: 10, height: 5}
@@ -116,6 +122,7 @@ receiver types. Here’s an example of a value receiver.
|
+
fmt.Println("area: ", r.area())
fmt.Println("perim:", r.perim())
@@ -133,6 +140,7 @@ receiving struct.
|
+
rp := &r
fmt.Println("area: ", rp.area())
fmt.Println("perim:", rp.perim())
@@ -151,6 +159,7 @@ receiving struct.
|
+
$ go run methods.go
area: 50
perim: 30
@@ -168,6 +177,7 @@ naming related sets of methods: interfaces.
|
+
|
diff --git a/public/multiple-return-values b/public/multiple-return-values
index 9cdf349..d81ced5 100644
--- a/public/multiple-return-values
+++ b/public/multiple-return-values
@@ -20,7 +20,6 @@
-
@@ -32,6 +31,7 @@ to return both result and error values from a function.
+
|
@@ -41,6 +41,7 @@ to return both result and error values from a function.
+
@@ -52,6 +53,7 @@ to return both result and error values from a function.
|
+
@@ -65,6 +67,7 @@ the function returns 2 int s.
|
+
func vals() (int, int) {
return 3, 7
}
@@ -78,6 +81,7 @@ the function returns 2 int s.
|
+
@@ -91,6 +95,7 @@ call with multiple assignment.
|
+
a, b := vals()
fmt.Println(a)
fmt.Println(b)
@@ -106,6 +111,7 @@ use the blank identifier _ .
|
+
_, c := vals()
fmt.Println(c)
}
@@ -123,6 +129,7 @@ use the blank identifier _ .
|
+
$ go run multiple-return-values.go
3
7
@@ -139,6 +146,7 @@ feature of Go functions; we’ll look at this next.
|
+
|
diff --git a/public/mutexes b/public/mutexes
index c588d23..c830315 100644
--- a/public/mutexes
+++ b/public/mutexes
@@ -20,7 +20,6 @@
-
@@ -33,6 +32,7 @@ to safely access data across multiple goroutines.
+
|
@@ -42,6 +42,7 @@ to safely access data across multiple goroutines.
+
@@ -53,6 +54,7 @@ to safely access data across multiple goroutines.
|
+
import (
"fmt"
"math/rand"
@@ -71,6 +73,7 @@ to safely access data across multiple goroutines.
|
+
@@ -83,6 +86,7 @@ to safely access data across multiple goroutines.
|
+
var state = make(map[int]int)
@@ -95,6 +99,7 @@ to safely access data across multiple goroutines.
|
+
var mutex = &sync.Mutex{}
@@ -109,6 +114,7 @@ operations we perform against the state.
|
+
@@ -122,6 +128,7 @@ reads against the state.
|
+
for r := 0; r < 100; r++ {
go func() {
total := 0
@@ -142,6 +149,7 @@ the ops count.
|
+
key := rand.Intn(5)
mutex.Lock()
total += state[key]
@@ -165,6 +173,7 @@ case we need to do it manually.
|
+
runtime.Gosched()
}
}()
@@ -181,6 +190,7 @@ using the same pattern we did for reads.
|
+
for w := 0; w < 10; w++ {
go func() {
for {
@@ -206,6 +216,7 @@ using the same pattern we did for reads.
|
+
@@ -218,6 +229,7 @@ using the same pattern we did for reads.
|
+
opsFinal := atomic.LoadInt64(&ops)
fmt.Println("ops:", opsFinal)
@@ -231,6 +243,7 @@ using the same pattern we did for reads.
|
+
mutex.Lock()
fmt.Println("state:", state)
mutex.Unlock()
@@ -252,6 +265,7 @@ using the same pattern we did for reads.
|
+
$ go run mutexes.go
ops: 3598302
state: map[1:38 4:98 2:23 3:85 0:44]
@@ -267,6 +281,7 @@ management task using only goroutines and channels.
|
+
|
diff --git a/public/non-blocking-channel-operations b/public/non-blocking-channel-operations
index 55a6126..de4e98c 100644
--- a/public/non-blocking-channel-operations
+++ b/public/non-blocking-channel-operations
@@ -20,7 +20,6 @@
Go by Example: Non-Blocking Channel Operations
-
@@ -33,6 +32,7 @@ non-blocking multi-way select s.
+
|
@@ -42,6 +42,7 @@ non-blocking multi-way select s.
+
@@ -53,6 +54,7 @@ non-blocking multi-way select s.
|
+
@@ -64,6 +66,7 @@ non-blocking multi-way select s.
|
+
func main() {
messages := make(chan string)
signals := make(chan bool)
@@ -81,6 +84,7 @@ it will immediately take the default case.
|
+
select {
case msg := <-messages:
fmt.Println("received message", msg)
@@ -98,6 +102,7 @@ it will immediately take the default case.
|
+
msg := "hi"
select {
case messages <- msg:
@@ -119,6 +124,7 @@ on both messages and signals .
|
+
select {
case msg := <-messages:
fmt.Println("received message", msg)
@@ -142,6 +148,7 @@ on both messages and signals .
|
+
$ go run non-blocking-channel-operations.go
no message received
no message sent
diff --git a/public/number-parsing b/public/number-parsing
index b01d116..910359f 100644
--- a/public/number-parsing
+++ b/public/number-parsing
@@ -20,7 +20,6 @@
-
@@ -31,6 +30,7 @@ in many programs; here’s how to do it in Go.
+
|
@@ -40,6 +40,7 @@ in many programs; here’s how to do it in Go.
+
@@ -53,6 +54,7 @@ parsing.
|
+
import "strconv"
import "fmt"
@@ -65,6 +67,7 @@ parsing.
|
+
@@ -78,6 +81,7 @@ precision to parse.
|
+
f, _ := strconv.ParseFloat("1.234", 64)
fmt.Println(f)
@@ -93,6 +97,7 @@ bits.
|
+
i, _ := strconv.ParseInt("123", 0, 64)
fmt.Println(i)
@@ -106,6 +111,7 @@ bits.
|
+
d, _ := strconv.ParseInt("0x1c8", 0, 64)
fmt.Println(d)
@@ -119,6 +125,7 @@ bits.
|
+
u, _ := strconv.ParseUint("789", 0, 64)
fmt.Println(u)
@@ -133,6 +140,7 @@ bits.
|
+
k, _ := strconv.Atoi("135")
fmt.Println(k)
@@ -146,6 +154,7 @@ bits.
|
+
_, e := strconv.Atoi("wat")
fmt.Println(e)
}
@@ -163,6 +172,7 @@ bits.
|
+
$ go run number-parsing.go
1.234
123
@@ -181,6 +191,7 @@ bits.
|
+
|
diff --git a/public/panic b/public/panic
index c4ea20a..202bf66 100644
--- a/public/panic
+++ b/public/panic
@@ -20,7 +20,6 @@
-
@@ -33,6 +32,7 @@ aren’t prepared to handle gracefully.
+
|
@@ -42,6 +42,7 @@ aren’t prepared to handle gracefully.
+
@@ -53,6 +54,7 @@ aren’t prepared to handle gracefully.
|
+
@@ -64,6 +66,7 @@ aren’t prepared to handle gracefully.
|
+
@@ -78,6 +81,7 @@ site designed to panic.
|
+
@@ -93,6 +97,7 @@ returns an error value that we don’t know how to
|
+
_, err := os.Create("/tmp/file")
if err != nil {
panic(err)
@@ -115,6 +120,7 @@ a non-zero status.
|
+
$ go run panic.go
panic: a problem
@@ -127,6 +133,7 @@ a non-zero status.
|
+
goroutine 1 [running]:
main.main()
/.../panic.go:12 +0x47
@@ -145,6 +152,7 @@ to use error-indicating return values wherever possible.
|
+
|
diff --git a/public/pointers b/public/pointers
index 4f2d6ad..bc6e8ba 100644
--- a/public/pointers
+++ b/public/pointers
@@ -20,7 +20,6 @@
-
@@ -32,6 +31,7 @@ within your program.
+
|
@@ -41,6 +41,7 @@ within your program.
+
@@ -52,6 +53,7 @@ within your program.
|
+
@@ -68,6 +70,7 @@ from the one in the calling function.
|
+
func zeroval(ival int) {
ival = 0
}
@@ -87,6 +90,7 @@ value at the referenced address.
|
+
func zeroptr(iptr *int) {
*iptr = 0
}
@@ -100,6 +104,7 @@ value at the referenced address.
|
+
func main() {
i := 1
fmt.Println("initial:", i)
@@ -113,6 +118,7 @@ value at the referenced address.
|
+
zeroval(i)
fmt.Println("zeroval:", i)
@@ -127,6 +133,7 @@ i.e. a pointer to i .
|
+
zeroptr(&i)
fmt.Println("zeroptr:", i)
@@ -140,6 +147,7 @@ i.e. a pointer to i .
|
+
fmt.Println("pointer:", &i)
}
@@ -159,6 +167,7 @@ the memory address for that variable.
|
+
$ go run pointers.go
initial: 1
zeroval: 1
diff --git a/public/random-numbers b/public/random-numbers
index 1f36a81..25ba951 100644
--- a/public/random-numbers
+++ b/public/random-numbers
@@ -20,7 +20,6 @@
-
@@ -32,6 +31,7 @@ generation.
+
|
@@ -41,6 +41,7 @@ generation.
+
@@ -52,6 +53,7 @@ generation.
|
+
import "fmt"
import "math/rand"
@@ -64,6 +66,7 @@ generation.
|
+
@@ -77,6 +80,7 @@ generation.
|
+
fmt.Print(rand.Intn(100), ",")
fmt.Print(rand.Intn(100))
fmt.Println()
@@ -92,6 +96,7 @@ generation.
|
+
fmt.Println(rand.Float64())
@@ -105,6 +110,7 @@ other ranges, for example 5.0 <= f' < 10.0 .
|
+
fmt.Print((rand.Float64()*5)+5, ",")
fmt.Print((rand.Float64() * 5) + 5)
fmt.Println()
@@ -120,6 +126,7 @@ give it a well-known seed.
|
+
s1 := rand.NewSource(42)
r1 := rand.New(s1)
@@ -134,6 +141,7 @@ functions on the rand package.
|
+
fmt.Print(r1.Intn(100), ",")
fmt.Print(r1.Intn(100))
fmt.Println()
@@ -149,6 +157,7 @@ produces the same sequence of random numbers.
|
+
s2 := rand.NewSource(42)
r2 := rand.New(s2)
fmt.Print(r2.Intn(100), ",")
@@ -169,6 +178,7 @@ produces the same sequence of random numbers.
|
+
$ go run random-numbers.go
81,87
0.6645600532184904
@@ -188,6 +198,7 @@ that Go can provide.
|
+
|
diff --git a/public/range b/public/range
index a4339c4..209c982 100644
--- a/public/range
+++ b/public/range
@@ -20,7 +20,6 @@
-
@@ -32,6 +31,7 @@ of the data structures we’ve already learned.
+
|
@@ -41,6 +41,7 @@ of the data structures we’ve already learned.
+
@@ -52,6 +53,7 @@ of the data structures we’ve already learned.
|
+
@@ -63,6 +65,7 @@ of the data structures we’ve already learned.
|
+
@@ -76,6 +79,7 @@ Arrays work like this too.
|
+
nums := []int{2, 3, 4}
sum := 0
for _, num := range nums {
@@ -97,6 +101,7 @@ the indexes though.
|
+
for i, num := range nums {
if num == 3 {
fmt.Println("index:", i)
@@ -113,6 +118,7 @@ the indexes though.
|
+
kvs := map[string]string{"a": "apple", "b": "banana"}
for k, v := range kvs {
fmt.Printf("%s -> %s\n", k, v)
@@ -130,6 +136,7 @@ of the rune and the second the rune itself.
|
+
for i, c := range "go" {
fmt.Println(i, c)
}
@@ -148,6 +155,7 @@ of the rune and the second the rune itself.
|
+
$ go run range.go
sum: 9
index: 1
diff --git a/public/range-over-channels b/public/range-over-channels
index 2a9cf69..202fb59 100644
--- a/public/range-over-channels
+++ b/public/range-over-channels
@@ -20,7 +20,6 @@
-
@@ -33,6 +32,7 @@ values received from a channel.
+
|
@@ -42,6 +42,7 @@ values received from a channel.
+
@@ -53,6 +54,7 @@ values received from a channel.
|
+
@@ -64,6 +66,7 @@ values received from a channel.
|
+
@@ -76,6 +79,7 @@ values received from a channel.
|
+
queue := make(chan string, 2)
queue <- "one"
queue <- "two"
@@ -95,6 +99,7 @@ we’d block on a 3rd receive in the loop.
|
+
for elem := range queue {
fmt.Println(elem)
}
@@ -113,6 +118,7 @@ we’d block on a 3rd receive in the loop.
|
+
$ go run range-over-channels.go
one
two
@@ -129,6 +135,7 @@ values be received.
|
+
|
diff --git a/public/rate-limiting b/public/rate-limiting
index 4e50cdc..7eae4fc 100644
--- a/public/rate-limiting
+++ b/public/rate-limiting
@@ -20,7 +20,6 @@
-
@@ -34,6 +33,7 @@ channels, and tickers.
+
|
@@ -43,6 +43,7 @@ channels, and tickers.
+
@@ -54,6 +55,7 @@ channels, and tickers.
|
+
import "time"
import "fmt"
@@ -66,6 +68,7 @@ channels, and tickers.
|
+
@@ -81,6 +84,7 @@ same name.
|
+
requests := make(chan int, 5)
for i := 1; i <= 5; i++ {
requests <- i
@@ -99,6 +103,7 @@ our rate limiting scheme.
|
+
limiter := time.Tick(time.Millisecond * 200)
@@ -113,6 +118,7 @@ before serving each request, we limit ourselves to
|
+
for req := range requests {
<-limiter
fmt.Println("request", req, time.Now())
@@ -132,6 +138,7 @@ channel will allow bursts of up to 3 events.
|
+
burstyLimiter := make(chan time.Time, 3)
@@ -144,6 +151,7 @@ channel will allow bursts of up to 3 events.
|
+
for i := 0; i < 3; i++ {
burstyLimiter <- time.Now()
}
@@ -159,6 +167,7 @@ value to burstyLimiter , up to its limit of 3.
|
+
go func() {
for t := range time.Tick(time.Millisecond * 200) {
burstyLimiter <- t
@@ -177,6 +186,7 @@ of burstyLimiter .
|
+
burstyRequests := make(chan int, 5)
for i := 1; i <= 5; i++ {
burstyRequests <- i
@@ -203,6 +213,7 @@ handled once every ~200 milliseconds as desired.
|
+
$ go run rate-limiting.go
request 1 2012-10-19 00:38:18.687438 +0000 UTC
request 2 2012-10-19 00:38:18.887471 +0000 UTC
@@ -222,6 +233,7 @@ then serve the remaining 2 with ~200ms delays each.
|
+
request 1 2012-10-19 00:38:20.487578 +0000 UTC
request 2 2012-10-19 00:38:20.487645 +0000 UTC
request 3 2012-10-19 00:38:20.487676 +0000 UTC
diff --git a/public/reading-files b/public/reading-files
index b946860..f491aff 100644
--- a/public/reading-files
+++ b/public/reading-files
@@ -20,7 +20,6 @@
-
@@ -32,6 +31,7 @@ reading files.
+
|
@@ -41,6 +41,7 @@ reading files.
+
@@ -52,6 +53,7 @@ reading files.
|
+
import (
"bufio"
"fmt"
@@ -71,6 +73,7 @@ This helper will streamline our error checks below.
|
+
func check(e error) {
if e != nil {
panic(e)
@@ -86,6 +89,7 @@ This helper will streamline our error checks below.
|
+
@@ -99,6 +103,7 @@ slurping a file’s entire contents into memory.
|
+
dat, err := ioutil.ReadFile("/tmp/dat")
check(err)
fmt.Print(string(dat))
@@ -115,6 +120,7 @@ by Open ing a file to obtain an os.File value.
|
+
f, err := os.Open("/tmp/dat")
@@ -129,6 +135,7 @@ actually were read.
|
+
b1 := make([]byte, 5)
n1, err := f.Read(b1)
check(err)
@@ -145,6 +152,7 @@ and Read from there.
|
+
o2, err := f.Seek(6, 0)
check(err)
b2 := make([]byte, 2)
@@ -165,6 +173,7 @@ implemented with ReadAtLeast .
|
+
o3, err := f.Seek(6, 0)
check(err)
b3 := make([]byte, 2)
@@ -183,6 +192,7 @@ accomplishes this.
|
+
_, err = f.Seek(0, 0)
check(err)
@@ -199,6 +209,7 @@ reading methods it provides.
|
+
r4 := bufio.NewReader(f)
b4, err := r4.Peek(5)
check(err)
@@ -216,6 +227,7 @@ be scheduled immediately after Open ing with
|
+
@@ -227,6 +239,7 @@ be scheduled immediately after Open ing with
|
+
@@ -242,6 +255,7 @@ be scheduled immediately after Open ing with
|
+
$ echo "hello" > /tmp/dat
$ echo "go" >> /tmp/dat
$ go run reading-files.go
@@ -262,6 +276,7 @@ be scheduled immediately after Open ing with
|
+
|
diff --git a/public/recursion b/public/recursion
index 516faa2..295fad2 100644
--- a/public/recursion
+++ b/public/recursion
@@ -20,7 +20,6 @@
-
@@ -32,6 +31,7 @@ Here’s a classic factorial example.
+
|
@@ -41,6 +41,7 @@ Here’s a classic factorial example.
+
@@ -52,6 +53,7 @@ Here’s a classic factorial example.
|
+
@@ -65,6 +67,7 @@ base case of fact(0) .
|
+
func fact(n int) int {
if n == 0 {
return 1
@@ -81,6 +84,7 @@ base case of fact(0) .
|
+
func main() {
fmt.Println(fact(7))
}
@@ -98,6 +102,7 @@ base case of fact(0) .
|
+
$ go run recursion.go
5040
diff --git a/public/regular-expressions b/public/regular-expressions
index ca8a19f..dd9af01 100644
--- a/public/regular-expressions
+++ b/public/regular-expressions
@@ -20,7 +20,6 @@
-
@@ -32,6 +31,7 @@ in Go.
+
|
@@ -41,6 +41,7 @@ in Go.
+
@@ -52,6 +53,7 @@ in Go.
|
+
import "bytes"
import "fmt"
import "regexp"
@@ -65,6 +67,7 @@ in Go.
|
+
@@ -77,6 +80,7 @@ in Go.
|
+
match, _ := regexp.MatchString("p([a-z]+)ch", "peach")
fmt.Println(match)
@@ -92,6 +96,7 @@ optimized Regexp struct.
|
+
r, _ := regexp.Compile("p([a-z]+)ch")
@@ -105,6 +110,7 @@ a match test like we saw earlier.
|
+
fmt.Println(r.MatchString("peach"))
@@ -117,6 +123,7 @@ a match test like we saw earlier.
|
+
fmt.Println(r.FindString("peach punch"))
@@ -131,6 +138,7 @@ matching text.
|
+
fmt.Println(r.FindStringIndex("peach punch"))
@@ -146,6 +154,7 @@ information for both p([a-z]+)ch and ([a-z]+) .
|
+
fmt.Println(r.FindStringSubmatch("peach punch"))
@@ -159,6 +168,7 @@ indexes of matches and submatches.
|
+
fmt.Println(r.FindStringSubmatchIndex("peach punch"))
@@ -173,6 +183,7 @@ example to find all matches for a regexp.
|
+
fmt.Println(r.FindAllString("peach punch pinch", -1))
@@ -186,6 +197,7 @@ functions we saw above as well.
|
+
fmt.Println(r.FindAllStringSubmatchIndex(
"peach punch pinch", -1))
@@ -201,6 +213,7 @@ of matches.
|
+
fmt.Println(r.FindAllString("peach punch pinch", 2))
@@ -216,6 +229,7 @@ function name.
|
+
fmt.Println(r.Match([]byte("peach")))
@@ -231,6 +245,7 @@ constants because it has 2 return values.
|
+
r = regexp.MustCompile("p([a-z]+)ch")
fmt.Println(r)
@@ -245,6 +260,7 @@ subsets of strings with other values.
|
+
fmt.Println(r.ReplaceAllString("a peach", "<fruit>"))
@@ -258,6 +274,7 @@ text with a given function.
|
+
in := []byte("a peach")
out := r.ReplaceAllFunc(in, bytes.ToUpper)
fmt.Println(string(out))
@@ -276,6 +293,7 @@ text with a given function.
|
+
$ go run regular-expressions.go
true
true
@@ -302,6 +320,7 @@ the regexp package docs
|
+
|
diff --git a/public/select b/public/select
index c4d94c9..33e0bcf 100644
--- a/public/select
+++ b/public/select
@@ -20,7 +20,6 @@
-
@@ -32,6 +31,7 @@ select is powerful feature of Go.
+
|
@@ -41,6 +41,7 @@ select is powerful feature of Go.
+
@@ -52,6 +53,7 @@ select is powerful feature of Go.
|
+
import "time"
import "fmt"
@@ -64,6 +66,7 @@ select is powerful feature of Go.
|
+
@@ -76,6 +79,7 @@ select is powerful feature of Go.
|
+
c1 := make(chan string)
c2 := make(chan string)
@@ -91,6 +95,7 @@ executing in concurrent goroutines.
|
+
go func() {
time.Sleep(time.Second * 1)
c1 <- "one"
@@ -111,6 +116,7 @@ simultaneously, printing each one as it arrives.
|
+
for i := 0; i < 2; i++ {
select {
case msg1 := <-c1:
@@ -136,6 +142,7 @@ expected.
|
+
$ time go run select.go
received one
received two
@@ -152,6 +159,7 @@ concurrently.
|
+
diff --git a/public/sha1-hashes b/public/sha1-hashes
index 0d0e1a9..285c703 100644
--- a/public/sha1-hashes
+++ b/public/sha1-hashes
@@ -20,7 +20,6 @@
-
@@ -35,6 +34,7 @@ compute SHA1 hashes in Go.
+
|
@@ -44,6 +44,7 @@ compute SHA1 hashes in Go.
+
@@ -57,6 +58,7 @@ compute SHA1 hashes in Go.
|
+
import "crypto/sha1"
import "fmt"
@@ -69,6 +71,7 @@ compute SHA1 hashes in Go.
|
+
func main() {
s := "sha1 this string"
@@ -84,6 +87,7 @@ Here we start with a new hash.
|
+
@@ -97,6 +101,7 @@ use []byte(s) to coerce it to bytes.
|
+
@@ -111,6 +116,7 @@ to an existing byte slice: it usually isn’t needed.
|
+
@@ -125,6 +131,7 @@ a hash results to a hex string.
|
+
fmt.Println(s)
fmt.Printf("%x\n", bs)
}
@@ -144,6 +151,7 @@ a human-readable hex format.
|
+
$ go run sha1-hashes.go
sha1 this string
cf23df2207d99a74fbe169e3eba035e633b65d94
@@ -160,6 +168,7 @@ import crypto/md5 and use md5.New() .
|
+
|
@@ -172,6 +181,7 @@ you should carefully research
+
|
diff --git a/public/signals b/public/signals
index 5ed5dbc..a149a0e 100644
--- a/public/signals
+++ b/public/signals
@@ -20,7 +20,6 @@
-
@@ -35,6 +34,7 @@ Here’s how to handle signals in Go with channels.
+
|
@@ -44,6 +44,7 @@ Here’s how to handle signals in Go with channels.
+
@@ -55,6 +56,7 @@ Here’s how to handle signals in Go with channels.
|
+
import "fmt"
import "os"
import "os/signal"
@@ -69,6 +71,7 @@ Here’s how to handle signals in Go with channels.
|
+
@@ -84,6 +87,7 @@ notify us when the program can exit.)
|
+
sigs := make(chan os.Signal, 1)
done := make(chan bool, 1)
@@ -98,6 +102,7 @@ receive notifications of the specified signals.
|
+
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
@@ -112,6 +117,7 @@ and then notify the program that it can finish.
|
+
go func() {
sig := <-sigs
fmt.Println()
@@ -131,6 +137,7 @@ above sending a value on done ) and then exit.
|
+
fmt.Println("awaiting signal")
<-done
fmt.Println("exiting")
@@ -153,6 +160,7 @@ causing the program to print interrupt and then exit.
|
+
$ go run signals.go
awaiting signal
^C
diff --git a/public/slices b/public/slices
index 0f282ec..e69b209 100644
--- a/public/slices
+++ b/public/slices
@@ -20,7 +20,6 @@
-
@@ -31,6 +30,7 @@ powerful interface to sequences than arrays.
+
|
@@ -40,6 +40,7 @@ powerful interface to sequences than arrays.
+
@@ -51,6 +52,7 @@ powerful interface to sequences than arrays.
|
+
@@ -62,6 +64,7 @@ powerful interface to sequences than arrays.
|
+
@@ -78,6 +81,7 @@ the builtin make . Here we make a slice of
|
+
s := make([]string, 3)
fmt.Println("emp:", s)
@@ -91,6 +95,7 @@ the builtin make . Here we make a slice of
|
+
s[0] = "a"
s[1] = "b"
s[2] = "c"
@@ -107,6 +112,7 @@ the builtin make . Here we make a slice of
|
+
fmt.Println("len:", len(s))
@@ -124,6 +130,7 @@ append as we may get a new slice value.
|
+
s = append(s, "d")
s = append(s, "e", "f")
fmt.Println("apd:", s)
@@ -140,6 +147,7 @@ into c from s .
|
+
c := make([]string, len(s))
copy(c, s)
fmt.Println("cpy:", c)
@@ -156,6 +164,7 @@ of the elements s[2] , s[3] , and s[4] .
|
+
l := s[2:5]
fmt.Println("sl1:", l)
@@ -169,6 +178,7 @@ of the elements s[2] , s[3] , and s[4] .
|
+
l = s[:5]
fmt.Println("sl2:", l)
@@ -182,6 +192,7 @@ of the elements s[2] , s[3] , and s[4] .
|
+
l = s[2:]
fmt.Println("sl3:", l)
@@ -196,6 +207,7 @@ in a single line as well.
|
+
t := []string{"g", "h", "i"}
fmt.Println("dcl:", t)
@@ -211,6 +223,7 @@ vary, unlike with multi-dimensional arrays.
|
+
twoD := make([][]int, 3)
for i := 0; i < 3; i++ {
innerLen := i + 1
@@ -237,6 +250,7 @@ they are rendered similarly by fmt.Println .
|
+
$ go run slices.go
emp: [ ]
set: [a b c]
@@ -262,6 +276,7 @@ implementation of slices in Go.
|
+
|
@@ -273,6 +288,7 @@ Go’s other key builtin data structure: maps.
+
|
diff --git a/public/sorting b/public/sorting
index bd380b1..31dd745 100644
--- a/public/sorting
+++ b/public/sorting
@@ -20,7 +20,6 @@
-
@@ -32,6 +31,7 @@ builtins first.
+
|
@@ -41,6 +41,7 @@ builtins first.
+
@@ -52,6 +53,7 @@ builtins first.
|
+
import "fmt"
import "sort"
@@ -64,6 +66,7 @@ builtins first.
|
+
@@ -79,6 +82,7 @@ return a new one.
|
+
strs := []string{"c", "a", "b"}
sort.Strings(strs)
fmt.Println("Strings:", strs)
@@ -93,6 +97,7 @@ return a new one.
|
+
ints := []int{7, 2, 4}
sort.Ints(ints)
fmt.Println("Ints: ", ints)
@@ -108,6 +113,7 @@ already in sorted order.
|
+
s := sort.IntsAreSorted(ints)
fmt.Println("Sorted: ", s)
}
@@ -127,6 +133,7 @@ slices and true as the result of our AreSorted test.
|
+
$ go run sorting.go
Strings: [a b c]
Ints: [2 4 7]
diff --git a/public/sorting-by-functions b/public/sorting-by-functions
index 4b01d4f..85af568 100644
--- a/public/sorting-by-functions
+++ b/public/sorting-by-functions
@@ -20,7 +20,6 @@
-
@@ -34,6 +33,7 @@ in Go.
+
|
@@ -43,6 +43,7 @@ in Go.
+
@@ -54,6 +55,7 @@ in Go.
|
+
import "sort"
import "fmt"
@@ -70,6 +72,7 @@ type.
|
+
@@ -88,6 +91,7 @@ we use len(s[i]) and len(s[j]) here.
|
+
func (s ByLength) Len() int {
return len(s)
}
@@ -111,6 +115,7 @@ slice.
|
+
func main() {
fruits := []string{"peach", "banana", "kiwi"}
sort.Sort(ByLength(fruits))
@@ -132,6 +137,7 @@ length, as desired.
|
+
$ go run sorting-by-functions.go
[kiwi peach banana]
@@ -149,6 +155,7 @@ functions.
|
+
|
diff --git a/public/spawning-processes b/public/spawning-processes
index 8279f46..a6d4da7 100644
--- a/public/spawning-processes
+++ b/public/spawning-processes
@@ -20,7 +20,6 @@
-
@@ -35,6 +34,7 @@ of spawning processes from Go.
+
|
@@ -44,6 +44,7 @@ of spawning processes from Go.
+
@@ -55,6 +56,7 @@ of spawning processes from Go.
|
+
import "fmt"
import "io/ioutil"
import "os/exec"
@@ -68,6 +70,7 @@ of spawning processes from Go.
|
+
@@ -83,6 +86,7 @@ to represent this external process.
|
+
dateCmd := exec.Command("date")
@@ -98,6 +102,7 @@ and collecting its output. If there were no errors,
|
+
dateOut, err := dateCmd.Output()
if err != nil {
panic(err)
@@ -117,6 +122,7 @@ where we pipe data to the external process on its
|
+
grepCmd := exec.Command("grep", "hello")
@@ -132,6 +138,7 @@ to exit.
|
+
grepIn, _ := grepCmd.StdinPipe()
grepOut, _ := grepCmd.StdoutPipe()
grepCmd.Start()
@@ -154,6 +161,7 @@ exactly the same way.
|
+
fmt.Println("> grep hello")
fmt.Println(string(grepBytes))
@@ -172,6 +180,7 @@ option:
|
+
lsCmd := exec.Command("bash", "-c", "ls -a -l -h")
lsOut, err := lsCmd.Output()
if err != nil {
@@ -196,6 +205,7 @@ as if we had run them directly from the command-line.
|
+
$ go run spawning-processes.go
> date
Wed Oct 10 09:53:11 PDT 2012
@@ -209,6 +219,7 @@ as if we had run them directly from the command-line.
|
+
@@ -221,6 +232,7 @@ as if we had run them directly from the command-line.
|
+
> ls -a -l -h
drwxr-xr-x 4 mark 136B Oct 3 16:29 .
drwxr-xr-x 91 mark 3.0K Oct 3 12:50 ..
diff --git a/public/stateful-goroutines b/public/stateful-goroutines
index 03b2626..485ec2f 100644
--- a/public/stateful-goroutines
+++ b/public/stateful-goroutines
@@ -20,7 +20,6 @@
-
@@ -37,6 +36,7 @@ by exactly 1 goroutine.
+
|
@@ -46,6 +46,7 @@ by exactly 1 goroutine.
+
@@ -57,6 +58,7 @@ by exactly 1 goroutine.
|
+
import (
"fmt"
"math/rand"
@@ -81,6 +83,7 @@ goroutine to respond.
|
+
type readOp struct {
key int
resp chan int
@@ -100,6 +103,7 @@ goroutine to respond.
|
+
@@ -113,6 +117,7 @@ example.
|
+
var state = make(map[int]int)
@@ -126,6 +131,7 @@ perform.
|
+
@@ -140,6 +146,7 @@ respectively.
|
+
reads := make(chan *readOp)
writes := make(chan *writeOp)
@@ -159,6 +166,7 @@ on the response channel resp to indicate success
|
+
go func() {
for {
select {
@@ -185,6 +193,7 @@ result over the provided resp channel.
|
+
for r := 0; r < 100; r++ {
go func() {
for {
@@ -209,6 +218,7 @@ approach.
|
+
for w := 0; w < 10; w++ {
go func() {
for {
@@ -233,6 +243,7 @@ approach.
|
+
@@ -245,6 +256,7 @@ approach.
|
+
opsFinal := atomic.LoadInt64(&ops)
fmt.Println("ops:", opsFinal)
}
@@ -265,6 +277,7 @@ operations per second.
|
+
$ go run stateful-goroutines.go
ops: 807434
@@ -285,6 +298,7 @@ program.
|
+
|
diff --git a/public/string-formatting b/public/string-formatting
index 015b4df..9e54b0a 100644
--- a/public/string-formatting
+++ b/public/string-formatting
@@ -20,7 +20,6 @@
-
@@ -32,6 +31,7 @@ common string formatting tasks.
+
|
@@ -41,6 +41,7 @@ common string formatting tasks.
+
@@ -52,6 +53,7 @@ common string formatting tasks.
|
+
@@ -64,6 +66,7 @@ common string formatting tasks.
|
+
type point struct {
x, y int
}
@@ -77,6 +80,7 @@ common string formatting tasks.
|
+
@@ -91,6 +95,7 @@ an instance of our point struct.
|
+
p := point{1, 2}
fmt.Printf("%v\n", p)
@@ -105,6 +110,7 @@ include the struct’s field names.
|
+
@@ -119,6 +125,7 @@ would produce that value.
|
+
@@ -131,6 +138,7 @@ would produce that value.
|
+
@@ -143,6 +151,7 @@ would produce that value.
|
+
@@ -156,6 +165,7 @@ Use %d for standard, base-10 formatting.
|
+
@@ -168,6 +178,7 @@ Use %d for standard, base-10 formatting.
|
+
@@ -181,6 +192,7 @@ given integer.
|
+
@@ -193,6 +205,7 @@ given integer.
|
+
@@ -206,6 +219,7 @@ floats. For basic decimal formatting use %f .
|
+
@@ -219,6 +233,7 @@ different versions of) scientific notation.
|
+
fmt.Printf("%e\n", 123400000.0)
fmt.Printf("%E\n", 123400000.0)
@@ -232,6 +247,7 @@ different versions of) scientific notation.
|
+
fmt.Printf("%s\n", "\"string\"")
@@ -244,6 +260,7 @@ different versions of) scientific notation.
|
+
fmt.Printf("%q\n", "\"string\"")
@@ -258,6 +275,7 @@ per byte of input.
|
+
fmt.Printf("%x\n", "hex this")
@@ -270,6 +288,7 @@ per byte of input.
|
+
@@ -287,6 +306,7 @@ spaces.
|
+
fmt.Printf("|%6d|%6d|\n", 12, 345)
@@ -302,6 +322,7 @@ width.precision syntax.
|
+
fmt.Printf("|%6.2f|%6.2f|\n", 1.2, 3.45)
@@ -314,6 +335,7 @@ width.precision syntax.
|
+
fmt.Printf("|%-6.2f|%-6.2f|\n", 1.2, 3.45)
@@ -328,6 +350,7 @@ table-like output. For basic right-justified width.
|
+
fmt.Printf("|%6s|%6s|\n", "foo", "b")
@@ -340,6 +363,7 @@ table-like output. For basic right-justified width.
|
+
fmt.Printf("|%-6s|%-6s|\n", "foo", "b")
@@ -354,6 +378,7 @@ and returns a string without printing it anywhere.
|
+
s := fmt.Sprintf("a %s", "string")
fmt.Println(s)
@@ -368,6 +393,7 @@ and returns a string without printing it anywhere.
|
+
fmt.Fprintf(os.Stderr, "an %s\n", "error")
}
@@ -384,6 +410,7 @@ and returns a string without printing it anywhere.
|
+
$ go run string-formatting.go
{1 2}
{x:1 y:2}
diff --git a/public/string-functions b/public/string-functions
index 5fe25ce..6b83df4 100644
--- a/public/string-functions
+++ b/public/string-functions
@@ -20,7 +20,6 @@
-
@@ -32,6 +31,7 @@ to give you a sense of the package.
+
|
@@ -41,6 +41,7 @@ to give you a sense of the package.
+
@@ -52,6 +53,7 @@ to give you a sense of the package.
|
+
import s "strings"
import "fmt"
@@ -66,6 +68,7 @@ it a lot below.
|
+
@@ -77,6 +80,7 @@ it a lot below.
|
+
@@ -93,6 +97,7 @@ as the first argument to the function.
|
+
p("Contains: ", s.Contains("test", "es"))
p("Count: ", s.Count("test", "t"))
p("HasPrefix: ", s.HasPrefix("test", "te"))
@@ -118,6 +123,7 @@ package docs.
|
+
|
@@ -130,6 +136,7 @@ and getting a character by index.
+
p("Len: ", len("hello"))
p("Char:", "hello"[1])
}
@@ -147,6 +154,7 @@ and getting a character by index.
|
+
$ go run string-functions.go
Contains: true
Count: 2
@@ -170,6 +178,7 @@ and getting a character by index.
|
+
diff --git a/public/structs b/public/structs
index 34dfc36..7b41cd5 100644
--- a/public/structs
+++ b/public/structs
@@ -20,7 +20,6 @@
-
@@ -32,6 +31,7 @@ records.
+
|
@@ -41,6 +41,7 @@ records.
+
@@ -52,6 +53,7 @@ records.
|
+
@@ -64,6 +66,7 @@ records.
|
+
type person struct {
name string
age int
@@ -78,6 +81,7 @@ records.
|
+
@@ -90,6 +94,7 @@ records.
|
+
fmt.Println(person{"Bob", 20})
@@ -102,6 +107,7 @@ records.
|
+
fmt.Println(person{name: "Alice", age: 30})
@@ -114,6 +120,7 @@ records.
|
+
fmt.Println(person{name: "Fred"})
@@ -126,6 +133,7 @@ records.
|
+
fmt.Println(&person{name: "Ann", age: 40})
@@ -138,6 +146,7 @@ records.
|
+
s := person{name: "Sean", age: 50}
fmt.Println(s.name)
@@ -152,6 +161,7 @@ pointers are automatically dereferenced.
|
+
sp := &s
fmt.Println(sp.age)
@@ -165,6 +175,7 @@ pointers are automatically dereferenced.
|
+
sp.age = 51
fmt.Println(sp.age)
}
@@ -182,6 +193,7 @@ pointers are automatically dereferenced.
|
+
$ go run structs.go
{Bob 20}
{Alice 30}
diff --git a/public/switch b/public/switch
index e51eb62..f999571 100644
--- a/public/switch
+++ b/public/switch
@@ -20,7 +20,6 @@
-
@@ -31,6 +30,7 @@ branches.
+
|
@@ -40,6 +40,7 @@ branches.
+
@@ -51,6 +52,7 @@ branches.
|
+
import "fmt"
import "time"
@@ -63,6 +65,7 @@ branches.
|
+
@@ -75,6 +78,7 @@ branches.
|
+
i := 2
fmt.Print("write ", i, " as ")
switch i {
@@ -98,6 +102,7 @@ in the same case statement. We use the optional
|
+
switch time.Now().Weekday() {
case time.Saturday, time.Sunday:
fmt.Println("it's the weekend")
@@ -117,6 +122,7 @@ to express if/else logic. Here we also show how the
|
+
t := time.Now()
switch {
case t.Hour() < 12:
@@ -139,6 +145,7 @@ to express if/else logic. Here we also show how the
|
+
$ go run switch.go
write 2 as two
it's the weekend
diff --git a/public/tickers b/public/tickers
index 7c33751..48fd574 100644
--- a/public/tickers
+++ b/public/tickers
@@ -20,7 +20,6 @@
-
@@ -34,6 +33,7 @@ periodically until we stop it.
+
|
@@ -43,6 +43,7 @@ periodically until we stop it.
+
@@ -54,6 +55,7 @@ periodically until we stop it.
|
+
import "time"
import "fmt"
@@ -66,6 +68,7 @@ periodically until we stop it.
|
+
@@ -81,6 +84,7 @@ the values as they arrive every 500ms.
|
+
ticker := time.NewTicker(time.Millisecond * 500)
go func() {
for t := range ticker.C {
@@ -100,6 +104,7 @@ channel. We’ll stop ours after 1500ms.
|
+
time.Sleep(time.Millisecond * 1500)
ticker.Stop()
fmt.Println("Ticker stopped")
@@ -120,6 +125,7 @@ before we stop it.
|
+
$ go run tickers.go
Tick at 2012-09-23 11:29:56.487625 -0700 PDT
Tick at 2012-09-23 11:29:56.988063 -0700 PDT
diff --git a/public/time b/public/time
index ec48522..76eb47c 100644
--- a/public/time
+++ b/public/time
@@ -20,7 +20,6 @@
-
@@ -31,6 +30,7 @@ here are some examples.
+
|
@@ -40,6 +40,7 @@ here are some examples.
+
@@ -51,6 +52,7 @@ here are some examples.
|
+
import "fmt"
import "time"
@@ -63,6 +65,7 @@ here are some examples.
|
+
func main() {
p := fmt.Println
@@ -76,6 +79,7 @@ here are some examples.
|
+
@@ -91,6 +95,7 @@ with a Location , i.e. time zone.
|
+
then := time.Date(
2009, 11, 17, 20, 34, 58, 651387237, time.UTC)
p(then)
@@ -106,6 +111,7 @@ value as expected.
|
+
p(then.Year())
p(then.Month())
p(then.Day())
@@ -125,6 +131,7 @@ value as expected.
|
+
@@ -139,6 +146,7 @@ as the second, respectively.
|
+
p(then.Before(now))
p(then.After(now))
p(then.Equal(now))
@@ -154,6 +162,7 @@ the interval between two times.
|
+
diff := now.Sub(then)
p(diff)
@@ -168,6 +177,7 @@ various units.
|
+
p(diff.Hours())
p(diff.Minutes())
p(diff.Seconds())
@@ -185,6 +195,7 @@ duration.
|
+
p(then.Add(diff))
p(then.Add(-diff))
}
@@ -202,6 +213,7 @@ duration.
|
+
$ go run time.go
2012-10-31 15:50:13.793654 +0000 UTC
2009-11-17 20:34:58.651387237 +0000 UTC
@@ -236,6 +248,7 @@ the Unix epoch.
|
+
|
diff --git a/public/time-formatting-parsing b/public/time-formatting-parsing
index 41edb34..73cc45b 100644
--- a/public/time-formatting-parsing
+++ b/public/time-formatting-parsing
@@ -20,7 +20,6 @@
Go by Example: Time Formatting / Parsing
-
@@ -31,6 +30,7 @@ pattern-based layouts.
+
|
@@ -40,6 +40,7 @@ pattern-based layouts.
+
@@ -51,6 +52,7 @@ pattern-based layouts.
|
+
import "fmt"
import "time"
@@ -63,6 +65,7 @@ pattern-based layouts.
|
+
func main() {
p := fmt.Println
@@ -77,6 +80,7 @@ according to RFC3339.
|
+
t := time.Now()
p(t.Format("2006-01-02T15:04:05Z07:00"))
@@ -95,6 +99,7 @@ formatting.
|
+
p(t.Format("3:04PM"))
p(t.Format("Mon Jan _2 15:04:05 2006"))
p(t.Format("2006-01-02T15:04:05.999999-07:00"))
@@ -111,6 +116,7 @@ components of the time value.
|
+
fmt.Printf("%d-%02d-%02dT%02d:%02d:%02d-00:00\n",
t.Year(), t.Month(), t.Day(),
t.Hour(), t.Minute(), t.Second())
@@ -127,6 +133,7 @@ with some of the layouts used above.
|
+
withNanos := "2006-01-02T15:04:05.999999999-07:00"
t1, e := time.Parse(
withNanos,
@@ -147,6 +154,7 @@ explaining the parsing problem.
|
+
ansic := "Mon Jan _2 15:04:05 2006"
_, e = time.Parse(ansic, "8:41PM")
p(e)
@@ -162,6 +170,7 @@ use for both formatting and parsing.
|
+
p(t.Format(time.Kitchen))
}
@@ -178,6 +187,7 @@ use for both formatting and parsing.
|
+
$ go run time-formatting-parsing.go
2012-11-02T09:35:03-07:00
9:35AM
diff --git a/public/timeouts b/public/timeouts
index 7a0f185..e8b6567 100644
--- a/public/timeouts
+++ b/public/timeouts
@@ -20,7 +20,6 @@
-
@@ -33,6 +32,7 @@ elegant thanks to channels and select .
+
|
@@ -42,6 +42,7 @@ elegant thanks to channels and select .
+
@@ -53,6 +54,7 @@ elegant thanks to channels and select .
|
+
import "time"
import "fmt"
@@ -65,6 +67,7 @@ elegant thanks to channels and select .
|
+
@@ -79,6 +82,7 @@ after 2s.
|
+
c1 := make(chan string, 1)
go func() {
time.Sleep(time.Second * 2)
@@ -100,6 +104,7 @@ if the operation takes more than the allowed 1s.
|
+
select {
case res := <-c1:
fmt.Println(res)
@@ -118,6 +123,7 @@ from c2 will succeed and we’ll print the result.
|
+
c2 := make(chan string, 1)
go func() {
time.Sleep(time.Second * 2)
@@ -146,6 +152,7 @@ out and the second succeeding.
|
+
$ go run timeouts.go
timeout 1
result 2
@@ -164,6 +171,7 @@ examples of this next: timers and tickers.
|
+
|
diff --git a/public/timers b/public/timers
index e161537..77aec09 100644
--- a/public/timers
+++ b/public/timers
@@ -20,7 +20,6 @@
-
@@ -34,6 +33,7 @@ at tickers.
+
|
@@ -43,6 +43,7 @@ at tickers.
+
@@ -54,6 +55,7 @@ at tickers.
|
+
import "time"
import "fmt"
@@ -66,6 +68,7 @@ at tickers.
|
+
@@ -81,6 +84,7 @@ time. This timer will wait 2 seconds.
|
+
timer1 := time.NewTimer(time.Second * 2)
@@ -95,6 +99,7 @@ expired.
|
+
<-timer1.C
fmt.Println("Timer 1 expired")
@@ -111,6 +116,7 @@ Here’s an example of that.
|
+
timer2 := time.NewTimer(time.Second)
go func() {
<-timer2.C
@@ -138,6 +144,7 @@ a chance to expire.
|
+
$ go run timers.go
Timer 1 expired
Timer 2 stopped
diff --git a/public/url-parsing b/public/url-parsing
index aeeb426..b514a5e 100644
--- a/public/url-parsing
+++ b/public/url-parsing
@@ -20,7 +20,6 @@
-
@@ -31,6 +30,7 @@ Here’s how to parse URLs in Go.
+
|
@@ -40,6 +40,7 @@ Here’s how to parse URLs in Go.
+
@@ -51,6 +52,7 @@ Here’s how to parse URLs in Go.
|
+
import "fmt"
import "net/url"
import "strings"
@@ -64,6 +66,7 @@ Here’s how to parse URLs in Go.
|
+
@@ -78,6 +81,7 @@ query params, and query fragment.
|
+
s := "postgres://user:pass@host.com:5432/path?k=v#f"
@@ -90,6 +94,7 @@ query params, and query fragment.
|
+
u, err := url.Parse(s)
if err != nil {
panic(err)
@@ -105,6 +110,7 @@ query params, and query fragment.
|
+
@@ -119,6 +125,7 @@ values.
|
+
fmt.Println(u.User)
fmt.Println(u.User.Username())
p, _ := u.User.Password()
@@ -136,6 +143,7 @@ the port.
|
+
fmt.Println(u.Host)
h := strings.Split(u.Host, ":")
fmt.Println(h[0])
@@ -152,6 +160,7 @@ the # .
|
+
fmt.Println(u.Path)
fmt.Println(u.Fragment)
@@ -169,6 +178,7 @@ if you only want the first value.
|
+
fmt.Println(u.RawQuery)
m, _ := url.ParseQuery(u.RawQuery)
fmt.Println(m)
@@ -190,6 +200,7 @@ pieces that we extracted.
|
+
$ go run url-parsing.go
postgres
user:pass
diff --git a/public/values b/public/values
index d332548..aeeee0f 100644
--- a/public/values
+++ b/public/values
@@ -20,7 +20,6 @@
-
@@ -32,6 +31,7 @@ basic examples.
+
|
@@ -41,6 +41,7 @@ basic examples.
+
@@ -52,6 +53,7 @@ basic examples.
|
+
@@ -63,6 +65,7 @@ basic examples.
|
+
@@ -75,6 +78,7 @@ basic examples.
|
+
fmt.Println("go" + "lang")
@@ -87,6 +91,7 @@ basic examples.
|
+
fmt.Println("1+1 =", 1+1)
fmt.Println("7.0/3.0 =", 7.0/3.0)
@@ -100,6 +105,7 @@ basic examples.
|
+
fmt.Println(true && false)
fmt.Println(true || false)
fmt.Println(!true)
@@ -118,6 +124,7 @@ basic examples.
|
+
$ go run values.go
golang
1+1 = 2
diff --git a/public/variables b/public/variables
index abd7a7f..7422d14 100644
--- a/public/variables
+++ b/public/variables
@@ -20,7 +20,6 @@
-
@@ -32,6 +31,7 @@ calls.
+
|
@@ -41,6 +41,7 @@ calls.
+
@@ -52,6 +53,7 @@ calls.
|
+
@@ -63,6 +65,7 @@ calls.
|
+
@@ -75,6 +78,7 @@ calls.
|
+
var a string = "initial"
fmt.Println(a)
@@ -88,6 +92,7 @@ calls.
|
+
var b, c int = 1, 2
fmt.Println(b, c)
@@ -101,6 +106,7 @@ calls.
|
+
var d = true
fmt.Println(d)
@@ -116,6 +122,7 @@ zero value for an int is 0 .
|
+
@@ -131,6 +138,7 @@ initializing a variable, e.g. for
|
+
f := "short"
fmt.Println(f)
}
@@ -148,6 +156,7 @@ initializing a variable, e.g. for
|
+
$ go run variables.go
initial
1 2
diff --git a/public/variadic-functions b/public/variadic-functions
index 738256c..653c773 100644
--- a/public/variadic-functions
+++ b/public/variadic-functions
@@ -20,7 +20,6 @@
-
@@ -33,6 +32,7 @@ function.
+
|
@@ -42,6 +42,7 @@ function.
+
@@ -53,6 +54,7 @@ function.
|
+
@@ -66,6 +68,7 @@ of ints as arguments.
|
+
func sum(nums ...int) {
fmt.Print(nums, " ")
total := 0
@@ -84,6 +87,7 @@ of ints as arguments.
|
+
@@ -97,6 +101,7 @@ with individual arguments.
|
+
@@ -112,6 +117,7 @@ apply them to a variadic function using
|
+
nums := []int{1, 2, 3, 4}
sum(nums...)
}
@@ -129,6 +135,7 @@ apply them to a variadic function using
|
+
$ go run variadic-functions.go
[1 2] 3
[1 2 3] 6
@@ -145,6 +152,7 @@ to form closures, which we’ll look at next.
|
+
|
diff --git a/public/worker-pools b/public/worker-pools
index 5a9fe7e..1471e84 100644
--- a/public/worker-pools
+++ b/public/worker-pools
@@ -20,7 +20,6 @@
-
@@ -31,6 +30,7 @@ a worker pool using goroutines and channels.
+
|
@@ -40,6 +40,7 @@ a worker pool using goroutines and channels.
+
@@ -51,6 +52,7 @@ a worker pool using goroutines and channels.
|
+
import "fmt"
import "time"
@@ -68,6 +70,7 @@ simulate an expensive task.
|
+
func worker(id int, jobs <-chan int, results chan<- int) {
for j := range jobs {
fmt.Println("worker", id, "processing job", j)
@@ -85,6 +88,7 @@ simulate an expensive task.
|
+
@@ -99,6 +103,7 @@ channels for this.
|
+
jobs := make(chan int, 100)
results := make(chan int, 100)
@@ -113,6 +118,7 @@ because there are no jobs yet.
|
+
for w := 1; w <= 3; w++ {
go worker(w, jobs, results)
}
@@ -128,6 +134,7 @@ channel to indicate that’s all the work we have.
|
+
for j := 1; j <= 9; j++ {
jobs <- j
}
@@ -143,6 +150,7 @@ channel to indicate that’s all the work we have.
|
+
for a := 1; a <= 9; a++ {
<-results
}
@@ -165,6 +173,7 @@ there are 3 workers operating concurrently.
|
+
$ time go run worker-pools.go
worker 1 processing job 1
worker 2 processing job 2
@@ -185,6 +194,7 @@ there are 3 workers operating concurrently.
|
+
diff --git a/public/writing-files b/public/writing-files
index 7d4f2c1..dc9f576 100644
--- a/public/writing-files
+++ b/public/writing-files
@@ -20,7 +20,6 @@
-
@@ -31,6 +30,7 @@ ones we saw earlier for reading.
+
|
@@ -40,6 +40,7 @@ ones we saw earlier for reading.
+
@@ -51,6 +52,7 @@ ones we saw earlier for reading.
|
+
import (
"bufio"
"fmt"
@@ -67,6 +69,7 @@ ones we saw earlier for reading.
|
+
func check(e error) {
if e != nil {
panic(e)
@@ -82,6 +85,7 @@ ones we saw earlier for reading.
|
+
@@ -95,6 +99,7 @@ bytes) into a file.
|
+
d1 := []byte("hello\ngo\n")
err := ioutil.WriteFile("/tmp/dat1", d1, 0644)
check(err)
@@ -109,6 +114,7 @@ bytes) into a file.
|
+
f, err := os.Create("/tmp/dat2")
check(err)
@@ -123,6 +129,7 @@ after opening a file.
|
+
@@ -135,6 +142,7 @@ after opening a file.
|
+
d2 := []byte{115, 111, 109, 101, 10}
n2, err := f.Write(d2)
check(err)
@@ -150,6 +158,7 @@ after opening a file.
|
+
n3, err := f.WriteString("writes\n")
fmt.Printf("wrote %d bytes\n", n3)
@@ -163,6 +172,7 @@ after opening a file.
|
+
@@ -176,6 +186,7 @@ to the buffered readers we saw earlier.
|
+
w := bufio.NewWriter(f)
n4, err := w.WriteString("buffered\n")
fmt.Printf("wrote %d bytes\n", n4)
@@ -191,6 +202,7 @@ been applied to the underlying writer.
|
+
@@ -202,6 +214,7 @@ been applied to the underlying writer.
|
+
@@ -218,6 +231,7 @@ been applied to the underlying writer.
|
+
$ go run writing-files.go
wrote 5 bytes
wrote 7 bytes
@@ -233,6 +247,7 @@ been applied to the underlying writer.
|
+
$ cat /tmp/dat1
hello
go
@@ -252,6 +267,7 @@ we’ve just seen to the stdin and stdout streams.
|
+
|
diff --git a/templates/example.tmpl b/templates/example.tmpl
index bf048eb..db3dc96 100644
--- a/templates/example.tmpl
+++ b/templates/example.tmpl
@@ -20,7 +20,6 @@
- 
{{range .Segs}}
{{range .}}
@@ -29,6 +28,7 @@
{{.DocsRendered}}
+ {{if .CodeRun}} {{end}}
{{.CodeRendered}}
|
diff --git a/tools/generate.go b/tools/generate.go
index 4f1cc13..30d7291 100644
--- a/tools/generate.go
+++ b/tools/generate.go
@@ -118,9 +118,9 @@ var todoPat = regexp.MustCompile("\\/\\/ todo: ")
var dashPat = regexp.MustCompile("\\-+")
type Seg struct {
- Docs, DocsRendered string
- Code, CodeRendered string
- CodeEmpty, CodeLeading bool
+ Docs, DocsRendered string
+ Code, CodeRendered string
+ CodeEmpty, CodeLeading, CodeRun bool
}
type Example struct {
@@ -193,6 +193,7 @@ func parseSegs(sourcePath string) ([]*Seg, string) {
for i, seg := range segs {
seg.CodeEmpty = (seg.Code == "")
seg.CodeLeading = (i < (len(segs) - 1))
+ seg.CodeRun = strings.Contains(seg.Code, "package main")
}
return segs, filecontent
}
| | | | | | | | | | | | | | | | | | | | | | | | | | | | |