From dc33273d8a9b881a38870d59cc9a576a1e65d68f Mon Sep 17 00:00:00 2001 From: julien Date: Tue, 3 Jan 2017 17:50:49 +0100 Subject: [PATCH 01/54] added clipboard functionality with your comments --- templates/clipboard.png | Bin 0 -> 488 bytes templates/example.tmpl | 7 ++++++- templates/site.css | 5 ++++- templates/site.js | 17 +++++++++++++++++ tools/generate.go | 8 +++++++- 5 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 templates/clipboard.png create mode 100644 templates/site.js diff --git a/templates/clipboard.png b/templates/clipboard.png new file mode 100644 index 0000000000000000000000000000000000000000..0e262fec70a6efb70c8c03c67e4cfea0b230d5ab GIT binary patch literal 488 zcmVP)vs0+u6@oUjF!il?f%*EGIz@kHuY0Jz-x!^TP`0I+j#4M3yOun`C$0GLY;0}N!> z@?HR!^uMdY?T0(;4FS(8K`+4e{$(p$r=i9GO#pFzR`vm!Q+6ka*jT(SNo?u|Lt!d6 zSGM3_C`@*F72plf0fhAVfD0h{U)v;(fF70L6Q}@Ds{#v|#T@yq_0~Ezo&p%OgcqtH ze?6R7A=SQhZwYS^XuznG2EkC6sp+&;0f49d3Xi}@mm2i7x*%siPzKUY8ptjfQgpvc zU|4PGLW39J38<u`lTp#J+Cizm8Ecyw8bkh1}(e_fNd33!{0 eZzG - {{if .CodeRun}}{{end}} + {{if .CodeRun}}{{end}} {{.CodeRendered}} @@ -44,5 +44,10 @@ by @mmcgrana | feedback | source | license

+ + diff --git a/templates/site.css b/templates/site.css index 4808e32..06d0111 100644 --- a/templates/site.css +++ b/templates/site.css @@ -136,11 +136,14 @@ pre, code { font-size: 14px; line-height: 18px; font-family: 'Menlo', 'Monaco', 'Consolas', 'Lucida Console', monospace; } -img.run { +img.copy, img.run { height: 16px; width: 16px; float: right } +img.copy { + cursor: pointer; +} /* Syntax highlighting */ body .hll { background-color: #ffffcc } diff --git a/templates/site.js b/templates/site.js new file mode 100644 index 0000000..752e656 --- /dev/null +++ b/templates/site.js @@ -0,0 +1,17 @@ +/*! + * clipboard.js v1.5.13 + * https://zenorocha.github.io/clipboard.js + * + * Licensed MIT © Zeno Rocha + */ +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Clipboard=t()}}(function(){var t,e,n;return function t(e,n,o){function r(c,a){if(!n[c]){if(!e[c]){var l="function"==typeof require&&require;if(!a&&l)return l(c,!0);if(i)return i(c,!0);var s=new Error("Cannot find module '"+c+"'");throw s.code="MODULE_NOT_FOUND",s}var u=n[c]={exports:{}};e[c][0].call(u.exports,function(t){var n=e[c][1][t];return r(n?n:t)},u,u.exports,t,e,n,o)}return n[c].exports}for(var i="function"==typeof require&&require,c=0;c Date: Wed, 17 Oct 2018 13:52:04 -0700 Subject: [PATCH 02/54] Update tickers.go to not leak goroutine The code in the example will leak a goroutine because ticker.Stop() does not close ticker.C. There is no way to close ticker.C, so `for _ := range ticker` is not a generally safe example for using a ticker. --- examples/tickers/tickers.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/examples/tickers/tickers.go b/examples/tickers/tickers.go index ef55c97..3547648 100644 --- a/examples/tickers/tickers.go +++ b/examples/tickers/tickers.go @@ -16,9 +16,16 @@ func main() { // `range` builtin on the channel to iterate over // the values as they arrive every 500ms. ticker := time.NewTicker(500 * time.Millisecond) + done := make(chan bool) + go func() { - for t := range ticker.C { - fmt.Println("Tick at", t) + for { + select { + case <-done: + return + case t := <-ticker.C: + fmt.Println("Tick at", t) + } } }() @@ -27,5 +34,6 @@ func main() { // channel. We'll stop ours after 1600ms. time.Sleep(1600 * time.Millisecond) ticker.Stop() + done <- true fmt.Println("Ticker stopped") } From f1a6a94afd32ed3364eef57ce8dcd460987c2765 Mon Sep 17 00:00:00 2001 From: Bailey Wickham Date: Wed, 28 Nov 2018 18:04:20 -0800 Subject: [PATCH 03/54] Added warning for capital field names in structs Names without capital letters will be ignored by the JSON Marshaller. This may cause confusion when fields are not being unmarshalled correctly without a warning why. --- examples/json/json.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/json/json.go b/examples/json/json.go index 6a1f56d..101a1cb 100644 --- a/examples/json/json.go +++ b/examples/json/json.go @@ -14,6 +14,8 @@ type response1 struct { Page int Fruits []string } +// Fields must have capital letters to be exposed to other +// programs such as the JSON Marshaller. type response2 struct { Page int `json:"page"` Fruits []string `json:"fruits"` From 2e3c6d3f51a99e1717807c7ae7fe1c4353c8b3bf Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Tue, 4 Jun 2019 20:32:43 -0700 Subject: [PATCH 04/54] Initial Travis file for running CI Each run invokes tools/build, which already returns a non-zero status on errors and zero when OK. Updates #237 --- .travis.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..415b238 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,14 @@ +language: go + +go: + - 1.12 + +before_install: + - sudo apt-get update + - sudo apt-get install python + +install: + - go get -u github.com/russross/blackfriday + +script: + - 'tools/build' From c22108bc89ae5aa0641149a9d306624275a9b4c9 Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Wed, 5 Jun 2019 06:37:51 -0700 Subject: [PATCH 05/54] Comment --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 415b238..1864bc5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,7 @@ go: - 1.12 before_install: + # We need Python to run pygmentize for generating HTML. - sudo apt-get update - sudo apt-get install python From 82699a6deb0297d913663c701797e7a50470c144 Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Wed, 5 Jun 2019 09:57:37 -0700 Subject: [PATCH 06/54] Add Travis link to README --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f9454ea..b68ba5a 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,10 @@ -## Go by Example +# Go by Example + +[![Build Status](https://travis-ci.com/mmcgrana/gobyexample.svg?branch=master)][travis] Content and build toolchain for [Go by Example](https://gobyexample.com), a site that teaches Go via annotated example programs. - ### Overview The Go by Example site is built by extracting code and From 5487e88919f1495857367b478726ddfca283d319 Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Wed, 5 Jun 2019 10:15:13 -0700 Subject: [PATCH 07/54] Add VERBOSE option to tools/build and generate.go VERBOSE will be set by TRAVIS (but can also be set by user to diagnose slow builds). Using an env var so that it automatically propagates to all the sub-scripts and tools without having to pass it through tools/build explicitly. --- .travis.yml | 5 ++++- tools/build | 9 +++++++++ tools/generate.go | 13 ++++++++++++- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1864bc5..54d1654 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,4 +12,7 @@ install: - go get -u github.com/russross/blackfriday script: - - 'tools/build' + - tools/build + +env: + - VERBOSE=1 diff --git a/tools/build b/tools/build index 3c07db8..b3205bb 100755 --- a/tools/build +++ b/tools/build @@ -2,7 +2,16 @@ set -e +verbose() [[ -v VERBOSE ]] + +verbose && echo "Running tests..." tools/test + +verbose && echo "Formatting code..." tools/format + +verbose && echo "Measuring line lengths..." tools/measure + +verbose && echo "Generating HTML..." tools/generate diff --git a/tools/generate.go b/tools/generate.go index 32f542c..c840169 100644 --- a/tools/generate.go +++ b/tools/generate.go @@ -19,6 +19,10 @@ var cacheDir = "/tmp/gobyexample-cache" var siteDir = "./public" var pygmentizeBin = "./vendor/pygments/pygmentize" +func verbose() bool { + return len(os.Getenv("VERBOSE")) > 0 +} + func check(err error) { if err != nil { panic(err) @@ -221,6 +225,7 @@ func parseAndRenderSegs(sourcePath string) ([]*Seg, string) { } func parseExamples() []*Example { + fmt.Println("Parsing examples") exampleNames := readLines("examples.txt") examples := make([]*Example, 0) for _, exampleName := range exampleNames { @@ -261,6 +266,9 @@ func parseExamples() []*Example { } func renderIndex(examples []*Example) { + if verbose() { + fmt.Println("Rendering index") + } indexTmpl := template.New("index") _, err := indexTmpl.Parse(mustReadFile("templates/index.tmpl")) check(err) @@ -274,7 +282,10 @@ func renderExamples(examples []*Example) { exampleTmpl := template.New("example") _, err := exampleTmpl.Parse(mustReadFile("templates/example.tmpl")) check(err) - for _, example := range examples { + for i, example := range examples { + if verbose() { + fmt.Printf("Rendering %s [%d/%d]\n", example.Name, i, len(examples)) + } exampleF, err := os.Create(siteDir + "/" + example.ID) check(err) exampleTmpl.Execute(exampleF, example) From 3d0bde4f8f5000cbde5cf5262830e4d48401cb30 Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Wed, 5 Jun 2019 10:17:09 -0700 Subject: [PATCH 08/54] Add verbose guard in parseExamples --- tools/generate.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/generate.go b/tools/generate.go index c840169..1b79de8 100644 --- a/tools/generate.go +++ b/tools/generate.go @@ -225,7 +225,9 @@ func parseAndRenderSegs(sourcePath string) ([]*Seg, string) { } func parseExamples() []*Example { - fmt.Println("Parsing examples") + if verbose() { + fmt.Println("Parsing examples") + } exampleNames := readLines("examples.txt") examples := make([]*Example, 0) for _, exampleName := range exampleNames { From 2438aea95f80443de1ba823b9986c316bcfd820b Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Wed, 5 Jun 2019 10:25:14 -0700 Subject: [PATCH 09/54] Move the travis link / build status around --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index b68ba5a..42844e5 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,5 @@ # Go by Example -[![Build Status](https://travis-ci.com/mmcgrana/gobyexample.svg?branch=master)][travis] - Content and build toolchain for [Go by Example](https://gobyexample.com), a site that teaches Go via annotated example programs. @@ -18,9 +16,10 @@ The built `public` directory can be served by any static content system. The production site uses S3 and CloudFront, for example. - ### Building +[![Build Status](https://travis-ci.com/mmcgrana/gobyexample.svg?branch=master)][travis] + To build the site you'll need Go and Python installed. Run: ```console From 09dec4f4fc3ca6923d1576db0854bb96666afeb6 Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Wed, 5 Jun 2019 10:27:39 -0700 Subject: [PATCH 10/54] Reformat the travis link to render properly --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 42844e5..21686c4 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ CloudFront, for example. ### Building -[![Build Status](https://travis-ci.com/mmcgrana/gobyexample.svg?branch=master)][travis] +[![Build Status](https://travis-ci.com/mmcgrana/gobyexample.svg "Travis CI status")](https://travis-ci.com/mmcgrana/gobyexample) To build the site you'll need Go and Python installed. Run: From d34c7ac64e39abfde318e77d97df59e073e514ad Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Thu, 6 Jun 2019 05:26:20 -0700 Subject: [PATCH 11/54] Rewrite verbose() to work in OSX bash --- tools/build | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/build b/tools/build index b3205bb..f06beae 100755 --- a/tools/build +++ b/tools/build @@ -2,7 +2,9 @@ set -e -verbose() [[ -v VERBOSE ]] +verbose() { + ! test -z "$VERBOSE" +} verbose && echo "Running tests..." tools/test From 52be303a71d232a90a35e7391964dde28e2972fe Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Thu, 6 Jun 2019 06:17:45 -0700 Subject: [PATCH 12/54] File Paths example --- examples.txt | 1 + examples/file-paths/file-paths.go | 62 ++++++++ examples/file-paths/file-paths.hash | 2 + examples/file-paths/file-paths.sh | 12 ++ public/file-paths | 238 ++++++++++++++++++++++++++++ public/index.html | 2 + public/line-filters | 2 +- 7 files changed, 318 insertions(+), 1 deletion(-) create mode 100644 examples/file-paths/file-paths.go create mode 100644 examples/file-paths/file-paths.hash create mode 100644 examples/file-paths/file-paths.sh create mode 100644 public/file-paths diff --git a/examples.txt b/examples.txt index d4859d3..91a1fde 100644 --- a/examples.txt +++ b/examples.txt @@ -57,6 +57,7 @@ Base64 Encoding Reading Files Writing Files Line Filters +File Paths Command-Line Arguments Command-Line Flags Command-Line Subcommands diff --git a/examples/file-paths/file-paths.go b/examples/file-paths/file-paths.go new file mode 100644 index 0000000..75b017d --- /dev/null +++ b/examples/file-paths/file-paths.go @@ -0,0 +1,62 @@ +// The `filepath` package provides functions to parse +// and construct *file paths* in a way that is portable +// between operating systems; `dir/file` on Linux vs. +// `dir\file` on Windows, for example. +package main + +import ( + "fmt" + "path/filepath" + "strings" +) + +func main() { + + // `Join` should be used to construct paths in a + // portable way. It takes any number of arguments + // and constructs a hierarchical path from them. + p := filepath.Join("dir1", "dir2", "filename") + fmt.Println("p:", p) + + // You should always use `Join` instead of + // concatenating `/`s or `\`s manually. In addition + // to providing portability, `Join` will also + // normalize paths by removing superfluous separators + // and directory changes. + fmt.Println(filepath.Join("dir1//", "filename")) + fmt.Println(filepath.Join("dir1/../dir1", "filename")) + + // `Dir` and `Base` can be used to split a path to the + // directory and the file. Alternatively, `Split` will + // return both in the same call. + fmt.Println("Dir(p):", filepath.Dir(p)) + fmt.Println("Base(p):", filepath.Base(p)) + + // To check whether a path is absolute, use `IsAbs`. + fmt.Println(filepath.IsAbs("dir/file")) + fmt.Println(filepath.IsAbs("/dir/file")) + + filename := "config.json" + + // To find a file's extension, use `Ext`. + ext := filepath.Ext(filename) + fmt.Println(ext) + + // To find the file's name with the extension removed, + // use `TrimSuffix`. + fmt.Println(strings.TrimSuffix(filename, ext)) + + // `Rel` finds a relative path between a *base* and a + // *target*. + rel, err := filepath.Rel("a/b", "a/b/t/file") + if err != nil { + panic(err) + } + fmt.Println(rel) + + rel, err = filepath.Rel("a/b", "a/c/t/file") + if err != nil { + panic(err) + } + fmt.Println(rel) +} diff --git a/examples/file-paths/file-paths.hash b/examples/file-paths/file-paths.hash new file mode 100644 index 0000000..7cc06ab --- /dev/null +++ b/examples/file-paths/file-paths.hash @@ -0,0 +1,2 @@ +4611ff69626490eb50673a739707d870fac79142 +eUhAltl7_sI diff --git a/examples/file-paths/file-paths.sh b/examples/file-paths/file-paths.sh new file mode 100644 index 0000000..4ef4251 --- /dev/null +++ b/examples/file-paths/file-paths.sh @@ -0,0 +1,12 @@ +$ go run file-paths.go +p: dir1/dir2/filename +dir1/filename +dir1/filename +Dir(p): dir1/dir2 +Base(p): filename +false +true +.json +config +t/file +../c/t/file diff --git a/public/file-paths b/public/file-paths new file mode 100644 index 0000000..9085662 --- /dev/null +++ b/public/file-paths @@ -0,0 +1,238 @@ + + + + + Go by Example: File Paths + + + +
+

Go by Example: File Paths

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

The filepath package provides functions to parse +and construct file paths in a way that is portable +between operating systems; dir/file on Linux vs. +dir\file on Windows, for example.

+ +
+ + + +
package main
+
+ +
+ + + +
import (
+    "fmt"
+    "path/filepath"
+    "strings"
+)
+
+ +
+ + + +
func main() {
+
+ +
+

Join should be used to construct paths in a +portable way. It takes any number of arguments +and constructs a hierarchical path from them.

+ +
+ +
    p := filepath.Join("dir1", "dir2", "filename")
+    fmt.Println("p:", p)
+
+ +
+

You should always use Join instead of +concatenating /s or \s manually. In addition +to providing portability, Join will also +normalize paths by removing superfluous separators +and directory changes.

+ +
+ +
    fmt.Println(filepath.Join("dir1//", "filename"))
+    fmt.Println(filepath.Join("dir1/../dir1", "filename"))
+
+ +
+

Dir and Base can be used to split a path to the +directory and the file. Alternatively, Split will +return both in the same call.

+ +
+ +
    fmt.Println("Dir(p):", filepath.Dir(p))
+    fmt.Println("Base(p):", filepath.Base(p))
+
+ +
+

To check whether a path is absolute, use IsAbs.

+ +
+ +
    fmt.Println(filepath.IsAbs("dir/file"))
+    fmt.Println(filepath.IsAbs("/dir/file"))
+
+ +
+ + + +
    filename := "config.json"
+
+ +
+

To find a file’s extension, use Ext.

+ +
+ +
    ext := filepath.Ext(filename)
+    fmt.Println(ext)
+
+ +
+

To find the file’s name with the extension removed, +use TrimSuffix.

+ +
+ +
    fmt.Println(strings.TrimSuffix(filename, ext))
+
+ +
+

Rel finds a relative path between a base and a +target.

+ +
+ +
    rel, err := filepath.Rel("a/b", "a/b/t/file")
+    if err != nil {
+        panic(err)
+    }
+    fmt.Println(rel)
+
+ +
+ + + +
    rel, err = filepath.Rel("a/b", "a/c/t/file")
+    if err != nil {
+        panic(err)
+    }
+    fmt.Println(rel)
+}
+
+ +
+ + + + + + + + +
+ + + +
$ go run file-paths.go
+p: dir1/dir2/filename
+dir1/filename
+dir1/filename
+Dir(p): dir1/dir2
+Base(p): filename
+false
+true
+.json
+config
+t/file
+../c/t/file
+
+ +
+ + +

+ Next example: Command-Line Arguments. +

+ + +
+ + diff --git a/public/index.html b/public/index.html index e3960aa..ef6fe69 100644 --- a/public/index.html +++ b/public/index.html @@ -141,6 +141,8 @@
  • Line Filters
  • +
  • File Paths
  • +
  • Command-Line Arguments
  • Command-Line Flags
  • diff --git a/public/line-filters b/public/line-filters index d1dd866..d264214 100644 --- a/public/line-filters +++ b/public/line-filters @@ -183,7 +183,7 @@ lowercase lines.

    - Next example: Command-Line Arguments. + Next example: File Paths.

    package main
    @@ -109,7 +109,7 @@ return both in the same call.

    -

    To check whether a path is absolute, use IsAbs.

    +

    We can check whether a path is absolute.

    @@ -135,7 +135,8 @@ return both in the same call.

    -

    To find a file’s extension, use Ext.

    +

    Some file names have extensions following a dot. We +can split the extension out of such names with Ext.

    @@ -150,7 +151,7 @@ return both in the same call.

    To find the file’s name with the extension removed, -use TrimSuffix.

    +use strings.TrimSuffix.

    @@ -164,7 +165,8 @@ use TrimSuffix.

    Rel finds a relative path between a base and a -target.

    +target. It returns an error if the target cannot +be made relative to base.

    From cdbdae9715bf1ff501e4f22f7e066d5729ec1fb3 Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Fri, 7 Jun 2019 06:12:30 -0700 Subject: [PATCH 14/54] Do progress reporting during parsing/processing stage, not HTML render stage --- tools/generate.go | 75 ++++++++++++++++++++++++----------------------- 1 file changed, 39 insertions(+), 36 deletions(-) diff --git a/tools/generate.go b/tools/generate.go index 1b79de8..24a5a26 100644 --- a/tools/generate.go +++ b/tools/generate.go @@ -225,40 +225,43 @@ func parseAndRenderSegs(sourcePath string) ([]*Seg, string) { } func parseExamples() []*Example { - if verbose() { - fmt.Println("Parsing examples") - } - exampleNames := readLines("examples.txt") - examples := make([]*Example, 0) - for _, exampleName := range exampleNames { - if (exampleName != "") && !strings.HasPrefix(exampleName, "#") { - example := Example{Name: exampleName} - exampleID := strings.ToLower(exampleName) - exampleID = strings.Replace(exampleID, " ", "-", -1) - exampleID = strings.Replace(exampleID, "/", "-", -1) - exampleID = strings.Replace(exampleID, "'", "", -1) - exampleID = dashPat.ReplaceAllString(exampleID, "-") - example.ID = exampleID - example.Segs = make([][]*Seg, 0) - sourcePaths := mustGlob("examples/" + exampleID + "/*") - for _, sourcePath := range sourcePaths { - if strings.HasSuffix(sourcePath, ".hash") { - example.GoCodeHash, example.URLHash = parseHashFile(sourcePath) - } else { - sourceSegs, filecontents := parseAndRenderSegs(sourcePath) - if filecontents != "" { - example.GoCode = filecontents - } - example.Segs = append(example.Segs, sourceSegs) - } - } - newCodeHash := sha1Sum(example.GoCode) - if example.GoCodeHash != newCodeHash { - example.URLHash = resetURLHashFile(newCodeHash, example.GoCode, "examples/"+example.ID+"/"+example.ID+".hash") - } - examples = append(examples, &example) + var exampleNames []string + for _, line := range readLines("examples.txt") { + if line != "" && !strings.HasPrefix(line, "#") { + exampleNames = append(exampleNames, line) } } + examples := make([]*Example, 0) + for i, exampleName := range exampleNames { + if verbose() { + fmt.Printf("Processing %s [%d/%d]\n", exampleName, i+1, len(exampleNames)) + } + example := Example{Name: exampleName} + exampleID := strings.ToLower(exampleName) + exampleID = strings.Replace(exampleID, " ", "-", -1) + exampleID = strings.Replace(exampleID, "/", "-", -1) + exampleID = strings.Replace(exampleID, "'", "", -1) + exampleID = dashPat.ReplaceAllString(exampleID, "-") + example.ID = exampleID + example.Segs = make([][]*Seg, 0) + sourcePaths := mustGlob("examples/" + exampleID + "/*") + for _, sourcePath := range sourcePaths { + if strings.HasSuffix(sourcePath, ".hash") { + example.GoCodeHash, example.URLHash = parseHashFile(sourcePath) + } else { + sourceSegs, filecontents := parseAndRenderSegs(sourcePath) + if filecontents != "" { + example.GoCode = filecontents + } + example.Segs = append(example.Segs, sourceSegs) + } + } + newCodeHash := sha1Sum(example.GoCode) + if example.GoCodeHash != newCodeHash { + example.URLHash = resetURLHashFile(newCodeHash, example.GoCode, "examples/"+example.ID+"/"+example.ID+".hash") + } + examples = append(examples, &example) + } for i, example := range examples { if i < (len(examples) - 1) { example.NextExample = examples[i+1] @@ -281,13 +284,13 @@ func renderIndex(examples []*Example) { } func renderExamples(examples []*Example) { + if verbose() { + fmt.Println("Generating HTML") + } exampleTmpl := template.New("example") _, err := exampleTmpl.Parse(mustReadFile("templates/example.tmpl")) check(err) - for i, example := range examples { - if verbose() { - fmt.Printf("Rendering %s [%d/%d]\n", example.Name, i, len(examples)) - } + for _, example := range examples { exampleF, err := os.Create(siteDir + "/" + example.ID) check(err) exampleTmpl.Execute(exampleF, example) From cb0f0a305624f6dd0b50b374ebb5d0a5f21a5e1d Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Fri, 7 Jun 2019 06:17:26 -0700 Subject: [PATCH 15/54] Tweak logged text --- tools/generate.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/generate.go b/tools/generate.go index 24a5a26..4872b3b 100644 --- a/tools/generate.go +++ b/tools/generate.go @@ -285,7 +285,7 @@ func renderIndex(examples []*Example) { func renderExamples(examples []*Example) { if verbose() { - fmt.Println("Generating HTML") + fmt.Println("Rendering templates") } exampleTmpl := template.New("example") _, err := exampleTmpl.Parse(mustReadFile("templates/example.tmpl")) From 70cb6ffb45bd8a39365b4da3ae4a23488a0a1038 Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Fri, 7 Jun 2019 06:26:27 -0700 Subject: [PATCH 16/54] Add printout when sending a request to play.golang.org --- tools/generate.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/generate.go b/tools/generate.go index 4872b3b..51b4a04 100644 --- a/tools/generate.go +++ b/tools/generate.go @@ -143,6 +143,9 @@ func parseHashFile(sourcePath string) (string, string) { } func resetURLHashFile(codehash, code, sourcePath string) string { + if verbose() { + fmt.Println(" Sending request to play.golang.org") + } payload := strings.NewReader(code) resp, err := http.Post("https://play.golang.org/share", "text/plain", payload) if err != nil { From 447d77234f9d90ed8cf9b938f38dddc5fa021641 Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Sat, 8 Jun 2019 06:11:13 -0700 Subject: [PATCH 17/54] Add directories example --- examples.txt | 1 + examples/directories/directories.go | 77 +++++++ examples/directories/directories.hash | 2 + examples/directories/directories.sh | 7 + public/directories | 297 ++++++++++++++++++++++++++ public/file-paths | 2 +- public/index.html | 2 + 7 files changed, 387 insertions(+), 1 deletion(-) create mode 100644 examples/directories/directories.go create mode 100644 examples/directories/directories.hash create mode 100644 examples/directories/directories.sh create mode 100644 public/directories diff --git a/examples.txt b/examples.txt index 91a1fde..887ef69 100644 --- a/examples.txt +++ b/examples.txt @@ -58,6 +58,7 @@ Reading Files Writing Files Line Filters File Paths +Directories Command-Line Arguments Command-Line Flags Command-Line Subcommands diff --git a/examples/directories/directories.go b/examples/directories/directories.go new file mode 100644 index 0000000..1d4eec9 --- /dev/null +++ b/examples/directories/directories.go @@ -0,0 +1,77 @@ +// Go has several useful functions for working with +// *directories* in the file system. + +package main + +import ( + "fmt" + "io/ioutil" + "os" +) + +func check(e error) { + if e != nil { + panic(e) + } +} + +func main() { + + // Create a new sub-directory in the current working + // directory. + err := os.Mkdir("subdir", 0755) + check(err) + + // When creating temporary directories, it's good + // practice to `defer` their removal. `os.RemoveAll` + // will delete a whole directory tree (similarly to + // `rm -rf`). + defer os.RemoveAll("subdir") + + // Helper function to create a new empty file. + createEmptyFile := func(name string) { + d := []byte("") + check(ioutil.WriteFile(name, d, 0644)) + } + + createEmptyFile("subdir/file1") + + // We can create a hierarchy of directories, including + // parents wiht `MkdirAll`. This is similar to the + // command-line `mkdir -p`. + err = os.MkdirAll("subdir/parent/child", 0755) + check(err) + + createEmptyFile("subdir/parent/file2") + createEmptyFile("subdir/parent/file3") + createEmptyFile("subdir/parent/child/file4") + + // `ReadDir` lists directory contents, returning a + // slice of `os.FileInfo` objects. + c, err := ioutil.ReadDir("subdir/parent") + check(err) + + fmt.Println("Listing subdir/parent") + for _, entry := range c { + fmt.Println(entry.Name(), entry.IsDir()) + } + + // `Chdir` lets us change the current working directory, + // similarly to `cd`. + err = os.Chdir("subdir/parent/child") + check(err) + + // Now we'll see the contents of "subdir/parent/child" + // when listing the *current* directory. + c, err = ioutil.ReadDir(".") + check(err) + + fmt.Println("Listing subdir/parent/child") + for _, entry := range c { + fmt.Println(entry.Name(), entry.IsDir()) + } + + // `cd` back to where we started. + err = os.Chdir("../../..") + check(err) +} diff --git a/examples/directories/directories.hash b/examples/directories/directories.hash new file mode 100644 index 0000000..b599edd --- /dev/null +++ b/examples/directories/directories.hash @@ -0,0 +1,2 @@ +7b2eed223a00c8a84df582bd254a642c7a57dd9b +UnjBL6NmR8- diff --git a/examples/directories/directories.sh b/examples/directories/directories.sh new file mode 100644 index 0000000..cc48f74 --- /dev/null +++ b/examples/directories/directories.sh @@ -0,0 +1,7 @@ +$ go run directories.go +Listing subdir/parent +child true +file2 false +file3 false +Listing subdir/parent/child +file4 false diff --git a/public/directories b/public/directories new file mode 100644 index 0000000..f80b48f --- /dev/null +++ b/public/directories @@ -0,0 +1,297 @@ + + + + + Go by Example: Directories + + + +
    +

    Go by Example: Directories

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    Go has several useful functions for working with +directories in the file system.

    + +
    + + +
    + + + + + +
    package main
    +
    + +
    + + + +
    import (
    +    "fmt"
    +    "io/ioutil"
    +    "os"
    +)
    +
    + +
    + + + +
    func check(e error) {
    +    if e != nil {
    +        panic(e)
    +    }
    +}
    +
    + +
    + + + +
    func main() {
    +
    + +
    +

    Create a new sub-directory in the current working +directory.

    + +
    + +
        err := os.Mkdir("subdir", 0755)
    +    check(err)
    +
    + +
    +

    When creating temporary directories, it’s good +practice to defer their removal. os.RemoveAll +will delete a whole directory tree (similarly to +rm -rf).

    + +
    + +
        defer os.RemoveAll("subdir")
    +
    + +
    +

    Helper function to create a new empty file.

    + +
    + +
        createEmptyFile := func(name string) {
    +        d := []byte("")
    +        check(ioutil.WriteFile(name, d, 0644))
    +    }
    +
    + +
    + + + +
        createEmptyFile("subdir/file1")
    +
    + +
    +

    We can create a hierarchy of directories, including +parents wiht MkdirAll. This is similar to the +command-line mkdir -p.

    + +
    + +
        err = os.MkdirAll("subdir/parent/child", 0755)
    +    check(err)
    +
    + +
    + + + +
        createEmptyFile("subdir/parent/file2")
    +    createEmptyFile("subdir/parent/file3")
    +    createEmptyFile("subdir/parent/child/file4")
    +
    + +
    +

    ReadDir lists directory contents, returning a +slice of os.FileInfo objects.

    + +
    + +
        c, err := ioutil.ReadDir("subdir/parent")
    +    check(err)
    +
    + +
    + + + +
        fmt.Println("Listing subdir/parent")
    +    for _, entry := range c {
    +        fmt.Println(entry.Name(), entry.IsDir())
    +    }
    +
    + +
    +

    Chdir lets us change the current working directory, +similarly to cd.

    + +
    + +
        err = os.Chdir("subdir/parent/child")
    +    check(err)
    +
    + +
    +

    Now we’ll see the contents of “subdir/parent/child” +when listing the current directory.

    + +
    + +
        c, err = ioutil.ReadDir(".")
    +    check(err)
    +
    + +
    + + + +
        fmt.Println("Listing subdir/parent/child")
    +    for _, entry := range c {
    +        fmt.Println(entry.Name(), entry.IsDir())
    +    }
    +
    + +
    +

    cd back to where we started.

    + +
    + +
        err = os.Chdir("../../..")
    +    check(err)
    +}
    +
    + +
    + + + + + + + + +
    + + + +
    $ go run directories.go
    +Listing subdir/parent
    +child true
    +file2 false
    +file3 false
    +Listing subdir/parent/child
    +file4 false
    +
    + +
    + + +

    + Next example: Command-Line Arguments. +

    + + +
    + + diff --git a/public/file-paths b/public/file-paths index 65e3886..f7b24a1 100644 --- a/public/file-paths +++ b/public/file-paths @@ -229,7 +229,7 @@ be made relative to base.

    - Next example: Command-Line Arguments. + Next example: Directories.

  • File Paths
  • +
  • Directories
  • +
  • Command-Line Arguments
  • Command-Line Flags
  • From bee52f22ce5faaef01bb4318220ad3b7dc787b65 Mon Sep 17 00:00:00 2001 From: Mark McGranaghan Date: Sat, 8 Jun 2019 11:21:40 -0400 Subject: [PATCH 18/54] Change word --- tools/generate.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/generate.go b/tools/generate.go index 51b4a04..97d8ab5 100644 --- a/tools/generate.go +++ b/tools/generate.go @@ -288,7 +288,7 @@ func renderIndex(examples []*Example) { func renderExamples(examples []*Example) { if verbose() { - fmt.Println("Rendering templates") + fmt.Println("Rendering examples") } exampleTmpl := template.New("example") _, err := exampleTmpl.Parse(mustReadFile("templates/example.tmpl")) From ee8c401ac383887e769f0348a4df6f5a11e38836 Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Sat, 8 Jun 2019 11:11:58 -0700 Subject: [PATCH 19/54] Update examples/directories/directories.go Co-Authored-By: Mark McGranaghan --- examples/directories/directories.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/directories/directories.go b/examples/directories/directories.go index 1d4eec9..0384354 100644 --- a/examples/directories/directories.go +++ b/examples/directories/directories.go @@ -37,7 +37,7 @@ func main() { createEmptyFile("subdir/file1") // We can create a hierarchy of directories, including - // parents wiht `MkdirAll`. This is similar to the + // parents with `MkdirAll`. This is similar to the // command-line `mkdir -p`. err = os.MkdirAll("subdir/parent/child", 0755) check(err) From 1be2c1c9100d53294505f42e9d8e468a4cbe7fce Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Sat, 8 Jun 2019 11:20:00 -0700 Subject: [PATCH 20/54] Add Walk --- examples/directories/directories.go | 22 ++++++++- examples/directories/directories.hash | 4 +- examples/directories/directories.sh | 16 +++++-- public/directories | 64 +++++++++++++++++++++++---- 4 files changed, 89 insertions(+), 17 deletions(-) diff --git a/examples/directories/directories.go b/examples/directories/directories.go index 0384354..8abdb51 100644 --- a/examples/directories/directories.go +++ b/examples/directories/directories.go @@ -7,6 +7,7 @@ import ( "fmt" "io/ioutil" "os" + "path/filepath" ) func check(e error) { @@ -53,7 +54,7 @@ func main() { fmt.Println("Listing subdir/parent") for _, entry := range c { - fmt.Println(entry.Name(), entry.IsDir()) + fmt.Println(" ", entry.Name(), entry.IsDir()) } // `Chdir` lets us change the current working directory, @@ -68,10 +69,27 @@ func main() { fmt.Println("Listing subdir/parent/child") for _, entry := range c { - fmt.Println(entry.Name(), entry.IsDir()) + fmt.Println(" ", entry.Name(), entry.IsDir()) } // `cd` back to where we started. err = os.Chdir("../../..") check(err) + + // We can also visit a directory *recursively*, + // including all its sub-directories. `Walk` accepts + // a callback function to handle every file or + // directory visited. + fmt.Println("Visiting subdir") + err = filepath.Walk("subdir", visit) +} + +// visit is called for every file or directory found +// recursively by `filepath.Walk`. +func visit(p string, info os.FileInfo, err error) error { + if err != nil { + return err + } + fmt.Println(" ", p, info.IsDir()) + return nil } diff --git a/examples/directories/directories.hash b/examples/directories/directories.hash index b599edd..75cb9fa 100644 --- a/examples/directories/directories.hash +++ b/examples/directories/directories.hash @@ -1,2 +1,2 @@ -7b2eed223a00c8a84df582bd254a642c7a57dd9b -UnjBL6NmR8- +57a8f629f040270c15a0375be4424b392edf3c95 +LI7ty_KDozd diff --git a/examples/directories/directories.sh b/examples/directories/directories.sh index cc48f74..31a8f0c 100644 --- a/examples/directories/directories.sh +++ b/examples/directories/directories.sh @@ -1,7 +1,15 @@ $ go run directories.go Listing subdir/parent -child true -file2 false -file3 false + child true + file2 false + file3 false Listing subdir/parent/child -file4 false + file4 false +Visiting subdir + subdir true + subdir/file1 false + subdir/parent true + subdir/parent/child true + subdir/parent/child/file4 false + subdir/parent/file2 false + subdir/parent/file3 false diff --git a/public/directories b/public/directories index f80b48f..a1bfce5 100644 --- a/public/directories +++ b/public/directories @@ -28,7 +28,7 @@ - +
    package main
    @@ -47,6 +47,7 @@
         "fmt"
         "io/ioutil"
         "os"
    +    "path/filepath"
     )
     
    @@ -143,7 +144,7 @@ will delete a whole directory tree (similarly to

    We can create a hierarchy of directories, including -parents wiht MkdirAll. This is similar to the +parents with MkdirAll. This is similar to the command-line mkdir -p.

    @@ -193,7 +194,7 @@ slice of os.FileInfo objects.

        fmt.Println("Listing subdir/parent")
         for _, entry := range c {
    -        fmt.Println(entry.Name(), entry.IsDir())
    +        fmt.Println(" ", entry.Name(), entry.IsDir())
         }
     
    @@ -238,7 +239,7 @@ when listing the current directory.

        fmt.Println("Listing subdir/parent/child")
         for _, entry := range c {
    -        fmt.Println(entry.Name(), entry.IsDir())
    +        fmt.Println(" ", entry.Name(), entry.IsDir())
         }
     
    @@ -250,10 +251,47 @@ when listing the current directory.

    cd back to where we started.

    - +
        err = os.Chdir("../../..")
         check(err)
    +
    + + + + + + +

    We can also visit a directory recursively, +including all its sub-directories. Walk accepts +a callback function to handle every file or +directory visited.

    + + + + +
        fmt.Println("Visiting subdir")
    +    err = filepath.Walk("subdir", visit)
    +}
    +
    + + + + + + +

    visit is called for every file or directory found +recursively by filepath.Walk.

    + + + + +
    func visit(p string, info os.FileInfo, err error) error {
    +    if err != nil {
    +        return err
    +    }
    +    fmt.Println(" ", p, info.IsDir())
    +    return nil
     }
     
    @@ -272,11 +310,19 @@ when listing the current directory.

    $ go run directories.go
     Listing subdir/parent
    -child true
    -file2 false
    -file3 false
    +  child true
    +  file2 false
    +  file3 false
     Listing subdir/parent/child
    -file4 false
    +  file4 false
    +Visiting subdir
    +  subdir true
    +  subdir/file1 false
    +  subdir/parent true
    +  subdir/parent/child true
    +  subdir/parent/child/file4 false
    +  subdir/parent/file2 false
    +  subdir/parent/file3 false
     
    From 39cc92ae7f31de3943567e340aab729214eb9fa5 Mon Sep 17 00:00:00 2001 From: Ross Eskridge Date: Wed, 12 Jun 2019 20:18:46 +0000 Subject: [PATCH 21/54] Fix forward reference in command line flags text Text in command line flags referenced environment variables, moved that to subcommands to read correctly. --- examples/command-line-flags/command-line-flags.sh | 3 --- examples/command-line-subcommands/command-line-subcommands.sh | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/command-line-flags/command-line-flags.sh b/examples/command-line-flags/command-line-flags.sh index d8fb754..246f4c7 100644 --- a/examples/command-line-flags/command-line-flags.sh +++ b/examples/command-line-flags/command-line-flags.sh @@ -54,6 +54,3 @@ $ ./command-line-flags -wat flag provided but not defined: -wat Usage of ./command-line-flags: ... - -# Next we'll look at environment variables, another common -# way to parameterize programs. diff --git a/examples/command-line-subcommands/command-line-subcommands.sh b/examples/command-line-subcommands/command-line-subcommands.sh index c5948e8..32531ed 100644 --- a/examples/command-line-subcommands/command-line-subcommands.sh +++ b/examples/command-line-subcommands/command-line-subcommands.sh @@ -19,3 +19,6 @@ flag provided but not defined: -enable Usage of bar: -level int level + +# Next we'll look at environment variables, another common +# way to parameterize programs. From d18911d3e835b25b0d3dd3b5bc91f6b4f93f618f Mon Sep 17 00:00:00 2001 From: Ross Eskridge Date: Thu, 13 Jun 2019 13:59:54 +0000 Subject: [PATCH 22/54] Generate html with textual reference fix --- public/command-line-flags | 14 +------------- public/command-line-subcommands | 14 +++++++++++++- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/public/command-line-flags b/public/command-line-flags index 42dad0b..43ec18f 100644 --- a/public/command-line-flags +++ b/public/command-line-flags @@ -272,7 +272,7 @@ generated help text for the command-line program.

    and show the help text again.

    - +
    $ ./command-line-flags -wat
     flag provided but not defined: -wat
    @@ -283,18 +283,6 @@ and show the help text again.

    - - -

    Next we’ll look at environment variables, another common -way to parameterize programs.

    - - - - - - - - diff --git a/public/command-line-subcommands b/public/command-line-subcommands index 945f646..39b385b 100644 --- a/public/command-line-subcommands +++ b/public/command-line-subcommands @@ -214,7 +214,7 @@ have access to trailing positional arguments.

    But bar won’t accept foo’s flags.

    - +
    $ ./command-line-subcommands bar -enable a1
     flag provided but not defined: -enable
    @@ -226,6 +226,18 @@ have access to trailing positional arguments.

    + + +

    Next we’ll look at environment variables, another common +way to parameterize programs.

    + + + + + + + + From 3b153c7d805c3ed5374923480f42b7561af655b2 Mon Sep 17 00:00:00 2001 From: Maciek Niemczyk Date: Mon, 17 Jun 2019 14:25:41 +0200 Subject: [PATCH 23/54] according to https://www.joeshaw.org/dont-defer-close-on-writable-files/ one should not use defer file.close(), its a bad pattern --- examples/defer/defer.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/defer/defer.go b/examples/defer/defer.go index 06c827f..8d1c3ed 100644 --- a/examples/defer/defer.go +++ b/examples/defer/defer.go @@ -40,5 +40,9 @@ func writeFile(f *os.File) { func closeFile(f *os.File) { fmt.Println("closing") - f.Close() + err := f.Close() + if err != nil { + _, _ = fmt.Fprintf(os.Stderr, "error: %v\n", err) + os.Exit(1) + } } From 862833fcb87968830c9a7cb533d198dbfbddb06d Mon Sep 17 00:00:00 2001 From: Maciek Niemczyk Date: Mon, 17 Jun 2019 14:46:02 +0200 Subject: [PATCH 24/54] CDR request --- examples/defer/defer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/defer/defer.go b/examples/defer/defer.go index 8d1c3ed..0eca985 100644 --- a/examples/defer/defer.go +++ b/examples/defer/defer.go @@ -42,7 +42,7 @@ func closeFile(f *os.File) { fmt.Println("closing") err := f.Close() if err != nil { - _, _ = fmt.Fprintf(os.Stderr, "error: %v\n", err) + fmt.Fprintf(os.Stderr, "error: %v\n", err) os.Exit(1) } } From b00cb1ec7eb532ddc1bf5a27fd1303fc78714b49 Mon Sep 17 00:00:00 2001 From: Maciek Niemczyk Date: Mon, 17 Jun 2019 14:47:46 +0200 Subject: [PATCH 25/54] CDR request 2 --- examples/defer/defer.go | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/defer/defer.go b/examples/defer/defer.go index 0eca985..0941d10 100644 --- a/examples/defer/defer.go +++ b/examples/defer/defer.go @@ -41,6 +41,7 @@ func writeFile(f *os.File) { func closeFile(f *os.File) { fmt.Println("closing") err := f.Close() + // It is important to check for errors when closing a file, even in a deferred function. if err != nil { fmt.Fprintf(os.Stderr, "error: %v\n", err) os.Exit(1) From 1aa6ac2a7a747405c1bc993ebbcca9cb47e20e26 Mon Sep 17 00:00:00 2001 From: Maciek Niemczyk Date: Mon, 17 Jun 2019 15:13:11 +0200 Subject: [PATCH 26/54] those files has been changed after running tools/build --- examples/defer/defer.hash | 4 ++-- public/defer | 24 ++++++++++++++++++++---- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/examples/defer/defer.hash b/examples/defer/defer.hash index 2994617..5e437d4 100644 --- a/examples/defer/defer.hash +++ b/examples/defer/defer.hash @@ -1,2 +1,2 @@ -570699fc50a1d39e9d0ad6a4461aef3248b080e1 -xPbQ5SGkH2O +4e2229c593e102d4efd101a7e9aa21f3345e90d1 +S2RuPTkABip diff --git a/public/defer b/public/defer index 43445ec..8f0b130 100644 --- a/public/defer +++ b/public/defer @@ -30,7 +30,7 @@ purposes of cleanup. defer is often used where e.g. - +
    package main
    @@ -132,15 +132,31 @@ of the enclosing function (main), after
               
             
             
    +        
    +          
    +            

    It is important to check for errors when closing a file, even in a deferred function.

    + + + + +
    func closeFile(f *os.File) {
    +    fmt.Println("closing")
    +    err := f.Close()
    +
    + + + + -
    func closeFile(f *os.File) {
    -    fmt.Println("closing")
    -    f.Close()
    +            
        if err != nil {
    +        fmt.Fprintf(os.Stderr, "error: %v\n", err)
    +        os.Exit(1)
    +    }
     }
     
    From 751eeda8b2117d0f7fd00c6444f25237694eab48 Mon Sep 17 00:00:00 2001 From: Mark McGranaghan Date: Sun, 30 Jun 2019 13:55:57 -0700 Subject: [PATCH 27/54] Code styling for symbol references --- examples/directories/directories.go | 4 ++-- examples/directories/directories.hash | 4 ++-- public/directories | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/directories/directories.go b/examples/directories/directories.go index 8abdb51..9b71274 100644 --- a/examples/directories/directories.go +++ b/examples/directories/directories.go @@ -62,7 +62,7 @@ func main() { err = os.Chdir("subdir/parent/child") check(err) - // Now we'll see the contents of "subdir/parent/child" + // Now we'll see the contents of `subdir/parent/child` // when listing the *current* directory. c, err = ioutil.ReadDir(".") check(err) @@ -84,7 +84,7 @@ func main() { err = filepath.Walk("subdir", visit) } -// visit is called for every file or directory found +// `visit` is called for every file or directory found // recursively by `filepath.Walk`. func visit(p string, info os.FileInfo, err error) error { if err != nil { diff --git a/examples/directories/directories.hash b/examples/directories/directories.hash index 75cb9fa..cebae56 100644 --- a/examples/directories/directories.hash +++ b/examples/directories/directories.hash @@ -1,2 +1,2 @@ -57a8f629f040270c15a0375be4424b392edf3c95 -LI7ty_KDozd +83f67db91816b4544072d0a4d099111a21c60723 +-7kWq0PmATF diff --git a/public/directories b/public/directories index a1bfce5..e0746ba 100644 --- a/public/directories +++ b/public/directories @@ -28,7 +28,7 @@ - +
    package main
    @@ -218,7 +218,7 @@ similarly to cd.

    -

    Now we’ll see the contents of “subdir/parent/child” +

    Now we’ll see the contents of subdir/parent/child when listing the current directory.

    @@ -280,7 +280,7 @@ directory visited.

    -

    visit is called for every file or directory found +

    visit is called for every file or directory found recursively by filepath.Walk.

    From 8219122e44d0dd7a40b082db37a0baed94246204 Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Mon, 17 Jun 2019 06:01:41 -0700 Subject: [PATCH 28/54] Temporary files and directories sample Followup on discussion in #243 --- examples.txt | 1 + .../temporary-files-and-directories.go | 65 +++++ .../temporary-files-and-directories.hash | 2 + .../temporary-files-and-directories.sh | 4 + public/index.html | 2 + public/temporary-files-and-directories | 232 ++++++++++++++++++ public/writing-files | 2 +- 7 files changed, 307 insertions(+), 1 deletion(-) create mode 100644 examples/temporary-files-and-directories/temporary-files-and-directories.go create mode 100644 examples/temporary-files-and-directories/temporary-files-and-directories.hash create mode 100644 examples/temporary-files-and-directories/temporary-files-and-directories.sh create mode 100644 public/temporary-files-and-directories diff --git a/examples.txt b/examples.txt index 887ef69..ae601df 100644 --- a/examples.txt +++ b/examples.txt @@ -56,6 +56,7 @@ SHA1 Hashes Base64 Encoding Reading Files Writing Files +Temporary Files and Directories Line Filters File Paths Directories diff --git a/examples/temporary-files-and-directories/temporary-files-and-directories.go b/examples/temporary-files-and-directories/temporary-files-and-directories.go new file mode 100644 index 0000000..abed14e --- /dev/null +++ b/examples/temporary-files-and-directories/temporary-files-and-directories.go @@ -0,0 +1,65 @@ +// Throughout program execution, we often want to create +// data that isn't needed after the program exits. +// *Temporary files and directories* are useful for this +// purpose since they don't pollute the file system over +// time. + +package main + +import ( + "fmt" + "io/ioutil" + "os" + "path/filepath" +) + +func check(e error) { + if e != nil { + panic(e) + } +} + +func main() { + + // The easiest way to create a temporary file is by + // calling `ioutil.TempFile`. It creates a file *and* + // opens it for reading and writing. We provide `""` + // as the first argument, so `ioutil.TempFile` will + // create the file in the default location for our OS. + f, err := ioutil.TempFile("", "sample") + check(err) + + // Display the name of the temporary file. On + // Unix-based OSes the directory will likely be `/tmp`. + // The file name starts with the prefix given as the + // second argument to `ioutil.TempFile` and the rest + // is chosen automatically to ensure that concurrent + // calls will always create different file names. + fmt.Println("Temp file name:", f.Name()) + + // Clean up the file after we're done. The OS is + // likely to clean up temporary files by itself after + // some time, but it's good practice to do this + // explicitly. + defer os.Remove(f.Name()) + + // We can write some data to the file. + _, err = f.Write([]byte{1, 2, 3, 4}) + check(err) + + // If we intend to write many temporary files, we may + // prefer to create a temporary *directory*. + // `ioutil.TempDir`'s arguments are the same as + // `TempFile`'s, but it returns a directory *name* + // rather than an open file. + dname, err := ioutil.TempDir("", "sampledir") + fmt.Println("Temp dir name:", dname) + + defer os.RemoveAll(dname) + + // Now we can synthesize temporary file names by + // prefixing them with our temporary directory. + fname := filepath.Join(dname, "file1") + err = ioutil.WriteFile(fname, []byte{1, 2}, 0666) + check(err) +} diff --git a/examples/temporary-files-and-directories/temporary-files-and-directories.hash b/examples/temporary-files-and-directories/temporary-files-and-directories.hash new file mode 100644 index 0000000..f523002 --- /dev/null +++ b/examples/temporary-files-and-directories/temporary-files-and-directories.hash @@ -0,0 +1,2 @@ +5f7d0c43988d7dce235adb06ec02f4d2026b7f83 +pxE20wGTFjv diff --git a/examples/temporary-files-and-directories/temporary-files-and-directories.sh b/examples/temporary-files-and-directories/temporary-files-and-directories.sh new file mode 100644 index 0000000..1854a19 --- /dev/null +++ b/examples/temporary-files-and-directories/temporary-files-and-directories.sh @@ -0,0 +1,4 @@ +# The exact names printed out will likely be different. +$ go run temporary-files-and-directories.go +Temp file name: /tmp/sample610887201 +Temp dir name: /tmp/sampledir898854668 diff --git a/public/index.html b/public/index.html index b11b9ef..e3cb506 100644 --- a/public/index.html +++ b/public/index.html @@ -139,6 +139,8 @@
  • Writing Files
  • +
  • Temporary Files and Directories
  • +
  • Line Filters
  • File Paths
  • diff --git a/public/temporary-files-and-directories b/public/temporary-files-and-directories new file mode 100644 index 0000000..e8336ca --- /dev/null +++ b/public/temporary-files-and-directories @@ -0,0 +1,232 @@ + + + + + Go by Example: Temporary Files and Directories + + + +
    +

    Go by Example: Temporary Files and Directories

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    Throughout program execution, we often want to create +data that isn’t needed after the program exits. +Temporary files and directories are useful for this +purpose since they don’t pollute the file system over +time.

    + +
    + + +
    + + + + + +
    package main
    +
    + +
    + + + +
    import (
    +    "fmt"
    +    "io/ioutil"
    +    "os"
    +    "path/filepath"
    +)
    +
    + +
    + + + +
    func check(e error) {
    +    if e != nil {
    +        panic(e)
    +    }
    +}
    +
    + +
    + + + +
    func main() {
    +
    + +
    +

    The easiest way to create a temporary file is by +calling ioutil.TempFile. It creates a file and +opens it for reading and writing. We provide "" +as the first argument, so ioutil.TempFile will +create the file in the default location for our OS.

    + +
    + +
        f, err := ioutil.TempFile("", "sample")
    +    check(err)
    +
    + +
    +

    Display the name of the temporary file. On +Unix-based OSes the directory will likely be /tmp. +The file name starts with the prefix given as the +second argument to ioutil.TempFile and the rest +is chosen automatically to ensure that concurrent +calls will always create different file names.

    + +
    + +
        fmt.Println("Temp file name:", f.Name())
    +
    + +
    +

    Clean up the file after we’re done. The OS is +likely to clean up temporary files by itself after +some time, but it’s good practice to do this +explicitly.

    + +
    + +
        defer os.Remove(f.Name())
    +
    + +
    +

    We can write some data to the file.

    + +
    + +
        _, err = f.Write([]byte{1, 2, 3, 4})
    +    check(err)
    +
    + +
    +

    If we intend to write many temporary files, we may +prefer to create a temporary directory. +ioutil.TempDir’s arguments are the same as +TempFile’s, but it returns a directory name +rather than an open file.

    + +
    + +
        dname, err := ioutil.TempDir("", "sampledir")
    +    fmt.Println("Temp dir name:", dname)
    +
    + +
    + + + +
        defer os.RemoveAll(dname)
    +
    + +
    +

    Now we can synthesize temporary file names by +prefixing them with our temporary directory.

    + +
    + +
        fname := filepath.Join(dname, "file1")
    +    err = ioutil.WriteFile(fname, []byte{1, 2}, 0666)
    +    check(err)
    +}
    +
    + +
    + + + + + + + + +
    +

    The exact names printed out will likely be different.

    + +
    + +
    $ go run temporary-files-and-directories.go
    +Temp file name: /tmp/sample610887201
    +Temp dir name: /tmp/sampledir898854668
    +
    + +
    + + +

    + Next example: Line Filters. +

    + + +
    + + diff --git a/public/writing-files b/public/writing-files index ca974bd..98401c2 100644 --- a/public/writing-files +++ b/public/writing-files @@ -266,7 +266,7 @@ we’ve just seen to the stdin and stdout streams.

    - Next example: Line Filters. + Next example: Temporary Files and Directories.

    - Next example: Command-Line Arguments. + Next example: Temporary Files and Directories.

  • Writing Files
  • -
  • Temporary Files and Directories
  • -
  • Line Filters
  • File Paths
  • Directories
  • +
  • Temporary Files and Directories
  • +
  • Command-Line Arguments
  • Command-Line Flags
  • diff --git a/public/temporary-files-and-directories b/public/temporary-files-and-directories index e8336ca..3b3bfc1 100644 --- a/public/temporary-files-and-directories +++ b/public/temporary-files-and-directories @@ -221,7 +221,7 @@ prefixing them with our temporary directory.

    - Next example: Line Filters. + Next example: Command-Line Arguments.

    - Next example: Temporary Files and Directories. + Next example: Line Filters.

    -

    The exact names printed out will likely be different.

    - + From 3d55c3ae33390451d13e26a06f7487d03355155c Mon Sep 17 00:00:00 2001 From: Mark McGranaghan Date: Sun, 30 Jun 2019 14:11:14 -0700 Subject: [PATCH 31/54] Tweak comment --- examples/defer/defer.go | 3 ++- examples/defer/defer.hash | 4 ++-- public/defer | 5 +++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/examples/defer/defer.go b/examples/defer/defer.go index 0941d10..724e698 100644 --- a/examples/defer/defer.go +++ b/examples/defer/defer.go @@ -41,7 +41,8 @@ func writeFile(f *os.File) { func closeFile(f *os.File) { fmt.Println("closing") err := f.Close() - // It is important to check for errors when closing a file, even in a deferred function. + // It's important to check for errors when closing a + // file, even in a deferred function. if err != nil { fmt.Fprintf(os.Stderr, "error: %v\n", err) os.Exit(1) diff --git a/examples/defer/defer.hash b/examples/defer/defer.hash index 5e437d4..78d3e35 100644 --- a/examples/defer/defer.hash +++ b/examples/defer/defer.hash @@ -1,2 +1,2 @@ -4e2229c593e102d4efd101a7e9aa21f3345e90d1 -S2RuPTkABip +fadbe9c05bb42db672316ba19adf3c2189c7b3f5 +OrCaBiCrTKq diff --git a/public/defer b/public/defer index 8f0b130..445d689 100644 --- a/public/defer +++ b/public/defer @@ -30,7 +30,7 @@ purposes of cleanup. defer is often used where e.g. - +
    package main
    @@ -134,7 +134,8 @@ of the enclosing function (main), after
             
             
               
    -            

    It is important to check for errors when closing a file, even in a deferred function.

    +

    It’s important to check for errors when closing a +file, even in a deferred function.

    From fb2c28e58a562d847d24c97abbdabbf5aef8de24 Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Mon, 1 Jul 2019 06:44:09 -0700 Subject: [PATCH 32/54] When testing on Travis, verify that tools/build was run This is done by routing the generation of HTML into a temporary directory, and checking its diff agains the existing public/ when running tests. Fixes #237 --- .travis.yml | 1 + tools/build | 26 ++++++++++++++++++++++++-- tools/generate | 2 +- tools/generate.go | 11 ++++++++++- 4 files changed, 36 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 54d1654..25b9ffc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,3 +16,4 @@ script: env: - VERBOSE=1 + - TESTING=1 diff --git a/tools/build b/tools/build index f06beae..4f66902 100755 --- a/tools/build +++ b/tools/build @@ -15,5 +15,27 @@ tools/format verbose && echo "Measuring line lengths..." tools/measure -verbose && echo "Generating HTML..." -tools/generate +# SITE_DIR is the final location where we want generated content to be +SITE_DIR="public" + +# GENERATE_DIR is where the content will be generated initially +GENERATE_DIR="$(mktemp -d)" + +function cleanup() { + rm -rf "$GENERATE_DIR" +} +trap cleanup EXIT + +verbose && echo "Generating HTML to $GENERATE_DIR..." +tools/generate $GENERATE_DIR + +# In TESTING mode, make sure that the generated content is identical to +# what's already in SITE_DIR. If a difference is found, this script exits +# with an error. +if [[ ! -z "$TESTING" ]]; then + echo "Comparing $GENERATE_DIR with $SITE_DIR..." + diff -r "$GENERATE_DIR" "$SITE_DIR" +fi + +verbose && echo "Copying $GENERATE_DIR to $SITE_DIR" +cp -rf "${GENERATE_DIR}/." "$SITE_DIR" diff --git a/tools/generate b/tools/generate index 83ed0e7..af897e5 100755 --- a/tools/generate +++ b/tools/generate @@ -1,3 +1,3 @@ #!/bin/bash -exec go run tools/generate.go +exec go run tools/generate.go $@ diff --git a/tools/generate.go b/tools/generate.go index 97d8ab5..a332128 100644 --- a/tools/generate.go +++ b/tools/generate.go @@ -15,8 +15,12 @@ import ( "github.com/russross/blackfriday" ) -var cacheDir = "/tmp/gobyexample-cache" +// siteDir is the target directory into which the HTML gets generated. Its +// default is set here but can be changed by an argument passed into the +// program. var siteDir = "./public" + +var cacheDir = "/tmp/gobyexample-cache" var pygmentizeBin = "./vendor/pygments/pygmentize" func verbose() bool { @@ -301,6 +305,11 @@ func renderExamples(examples []*Example) { } func main() { + if len(os.Args) > 1 { + siteDir = os.Args[1] + } + ensureDir(siteDir) + copyFile("templates/site.css", siteDir+"/site.css") copyFile("templates/favicon.ico", siteDir+"/favicon.ico") copyFile("templates/404.html", siteDir+"/404.html") From fe1443c7ed2d1ea56bf19ee45a28ffd8d9952ae4 Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Mon, 1 Jul 2019 06:51:20 -0700 Subject: [PATCH 33/54] Combine testing environments on travis --- .travis.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 25b9ffc..96a94a1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,5 +15,4 @@ script: - tools/build env: - - VERBOSE=1 - - TESTING=1 + - VERBOSE=1 TESTING=1 From c127e2898e6f63bdf0733b8c6b636ad9bb32b51c Mon Sep 17 00:00:00 2001 From: PeterBocan Date: Mon, 1 Jul 2019 16:45:01 +0200 Subject: [PATCH 34/54] Added a constructor to structs --- examples/structs/structs.go | 13 ++++++++++ examples/structs/structs.hash | 4 +-- examples/structs/structs.sh | 1 + public/structs | 47 +++++++++++++++++++++++++++++++++-- 4 files changed, 61 insertions(+), 4 deletions(-) diff --git a/examples/structs/structs.go b/examples/structs/structs.go index 6cf5629..21584a2 100644 --- a/examples/structs/structs.go +++ b/examples/structs/structs.go @@ -12,6 +12,16 @@ type person struct { age int } +// A de facto constructor of type `person`. +func NewPerson(name string) *person { + + // You can safely return a pointer to local variable + // as a local variable will survive the scope of the function. + p := person{name: name} + p.age = 42 + return &p +} + func main() { // This syntax creates a new struct. @@ -38,4 +48,7 @@ func main() { // Structs are mutable. sp.age = 51 fmt.Println(sp.age) + + // Call our constructor + fmt.Println(NewPerson("Jon")) } diff --git a/examples/structs/structs.hash b/examples/structs/structs.hash index 2c0e37f..a1194e9 100644 --- a/examples/structs/structs.hash +++ b/examples/structs/structs.hash @@ -1,2 +1,2 @@ -49cad39331ee5e9fb8d8dad99d3aff7f18a4e6d0 -XMZpGsF4sWM +71e8ecdcf8c8fbddbb250ada5bbe8659b68d5229 +nHvnHAGTYHq diff --git a/examples/structs/structs.sh b/examples/structs/structs.sh index 6d82fa0..f0d6025 100644 --- a/examples/structs/structs.sh +++ b/examples/structs/structs.sh @@ -6,3 +6,4 @@ $ go run structs.go Sean 50 51 +&{Jon 42} \ No newline at end of file diff --git a/public/structs b/public/structs index 31c03d0..22fd85f 100644 --- a/public/structs +++ b/public/structs @@ -29,7 +29,7 @@ records.

    - +
    package main
    @@ -66,6 +66,36 @@ records.

    + + +

    A de facto constructor of type person.

    + + + + +
    func NewPerson(name string) *person {
    +
    + + + + + + +

    You can safely return a pointer to local variable +as a local variable will survive the scope of the function.

    + + + + +
        p := person{name: name}
    +    p.age = 42
    +    return &p
    +}
    +
    + + + + @@ -164,10 +194,23 @@ pointers are automatically dereferenced.

    Structs are mutable.

    - +
        sp.age = 51
         fmt.Println(sp.age)
    +
    + + + + + + +

    Call our constructor

    + + + + +
        fmt.Println(NewPerson("Jon"))
     }
     
    From 615d5e2eb460851838448c5b1bd7a768b79c9ab9 Mon Sep 17 00:00:00 2001 From: PeterBocan Date: Tue, 2 Jul 2019 15:46:54 +0200 Subject: [PATCH 35/54] Struct allocation fixes. --- examples/structs/structs.go | 8 ++++---- examples/structs/structs.hash | 4 ++-- public/structs | 24 ++++++++++++++++++------ 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/examples/structs/structs.go b/examples/structs/structs.go index 21584a2..e2546fe 100644 --- a/examples/structs/structs.go +++ b/examples/structs/structs.go @@ -12,9 +12,8 @@ type person struct { age int } -// A de facto constructor of type `person`. +// NewPerson constructs a new person struct with the given name func NewPerson(name string) *person { - // You can safely return a pointer to local variable // as a local variable will survive the scope of the function. p := person{name: name} @@ -36,6 +35,9 @@ func main() { // An `&` prefix yields a pointer to the struct. fmt.Println(&person{name: "Ann", age: 40}) + // It's idiomatic to encapsulate new struct creation in constructor functions + fmt.Println(NewPerson("Jon")) + // Access struct fields with a dot. s := person{name: "Sean", age: 50} fmt.Println(s.name) @@ -49,6 +51,4 @@ func main() { sp.age = 51 fmt.Println(sp.age) - // Call our constructor - fmt.Println(NewPerson("Jon")) } diff --git a/examples/structs/structs.hash b/examples/structs/structs.hash index a1194e9..50e4d67 100644 --- a/examples/structs/structs.hash +++ b/examples/structs/structs.hash @@ -1,2 +1,2 @@ -71e8ecdcf8c8fbddbb250ada5bbe8659b68d5229 -nHvnHAGTYHq +cd504951e9f8504c159a66714b04bfda0629e58c +ezfE4eojTS7 diff --git a/public/structs b/public/structs index 22fd85f..0ea36aa 100644 --- a/public/structs +++ b/public/structs @@ -29,7 +29,7 @@ records.

    - +
    package main
    @@ -68,7 +68,7 @@ records.

    -

    A de facto constructor of type person.

    +

    NewPerson constructs a new person struct with the given name

    @@ -160,6 +160,19 @@ as a local variable will survive the scope of the function.

    + + +

    It’s idiomatic to encapsulate new struct creation in constructor functions

    + + + + +
        fmt.Println(NewPerson("Jon"))
    +
    + + + +

    Access struct fields with a dot.

    @@ -205,13 +218,11 @@ pointers are automatically dereferenced.

    -

    Call our constructor

    - + -
        fmt.Println(NewPerson("Jon"))
    -}
    +            
    }
     
    @@ -235,6 +246,7 @@ pointers are automatically dereferenced.

    Sean 50 51 +&{Jon 42}
    From c22f42f03cb1511c24e573374390ec261d6e2704 Mon Sep 17 00:00:00 2001 From: PeterBocan Date: Tue, 2 Jul 2019 16:30:42 +0200 Subject: [PATCH 36/54] Remove extra whitespace --- examples/structs/structs.go | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/structs/structs.go b/examples/structs/structs.go index e2546fe..384b57c 100644 --- a/examples/structs/structs.go +++ b/examples/structs/structs.go @@ -50,5 +50,4 @@ func main() { // Structs are mutable. sp.age = 51 fmt.Println(sp.age) - } From 1943fe080370d47556cfdc96f62c83a446f7e84d Mon Sep 17 00:00:00 2001 From: Shivam Rathore Date: Mon, 24 Jun 2019 00:41:52 +0530 Subject: [PATCH 37/54] arrow keys navigation added | fixes mmcgrana/gobyexample#222 --- .gitignore | 2 ++ public/arrays | 14 ++++++++++++++ public/atomic-counters | 14 ++++++++++++++ public/base64-encoding | 14 ++++++++++++++ public/channel-buffering | 14 ++++++++++++++ public/channel-directions | 14 ++++++++++++++ public/channel-synchronization | 14 ++++++++++++++ public/channels | 14 ++++++++++++++ public/closing-channels | 14 ++++++++++++++ public/closures | 14 ++++++++++++++ public/collection-functions | 14 ++++++++++++++ public/command-line-arguments | 14 ++++++++++++++ public/command-line-flags | 14 ++++++++++++++ public/command-line-subcommands | 14 ++++++++++++++ public/constants | 14 ++++++++++++++ public/defer | 14 ++++++++++++++ public/environment-variables | 14 ++++++++++++++ public/epoch | 14 ++++++++++++++ public/errors | 14 ++++++++++++++ public/execing-processes | 14 ++++++++++++++ public/exit | 10 ++++++++++ public/file-paths | 14 ++++++++++++++ public/for | 14 ++++++++++++++ public/functions | 14 ++++++++++++++ public/goroutines | 14 ++++++++++++++ public/hello-world | 10 ++++++++++ public/http-clients | 14 ++++++++++++++ public/http-servers | 14 ++++++++++++++ public/if-else | 14 ++++++++++++++ public/interfaces | 14 ++++++++++++++ public/json | 14 ++++++++++++++ public/line-filters | 14 ++++++++++++++ public/maps | 14 ++++++++++++++ public/methods | 14 ++++++++++++++ public/multiple-return-values | 14 ++++++++++++++ public/mutexes | 14 ++++++++++++++ public/non-blocking-channel-operations | 14 ++++++++++++++ public/number-parsing | 14 ++++++++++++++ public/panic | 14 ++++++++++++++ public/pointers | 14 ++++++++++++++ public/random-numbers | 14 ++++++++++++++ public/range | 14 ++++++++++++++ public/range-over-channels | 14 ++++++++++++++ public/rate-limiting | 14 ++++++++++++++ public/reading-files | 14 ++++++++++++++ public/recursion | 14 ++++++++++++++ public/regular-expressions | 14 ++++++++++++++ public/select | 14 ++++++++++++++ public/sha1-hashes | 14 ++++++++++++++ public/signals | 14 ++++++++++++++ public/slices | 14 ++++++++++++++ public/sorting | 14 ++++++++++++++ public/sorting-by-functions | 14 ++++++++++++++ public/spawning-processes | 14 ++++++++++++++ public/stateful-goroutines | 14 ++++++++++++++ public/string-formatting | 14 ++++++++++++++ public/string-functions | 14 ++++++++++++++ public/structs | 14 ++++++++++++++ public/switch | 14 ++++++++++++++ public/tickers | 14 ++++++++++++++ public/time | 14 ++++++++++++++ public/time-formatting-parsing | 14 ++++++++++++++ public/timeouts | 14 ++++++++++++++ public/timers | 14 ++++++++++++++ public/url-parsing | 14 ++++++++++++++ public/values | 14 ++++++++++++++ public/variables | 14 ++++++++++++++ public/variadic-functions | 14 ++++++++++++++ public/waitgroups | 14 ++++++++++++++ public/worker-pools | 14 ++++++++++++++ public/writing-files | 14 ++++++++++++++ templates/example.tmpl | 14 ++++++++++++++ tools/generate.go | 4 ++++ 73 files changed, 992 insertions(+) diff --git a/.gitignore b/.gitignore index 0d20b64..acb800c 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ *.pyc +.idea +.vscode diff --git a/public/arrays b/public/arrays index 9f12e9d..b9f36ce 100644 --- a/public/arrays +++ b/public/arrays @@ -5,6 +5,20 @@ Go by Example: Arrays +

    Go by Example: Arrays

    diff --git a/public/atomic-counters b/public/atomic-counters index 9ba1895..c4df533 100644 --- a/public/atomic-counters +++ b/public/atomic-counters @@ -5,6 +5,20 @@ Go by Example: Atomic Counters +

    Go by Example: Atomic Counters

    diff --git a/public/base64-encoding b/public/base64-encoding index 2c1da0d..fdbaaed 100644 --- a/public/base64-encoding +++ b/public/base64-encoding @@ -5,6 +5,20 @@ Go by Example: Base64 Encoding +

    Go by Example: Base64 Encoding

    diff --git a/public/channel-buffering b/public/channel-buffering index 2734939..a11749b 100644 --- a/public/channel-buffering +++ b/public/channel-buffering @@ -5,6 +5,20 @@ Go by Example: Channel Buffering +

    Go by Example: Channel Buffering

    diff --git a/public/channel-directions b/public/channel-directions index 02c7c0a..2c95a14 100644 --- a/public/channel-directions +++ b/public/channel-directions @@ -5,6 +5,20 @@ Go by Example: Channel Directions +

    Go by Example: Channel Directions

    diff --git a/public/channel-synchronization b/public/channel-synchronization index 00076f9..595487d 100644 --- a/public/channel-synchronization +++ b/public/channel-synchronization @@ -5,6 +5,20 @@ Go by Example: Channel Synchronization +

    Go by Example: Channel Synchronization

    diff --git a/public/channels b/public/channels index 94b14d7..25995b6 100644 --- a/public/channels +++ b/public/channels @@ -5,6 +5,20 @@ Go by Example: Channels +

    Go by Example: Channels

    diff --git a/public/closing-channels b/public/closing-channels index d873cd8..ff67861 100644 --- a/public/closing-channels +++ b/public/closing-channels @@ -5,6 +5,20 @@ Go by Example: Closing Channels +

    Go by Example: Closing Channels

    diff --git a/public/closures b/public/closures index d85af28..0bb3852 100644 --- a/public/closures +++ b/public/closures @@ -5,6 +5,20 @@ Go by Example: Closures +

    Go by Example: Closures

    diff --git a/public/collection-functions b/public/collection-functions index 07e970b..fce4ddd 100644 --- a/public/collection-functions +++ b/public/collection-functions @@ -5,6 +5,20 @@ Go by Example: Collection Functions +

    Go by Example: Collection Functions

    diff --git a/public/command-line-arguments b/public/command-line-arguments index b649bd2..a585d22 100644 --- a/public/command-line-arguments +++ b/public/command-line-arguments @@ -5,6 +5,20 @@ Go by Example: Command-Line Arguments +

    Go by Example: Command-Line Arguments

    diff --git a/public/command-line-flags b/public/command-line-flags index 43ec18f..32c7abe 100644 --- a/public/command-line-flags +++ b/public/command-line-flags @@ -5,6 +5,20 @@ Go by Example: Command-Line Flags +

    Go by Example: Command-Line Flags

    diff --git a/public/command-line-subcommands b/public/command-line-subcommands index 39b385b..333e048 100644 --- a/public/command-line-subcommands +++ b/public/command-line-subcommands @@ -5,6 +5,20 @@ Go by Example: Command-Line Subcommands +

    Go by Example: Command-Line Subcommands

    diff --git a/public/constants b/public/constants index c564424..0609217 100644 --- a/public/constants +++ b/public/constants @@ -5,6 +5,20 @@ Go by Example: Constants +

    Go by Example: Constants

    diff --git a/public/defer b/public/defer index 445d689..42299e5 100644 --- a/public/defer +++ b/public/defer @@ -5,6 +5,20 @@ Go by Example: Defer +

    Go by Example: Defer

    diff --git a/public/environment-variables b/public/environment-variables index 3d2e54c..56a1cc3 100644 --- a/public/environment-variables +++ b/public/environment-variables @@ -5,6 +5,20 @@ Go by Example: Environment Variables +

    Go by Example: Environment Variables

    diff --git a/public/epoch b/public/epoch index 46d62e7..60ecde3 100644 --- a/public/epoch +++ b/public/epoch @@ -5,6 +5,20 @@ Go by Example: Epoch +

    Go by Example: Epoch

    diff --git a/public/errors b/public/errors index 489f119..a473c1b 100644 --- a/public/errors +++ b/public/errors @@ -5,6 +5,20 @@ Go by Example: Errors +

    Go by Example: Errors

    diff --git a/public/execing-processes b/public/execing-processes index 85b155d..2d26b21 100644 --- a/public/execing-processes +++ b/public/execing-processes @@ -5,6 +5,20 @@ Go by Example: Exec'ing Processes +

    Go by Example: Exec'ing Processes

    diff --git a/public/exit b/public/exit index 4c6975d..7b32b81 100644 --- a/public/exit +++ b/public/exit @@ -5,6 +5,16 @@ Go by Example: Exit +

    Go by Example: Exit

    diff --git a/public/file-paths b/public/file-paths index f7b24a1..9dae4c6 100644 --- a/public/file-paths +++ b/public/file-paths @@ -5,6 +5,20 @@ Go by Example: File Paths +

    Go by Example: File Paths

    diff --git a/public/for b/public/for index 314f139..47f39c9 100644 --- a/public/for +++ b/public/for @@ -5,6 +5,20 @@ Go by Example: For +

    Go by Example: For

    diff --git a/public/functions b/public/functions index 7c89d83..8eeca6c 100644 --- a/public/functions +++ b/public/functions @@ -5,6 +5,20 @@ Go by Example: Functions +

    Go by Example: Functions

    diff --git a/public/goroutines b/public/goroutines index 40ba434..06f5e9b 100644 --- a/public/goroutines +++ b/public/goroutines @@ -5,6 +5,20 @@ Go by Example: Goroutines +

    Go by Example: Goroutines

    diff --git a/public/hello-world b/public/hello-world index d8b1872..f33d703 100644 --- a/public/hello-world +++ b/public/hello-world @@ -5,6 +5,16 @@ Go by Example: Hello World +

    Go by Example: Hello World

    diff --git a/public/http-clients b/public/http-clients index 5d5bf04..d1a9f50 100644 --- a/public/http-clients +++ b/public/http-clients @@ -5,6 +5,20 @@ Go by Example: HTTP Clients +

    Go by Example: HTTP Clients

    diff --git a/public/http-servers b/public/http-servers index 2dedf1a..68431cf 100644 --- a/public/http-servers +++ b/public/http-servers @@ -5,6 +5,20 @@ Go by Example: HTTP Servers +

    Go by Example: HTTP Servers

    diff --git a/public/if-else b/public/if-else index 2ed0680..dcc5aec 100644 --- a/public/if-else +++ b/public/if-else @@ -5,6 +5,20 @@ Go by Example: If/Else +

    Go by Example: If/Else

    diff --git a/public/interfaces b/public/interfaces index 277c8f8..909465b 100644 --- a/public/interfaces +++ b/public/interfaces @@ -5,6 +5,20 @@ Go by Example: Interfaces +

    Go by Example: Interfaces

    diff --git a/public/json b/public/json index 54979d2..f6a4146 100644 --- a/public/json +++ b/public/json @@ -5,6 +5,20 @@ Go by Example: JSON +

    Go by Example: JSON

    diff --git a/public/line-filters b/public/line-filters index d264214..d673b55 100644 --- a/public/line-filters +++ b/public/line-filters @@ -5,6 +5,20 @@ Go by Example: Line Filters +

    Go by Example: Line Filters

    diff --git a/public/maps b/public/maps index bf31208..bfaefce 100644 --- a/public/maps +++ b/public/maps @@ -5,6 +5,20 @@ Go by Example: Maps +

    Go by Example: Maps

    diff --git a/public/methods b/public/methods index c1ae6d0..cf9f7f7 100644 --- a/public/methods +++ b/public/methods @@ -5,6 +5,20 @@ Go by Example: Methods +

    Go by Example: Methods

    diff --git a/public/multiple-return-values b/public/multiple-return-values index 5392875..1bd021d 100644 --- a/public/multiple-return-values +++ b/public/multiple-return-values @@ -5,6 +5,20 @@ Go by Example: Multiple Return Values +

    Go by Example: Multiple Return Values

    diff --git a/public/mutexes b/public/mutexes index efc2253..f3c8476 100644 --- a/public/mutexes +++ b/public/mutexes @@ -5,6 +5,20 @@ Go by Example: Mutexes +

    Go by Example: Mutexes

    diff --git a/public/non-blocking-channel-operations b/public/non-blocking-channel-operations index ada60a3..64c17ca 100644 --- a/public/non-blocking-channel-operations +++ b/public/non-blocking-channel-operations @@ -5,6 +5,20 @@ Go by Example: Non-Blocking Channel Operations +

    Go by Example: Non-Blocking Channel Operations

    diff --git a/public/number-parsing b/public/number-parsing index 35e768e..e8c4f81 100644 --- a/public/number-parsing +++ b/public/number-parsing @@ -5,6 +5,20 @@ Go by Example: Number Parsing +

    Go by Example: Number Parsing

    diff --git a/public/panic b/public/panic index 59198af..4b08f98 100644 --- a/public/panic +++ b/public/panic @@ -5,6 +5,20 @@ Go by Example: Panic +

    Go by Example: Panic

    diff --git a/public/pointers b/public/pointers index 16687f5..2caca80 100644 --- a/public/pointers +++ b/public/pointers @@ -5,6 +5,20 @@ Go by Example: Pointers +

    Go by Example: Pointers

    diff --git a/public/random-numbers b/public/random-numbers index 5de950f..29f47e9 100644 --- a/public/random-numbers +++ b/public/random-numbers @@ -5,6 +5,20 @@ Go by Example: Random Numbers +

    Go by Example: Random Numbers

    diff --git a/public/range b/public/range index e9aa99e..688bbdb 100644 --- a/public/range +++ b/public/range @@ -5,6 +5,20 @@ Go by Example: Range +

    Go by Example: Range

    diff --git a/public/range-over-channels b/public/range-over-channels index a3ba422..5b6e160 100644 --- a/public/range-over-channels +++ b/public/range-over-channels @@ -5,6 +5,20 @@ Go by Example: Range over Channels +

    Go by Example: Range over Channels

    diff --git a/public/rate-limiting b/public/rate-limiting index 07dc185..30b739f 100644 --- a/public/rate-limiting +++ b/public/rate-limiting @@ -5,6 +5,20 @@ Go by Example: Rate Limiting +

    Go by Example: Rate Limiting

    diff --git a/public/reading-files b/public/reading-files index d51206c..af5009b 100644 --- a/public/reading-files +++ b/public/reading-files @@ -5,6 +5,20 @@ Go by Example: Reading Files +

    Go by Example: Reading Files

    diff --git a/public/recursion b/public/recursion index bedbf2f..db074e2 100644 --- a/public/recursion +++ b/public/recursion @@ -5,6 +5,20 @@ Go by Example: Recursion +

    Go by Example: Recursion

    diff --git a/public/regular-expressions b/public/regular-expressions index 8db2fbd..237af8e 100644 --- a/public/regular-expressions +++ b/public/regular-expressions @@ -5,6 +5,20 @@ Go by Example: Regular Expressions +

    Go by Example: Regular Expressions

    diff --git a/public/select b/public/select index d6733a1..af53205 100644 --- a/public/select +++ b/public/select @@ -5,6 +5,20 @@ Go by Example: Select +

    Go by Example: Select

    diff --git a/public/sha1-hashes b/public/sha1-hashes index c28cf1d..f3e4155 100644 --- a/public/sha1-hashes +++ b/public/sha1-hashes @@ -5,6 +5,20 @@ Go by Example: SHA1 Hashes +

    Go by Example: SHA1 Hashes

    diff --git a/public/signals b/public/signals index 50f0ec1..9a1d9f5 100644 --- a/public/signals +++ b/public/signals @@ -5,6 +5,20 @@ Go by Example: Signals +

    Go by Example: Signals

    diff --git a/public/slices b/public/slices index fba69c9..4e30c3f 100644 --- a/public/slices +++ b/public/slices @@ -5,6 +5,20 @@ Go by Example: Slices +

    Go by Example: Slices

    diff --git a/public/sorting b/public/sorting index 73f22b1..219bc63 100644 --- a/public/sorting +++ b/public/sorting @@ -5,6 +5,20 @@ Go by Example: Sorting +

    Go by Example: Sorting

    diff --git a/public/sorting-by-functions b/public/sorting-by-functions index 92c0f41..a2efcc8 100644 --- a/public/sorting-by-functions +++ b/public/sorting-by-functions @@ -5,6 +5,20 @@ Go by Example: Sorting by Functions +

    Go by Example: Sorting by Functions

    diff --git a/public/spawning-processes b/public/spawning-processes index c6ba21e..d8396b9 100644 --- a/public/spawning-processes +++ b/public/spawning-processes @@ -5,6 +5,20 @@ Go by Example: Spawning Processes +

    Go by Example: Spawning Processes

    diff --git a/public/stateful-goroutines b/public/stateful-goroutines index a14245a..da6329c 100644 --- a/public/stateful-goroutines +++ b/public/stateful-goroutines @@ -5,6 +5,20 @@ Go by Example: Stateful Goroutines +

    Go by Example: Stateful Goroutines

    diff --git a/public/string-formatting b/public/string-formatting index c3118b0..c0652e6 100644 --- a/public/string-formatting +++ b/public/string-formatting @@ -5,6 +5,20 @@ Go by Example: String Formatting +

    Go by Example: String Formatting

    diff --git a/public/string-functions b/public/string-functions index 73b6019..4882c60 100644 --- a/public/string-functions +++ b/public/string-functions @@ -5,6 +5,20 @@ Go by Example: String Functions +

    Go by Example: String Functions

    diff --git a/public/structs b/public/structs index 31c03d0..ac4a3cb 100644 --- a/public/structs +++ b/public/structs @@ -5,6 +5,20 @@ Go by Example: Structs +

    Go by Example: Structs

    diff --git a/public/switch b/public/switch index c739ea3..fae75e8 100644 --- a/public/switch +++ b/public/switch @@ -5,6 +5,20 @@ Go by Example: Switch +

    Go by Example: Switch

    diff --git a/public/tickers b/public/tickers index 64f1044..286dfff 100644 --- a/public/tickers +++ b/public/tickers @@ -5,6 +5,20 @@ Go by Example: Tickers +

    Go by Example: Tickers

    diff --git a/public/time b/public/time index 443f568..90fbf1f 100644 --- a/public/time +++ b/public/time @@ -5,6 +5,20 @@ Go by Example: Time +

    Go by Example: Time

    diff --git a/public/time-formatting-parsing b/public/time-formatting-parsing index f16fbc9..602c729 100644 --- a/public/time-formatting-parsing +++ b/public/time-formatting-parsing @@ -5,6 +5,20 @@ Go by Example: Time Formatting / Parsing +

    Go by Example: Time Formatting / Parsing

    diff --git a/public/timeouts b/public/timeouts index 449446a..35315f4 100644 --- a/public/timeouts +++ b/public/timeouts @@ -5,6 +5,20 @@ Go by Example: Timeouts +

    Go by Example: Timeouts

    diff --git a/public/timers b/public/timers index 7004b5f..3ba794e 100644 --- a/public/timers +++ b/public/timers @@ -5,6 +5,20 @@ Go by Example: Timers +

    Go by Example: Timers

    diff --git a/public/url-parsing b/public/url-parsing index 8b17377..71874e9 100644 --- a/public/url-parsing +++ b/public/url-parsing @@ -5,6 +5,20 @@ Go by Example: URL Parsing +

    Go by Example: URL Parsing

    diff --git a/public/values b/public/values index 38966a3..648aed8 100644 --- a/public/values +++ b/public/values @@ -5,6 +5,20 @@ Go by Example: Values +

    Go by Example: Values

    diff --git a/public/variables b/public/variables index 9c1156a..0779d1c 100644 --- a/public/variables +++ b/public/variables @@ -5,6 +5,20 @@ Go by Example: Variables +

    Go by Example: Variables

    diff --git a/public/variadic-functions b/public/variadic-functions index 75ce887..f0355c4 100644 --- a/public/variadic-functions +++ b/public/variadic-functions @@ -5,6 +5,20 @@ Go by Example: Variadic Functions +

    Go by Example: Variadic Functions

    diff --git a/public/waitgroups b/public/waitgroups index 45792a8..5962f99 100644 --- a/public/waitgroups +++ b/public/waitgroups @@ -5,6 +5,20 @@ Go by Example: WaitGroups +

    Go by Example: WaitGroups

    diff --git a/public/worker-pools b/public/worker-pools index e1170bf..ddabd53 100644 --- a/public/worker-pools +++ b/public/worker-pools @@ -5,6 +5,20 @@ Go by Example: Worker Pools +

    Go by Example: Worker Pools

    diff --git a/public/writing-files b/public/writing-files index ca974bd..f4dd30d 100644 --- a/public/writing-files +++ b/public/writing-files @@ -5,6 +5,20 @@ Go by Example: Writing Files +

    Go by Example: Writing Files

    diff --git a/templates/example.tmpl b/templates/example.tmpl index c9cfb7d..8d6f1aa 100644 --- a/templates/example.tmpl +++ b/templates/example.tmpl @@ -5,6 +5,20 @@ Go by Example: {{.Name}} +

    Go by Example: {{.Name}}

    diff --git a/tools/generate.go b/tools/generate.go index a332128..33acb60 100644 --- a/tools/generate.go +++ b/tools/generate.go @@ -138,6 +138,7 @@ type Example struct { ID, Name string GoCode, GoCodeHash, URLHash string Segs [][]*Seg + PrevExample *Example NextExample *Example } @@ -270,6 +271,9 @@ func parseExamples() []*Example { examples = append(examples, &example) } for i, example := range examples { + if i > 0 { + example.PrevExample = examples[i-1] + } if i < (len(examples) - 1) { example.NextExample = examples[i+1] } From 53a1b7a10762a3a7b8d5ec5e46b0ca37e95e724e Mon Sep 17 00:00:00 2001 From: Mark McGranaghan Date: Mon, 8 Jul 2019 19:04:48 -0700 Subject: [PATCH 38/54] Regenerate --- public/command-line-arguments | 2 +- public/directories | 14 ++++++++++++++ public/file-paths | 2 +- public/temporary-files-and-directories | 14 ++++++++++++++ 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/public/command-line-arguments b/public/command-line-arguments index a585d22..fc80282 100644 --- a/public/command-line-arguments +++ b/public/command-line-arguments @@ -9,7 +9,7 @@ onkeydown = (e) => { if (e.key == "ArrowLeft") { - window.location.href = 'file-paths'; + window.location.href = 'temporary-files-and-directories'; } diff --git a/public/directories b/public/directories index 25fc6d4..beb7a7e 100644 --- a/public/directories +++ b/public/directories @@ -5,6 +5,20 @@ Go by Example: Directories +

    Go by Example: Directories

    diff --git a/public/file-paths b/public/file-paths index 9dae4c6..44a1faf 100644 --- a/public/file-paths +++ b/public/file-paths @@ -14,7 +14,7 @@ if (e.key == "ArrowRight") { - window.location.href = 'command-line-arguments'; + window.location.href = 'directories'; } } diff --git a/public/temporary-files-and-directories b/public/temporary-files-and-directories index ddc5e39..ce479ca 100644 --- a/public/temporary-files-and-directories +++ b/public/temporary-files-and-directories @@ -5,6 +5,20 @@ Go by Example: Temporary Files and Directories +

    Go by Example: Temporary Files and Directories

    From 2862b97d01f4f2dc8294a758998f917f0b521e6e Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Fri, 12 Jul 2019 06:14:47 -0700 Subject: [PATCH 39/54] Update CONTRIBUTING.md --- CONTRIBUTING.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2366de8..40439fe 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,9 +2,11 @@ Thanks for your interest in contributing to Go by Example! -* If you see a typo or would like to suggest another small change, editing the - .go or .sh source file should be sufficient for the PR. I can rebuild the - HTML when I review the change. +* When sending a PR that affects the displayed contents of the site, run + `tools/build` locally and include the generated HTML in the PR. If you + only want to submit a simple typo suggestion (for example, through the + Github website), feel free to send a PR anyway - we'll regenerate the + HTML and merge with your commit. * We're open to adding more examples to the site. They should be on things used by many programmers and only require the standard library. If you're From 482bd86963754fe2bae6a005508153573388487f Mon Sep 17 00:00:00 2001 From: Julian Zucker Date: Wed, 24 Jul 2019 18:27:04 -0600 Subject: [PATCH 40/54] Fix typo in http servers example --- examples/http-servers/http-servers.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/http-servers/http-servers.go b/examples/http-servers/http-servers.go index 72726b4..42a83b3 100644 --- a/examples/http-servers/http-servers.go +++ b/examples/http-servers/http-servers.go @@ -17,7 +17,7 @@ func hello(w http.ResponseWriter, req *http.Request) { // Functions serving as handlers take a // `http.ResponseWriter` and a `http.Request` as // arguments. The response writer is used to fill in the - // HTTP response. Here out simple response is just + // HTTP response. Here our simple response is just // "hello\n". fmt.Fprintf(w, "hello\n") } From 0198f3e8246fad0c4baff11cca7dc95d9c20ecc6 Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Sat, 24 Aug 2019 06:28:01 -0700 Subject: [PATCH 41/54] Fix up language attribution for the Github UI Currently gobyexample is flagged as a CSS repository because of all the generated HTML. Following instructions at https://github.com/github/linguist#vendored-code to ask Github to ignore files that are not actual origin code. --- .gitattributes | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..ac8f8c3 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +public/* linguist-generated=true +vendor/* linguist-vendored=true + From 490c0e759913e5269a6515e128ced6b914d7dc4b Mon Sep 17 00:00:00 2001 From: Mark McGranaghan Date: Sun, 1 Sep 2019 15:11:49 -0700 Subject: [PATCH 42/54] Regenerate --- examples/http-servers/http-servers.hash | 4 ++-- public/http-servers | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/http-servers/http-servers.hash b/examples/http-servers/http-servers.hash index 6a0a323..a491ac1 100644 --- a/examples/http-servers/http-servers.hash +++ b/examples/http-servers/http-servers.hash @@ -1,2 +1,2 @@ -ac2909e69be30862bd9f18db954d9ee10f57ec6a -8GBAW6yNcbn +a4e8d30b7a6f3a6abd96b916d81ce5930bad94f9 +lNuS9ysZmxH diff --git a/public/http-servers b/public/http-servers index 68431cf..b9f74d6 100644 --- a/public/http-servers +++ b/public/http-servers @@ -32,7 +32,7 @@ - +
    package main
    @@ -78,7 +78,7 @@ on functions with the appropriate signature.

    Functions serving as handlers take a http.ResponseWriter and a http.Request as arguments. The response writer is used to fill in the -HTTP response. Here out simple response is just +HTTP response. Here our simple response is just “hello\n”.

    From 99505c39540b37c763ec1183e4878f98632293e8 Mon Sep 17 00:00:00 2001 From: Mark McGranaghan Date: Sun, 1 Sep 2019 15:30:27 -0700 Subject: [PATCH 43/54] Regnerate --- examples/structs/structs.hash | 4 ++-- public/structs | 17 +++-------------- 2 files changed, 5 insertions(+), 16 deletions(-) diff --git a/examples/structs/structs.hash b/examples/structs/structs.hash index 50e4d67..15fcdc0 100644 --- a/examples/structs/structs.hash +++ b/examples/structs/structs.hash @@ -1,2 +1,2 @@ -cd504951e9f8504c159a66714b04bfda0629e58c -ezfE4eojTS7 +c5caaf1eefaf084d688afb70d2ee5884a4983182 +00Yiw6xuICq diff --git a/public/structs b/public/structs index 0ca3b3e..b550a3c 100644 --- a/public/structs +++ b/public/structs @@ -43,7 +43,7 @@ records.

    - +
    package main
    @@ -221,22 +221,11 @@ pointers are automatically dereferenced.

    Structs are mutable.

    - +
        sp.age = 51
         fmt.Println(sp.age)
    -
    - - - - - - - - - - -
    }
    +}
     
    From 99218c520a60dca287cb0d01c91d7e8772296225 Mon Sep 17 00:00:00 2001 From: Bailey Wickham Date: Sun, 1 Sep 2019 16:07:33 -0700 Subject: [PATCH 44/54] Update export explanation --- examples/json/json.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/json/json.go b/examples/json/json.go index 101a1cb..bd91a8b 100644 --- a/examples/json/json.go +++ b/examples/json/json.go @@ -14,8 +14,8 @@ type response1 struct { Page int Fruits []string } -// Fields must have capital letters to be exposed to other -// programs such as the JSON Marshaller. +// Only exported fields will be encoded/decoded in JSON. +// Fields must start with capital letters to be exported. type response2 struct { Page int `json:"page"` Fruits []string `json:"fruits"` From 78e1fd61ec65924911ba3999796710b6735fddfb Mon Sep 17 00:00:00 2001 From: Mark McGranaghan Date: Sun, 1 Sep 2019 15:42:33 -0700 Subject: [PATCH 45/54] Clean up merge --- public/arrays | 31 ++++++------ public/atomic-counters | 33 +++++++------ public/base64-encoding | 29 ++++++----- public/channel-buffering | 25 +++++----- public/channel-directions | 23 +++++---- public/channel-synchronization | 29 ++++++----- public/channels | 27 +++++----- public/clipboard.png | Bin 0 -> 488 bytes public/closing-channels | 27 +++++----- public/closures | 29 ++++++----- public/collection-functions | 51 ++++++++++--------- public/command-line-arguments | 27 +++++----- public/command-line-flags | 41 ++++++++-------- public/command-line-subcommands | 37 +++++++------- public/constants | 29 ++++++----- public/defer | 31 ++++++------ public/directories | 49 ++++++++++--------- public/environment-variables | 27 +++++----- public/epoch | 27 +++++----- public/errors | 41 ++++++++-------- public/execing-processes | 29 ++++++----- public/exit | 29 ++++++----- public/file-paths | 35 +++++++------ public/for | 29 ++++++----- public/functions | 31 ++++++------ public/goroutines | 31 ++++++------ public/hello-world | 23 +++++---- public/http-clients | 25 +++++----- public/http-servers | 31 ++++++------ public/if-else | 29 ++++++----- public/interfaces | 33 +++++++------ public/json | 53 ++++++++++---------- public/line-filters | 31 ++++++------ public/maps | 35 +++++++------ public/methods | 31 ++++++------ public/multiple-return-values | 27 +++++----- public/mutexes | 41 ++++++++-------- public/non-blocking-channel-operations | 25 +++++----- public/number-parsing | 33 +++++++------ public/panic | 27 +++++----- public/pointers | 29 ++++++----- public/random-numbers | 33 +++++++------ public/range | 29 ++++++----- public/range-over-channels | 25 +++++----- public/rate-limiting | 35 +++++++------ public/reading-files | 39 ++++++++------- public/recursion | 21 ++++---- public/regular-expressions | 49 ++++++++++--------- public/select | 27 +++++----- public/sha1-hashes | 31 ++++++------ public/signals | 27 +++++----- public/site.css | 8 ++- public/site.js | 17 +++++++ public/slices | 43 ++++++++-------- public/sorting | 25 +++++----- public/sorting-by-functions | 25 +++++----- public/spawning-processes | 35 +++++++------ public/stateful-goroutines | 37 +++++++------- public/string-formatting | 65 +++++++++++++------------ public/string-functions | 29 ++++++----- public/structs | 41 ++++++++-------- public/switch | 27 +++++----- public/temporary-files-and-directories | 35 +++++++------ public/tickers | 23 +++++---- public/time | 37 +++++++------- public/time-formatting-parsing | 29 ++++++----- public/timeouts | 27 +++++----- public/timers | 25 +++++----- public/url-parsing | 33 +++++++------ public/values | 25 +++++----- public/variables | 29 ++++++----- public/variadic-functions | 27 +++++----- public/waitgroups | 33 +++++++------ public/worker-pools | 31 ++++++------ public/writing-files | 43 ++++++++-------- templates/example.tmpl | 6 +-- templates/site.css | 5 +- tools/generate.go | 10 ++-- 78 files changed, 1299 insertions(+), 1057 deletions(-) create mode 100644 public/clipboard.png create mode 100644 public/site.js diff --git a/public/arrays b/public/arrays index b9f36ce..d8273e0 100644 --- a/public/arrays +++ b/public/arrays @@ -33,7 +33,7 @@ specific length.

    - + @@ -42,10 +42,8 @@ specific length.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -57,7 +55,7 @@ specific length.

    -
    import "fmt"
    +          
    import "fmt"
     
    @@ -69,7 +67,7 @@ specific length.

    -
    func main() {
    +          
    func main() {
     
    @@ -85,7 +83,7 @@ zero-valued, which for ints means 0s.

    -
        var a [5]int
    +          
        var a [5]int
         fmt.Println("emp:", a)
     
    @@ -101,7 +99,7 @@ zero-valued, which for ints means 0s.

    -
        a[4] = 100
    +          
        a[4] = 100
         fmt.Println("set:", a)
         fmt.Println("get:", a[4])
     
    @@ -116,7 +114,7 @@ zero-valued, which for ints means 0s.

    -
        fmt.Println("len:", len(a))
    +          
        fmt.Println("len:", len(a))
     
    @@ -130,7 +128,7 @@ in one line.

    -
        b := [5]int{1, 2, 3, 4, 5}
    +          
        b := [5]int{1, 2, 3, 4, 5}
         fmt.Println("dcl:", b)
     
    @@ -146,7 +144,7 @@ structures.

    -
        var twoD [2][3]int
    +          
        var twoD [2][3]int
         for i := 0; i < 2; i++ {
             for j := 0; j < 3; j++ {
                 twoD[i][j] = i + j
    @@ -171,7 +169,7 @@ when printed with fmt.Println.

    -
    $ go run arrays.go
    +          
    $ go run arrays.go
     emp: [0 0 0 0 0]
     set: [0 0 0 0 100]
     get: 100
    @@ -191,7 +189,7 @@ typical Go. We’ll look at slices next.

    - + @@ -206,5 +204,10 @@ typical Go. We’ll look at slices next.

    by Mark McGranaghan | source | license

    + + diff --git a/public/atomic-counters b/public/atomic-counters index c4df533..b2e006e 100644 --- a/public/atomic-counters +++ b/public/atomic-counters @@ -37,7 +37,7 @@ counters accessed by multiple goroutines.

    - + @@ -46,10 +46,8 @@ counters accessed by multiple goroutines.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -61,7 +59,7 @@ counters accessed by multiple goroutines.

    -
    import "fmt"
    +          
    import "fmt"
     import "time"
     import "sync/atomic"
     
    @@ -75,7 +73,7 @@ counters accessed by multiple goroutines.

    -
    func main() {
    +          
    func main() {
     
    @@ -89,7 +87,7 @@ counters accessed by multiple goroutines.

    -
        var ops uint64
    +          
        var ops uint64
     
    @@ -104,7 +102,7 @@ once a millisecond.

    -
        for i := 0; i < 50; i++ {
    +          
        for i := 0; i < 50; i++ {
             go func() {
                 for {
     
    @@ -122,7 +120,7 @@ address of our ops counter with the -
                    atomic.AddUint64(&ops, 1)
    +          
                    atomic.AddUint64(&ops, 1)
     
    @@ -135,7 +133,7 @@ address of our ops counter with the -
                    time.Sleep(time.Millisecond)
    +          
                    time.Sleep(time.Millisecond)
                 }
             }()
         }
    @@ -151,7 +149,7 @@ address of our ops counter with the
               
               
                 
    -            
        time.Sleep(time.Second)
    +          
        time.Sleep(time.Second)
     
    @@ -169,7 +167,7 @@ fetch the value.

    -
        opsFinal := atomic.LoadUint64(&ops)
    +          
        opsFinal := atomic.LoadUint64(&ops)
         fmt.Println("ops:", opsFinal)
     }
     
    @@ -189,7 +187,7 @@ fetch the value.

    -
    $ go run atomic-counters.go
    +          
    $ go run atomic-counters.go
     ops: 41419
     
    @@ -204,7 +202,7 @@ state.

    - + @@ -219,5 +217,10 @@ state.

    by Mark McGranaghan | source | license

    + + diff --git a/public/base64-encoding b/public/base64-encoding index fdbaaed..d60fe9d 100644 --- a/public/base64-encoding +++ b/public/base64-encoding @@ -33,7 +33,7 @@ encoding/decoding.

    - + @@ -42,10 +42,8 @@ encoding/decoding.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -60,7 +58,7 @@ save us some space below.

    -
    import b64 "encoding/base64"
    +          
    import b64 "encoding/base64"
     import "fmt"
     
    @@ -73,7 +71,7 @@ save us some space below.

    -
    func main() {
    +          
    func main() {
     
    @@ -86,7 +84,7 @@ save us some space below.

    -
        data := "abc123!?$*&()'-=@~"
    +          
        data := "abc123!?$*&()'-=@~"
     
    @@ -102,7 +100,7 @@ convert our string to that type.

    -
        sEnc := b64.StdEncoding.EncodeToString([]byte(data))
    +          
        sEnc := b64.StdEncoding.EncodeToString([]byte(data))
         fmt.Println(sEnc)
     
    @@ -118,7 +116,7 @@ well-formed.

    -
        sDec, _ := b64.StdEncoding.DecodeString(sEnc)
    +          
        sDec, _ := b64.StdEncoding.DecodeString(sEnc)
         fmt.Println(string(sDec))
         fmt.Println()
     
    @@ -134,7 +132,7 @@ format.

    -
        uEnc := b64.URLEncoding.EncodeToString([]byte(data))
    +          
        uEnc := b64.URLEncoding.EncodeToString([]byte(data))
         fmt.Println(uEnc)
         uDec, _ := b64.URLEncoding.DecodeString(uEnc)
         fmt.Println(string(uDec))
    @@ -157,7 +155,7 @@ but they both decode to the original string as desired.

    -
    $ go run base64-encoding.go
    +          
    $ go run base64-encoding.go
     YWJjMTIzIT8kKiYoKSctPUB+
     abc123!?$*&()'-=@~
     
    @@ -171,7 +169,7 @@ but they both decode to the original string as desired.

    -
    YWJjMTIzIT8kKiYoKSctPUB-
    +          
    YWJjMTIzIT8kKiYoKSctPUB-
     abc123!?$*&()'-=@~
     
    @@ -189,5 +187,10 @@ but they both decode to the original string as desired.

    by Mark McGranaghan | source | license

    + + diff --git a/public/channel-buffering b/public/channel-buffering index a11749b..eab9a6e 100644 --- a/public/channel-buffering +++ b/public/channel-buffering @@ -37,7 +37,7 @@ those values.

    - + @@ -46,10 +46,8 @@ those values.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -61,7 +59,7 @@ those values.

    -
    import "fmt"
    +          
    import "fmt"
     
    @@ -73,7 +71,7 @@ those values.

    -
    func main() {
    +          
    func main() {
     
    @@ -87,7 +85,7 @@ those values.

    -
        messages := make(chan string, 2)
    +          
        messages := make(chan string, 2)
     
    @@ -102,7 +100,7 @@ concurrent receive.

    -
        messages <- "buffered"
    +          
        messages <- "buffered"
         messages <- "channel"
     
    @@ -116,7 +114,7 @@ concurrent receive.

    -
        fmt.Println(<-messages)
    +          
        fmt.Println(<-messages)
         fmt.Println(<-messages)
     }
     
    @@ -134,7 +132,7 @@ concurrent receive.

    -
    $ go run channel-buffering.go 
    +          
    $ go run channel-buffering.go 
     buffered
     channel
     
    @@ -153,5 +151,10 @@ concurrent receive.

    by Mark McGranaghan | source | license

    + + diff --git a/public/channel-directions b/public/channel-directions index 2c95a14..fbbe7b5 100644 --- a/public/channel-directions +++ b/public/channel-directions @@ -35,7 +35,7 @@ the program.

    - + @@ -44,10 +44,8 @@ the program.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -59,7 +57,7 @@ the program.

    -
    import "fmt"
    +          
    import "fmt"
     
    @@ -74,7 +72,7 @@ receive on this channel.

    -
    func ping(pings chan<- string, msg string) {
    +          
    func ping(pings chan<- string, msg string) {
         pings <- msg
     }
     
    @@ -90,7 +88,7 @@ receive on this channel.

    -
    func pong(pings <-chan string, pongs chan<- string) {
    +          
    func pong(pings <-chan string, pongs chan<- string) {
         msg := <-pings
         pongs <- msg
     }
    @@ -105,7 +103,7 @@ receive on this channel.

    -
    func main() {
    +          
    func main() {
         pings := make(chan string, 1)
         pongs := make(chan string, 1)
         ping(pings, "passed message")
    @@ -127,7 +125,7 @@ receive on this channel.

    -
    $ go run channel-directions.go
    +          
    $ go run channel-directions.go
     passed message
     
    @@ -145,5 +143,10 @@ receive on this channel.

    by Mark McGranaghan | source | license

    + + diff --git a/public/channel-synchronization b/public/channel-synchronization index 595487d..16de092 100644 --- a/public/channel-synchronization +++ b/public/channel-synchronization @@ -36,7 +36,7 @@ you may prefer to use a WaitGroup.

    - + @@ -45,10 +45,8 @@ you may prefer to use a WaitGroup.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -60,7 +58,7 @@ you may prefer to use a WaitGroup.

    -
    import "fmt"
    +          
    import "fmt"
     import "time"
     
    @@ -76,7 +74,7 @@ goroutine that this function’s work is done.

    -
    func worker(done chan bool) {
    +          
    func worker(done chan bool) {
         fmt.Print("working...")
         time.Sleep(time.Second)
         fmt.Println("done")
    @@ -92,7 +90,7 @@ goroutine that this function’s work is done.

    -
        done <- true
    +          
        done <- true
     }
     
    @@ -105,7 +103,7 @@ goroutine that this function’s work is done.

    -
    func main() {
    +          
    func main() {
     
    @@ -119,7 +117,7 @@ notify on.

    -
        done := make(chan bool, 1)
    +          
        done := make(chan bool, 1)
         go worker(done)
     
    @@ -134,7 +132,7 @@ worker on the channel.

    -
        <-done
    +          
        <-done
     }
     
    @@ -151,7 +149,7 @@ worker on the channel.

    -
    $ go run channel-synchronization.go      
    +          
    $ go run channel-synchronization.go      
     working...done                  
     
    @@ -167,7 +165,7 @@ started.

    - + @@ -182,5 +180,10 @@ started.

    by Mark McGranaghan | source | license

    + + diff --git a/public/channels b/public/channels index 25995b6..704c9f4 100644 --- a/public/channels +++ b/public/channels @@ -35,7 +35,7 @@ goroutine.

    - + @@ -44,10 +44,8 @@ goroutine.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -59,7 +57,7 @@ goroutine.

    -
    import "fmt"
    +          
    import "fmt"
     
    @@ -71,7 +69,7 @@ goroutine.

    -
    func main() {
    +          
    func main() {
     
    @@ -85,7 +83,7 @@ Channels are typed by the values they convey.

    -
        messages := make(chan string)
    +          
        messages := make(chan string)
     
    @@ -100,7 +98,7 @@ channel we made above, from a new goroutine.

    -
        go func() { messages <- "ping" }()
    +          
        go func() { messages <- "ping" }()
     
    @@ -115,7 +113,7 @@ we sent above and print it out.

    -
        msg := <-messages
    +          
        msg := <-messages
         fmt.Println(msg)
     }
     
    @@ -136,7 +134,7 @@ our channel.

    -
    $ go run channels.go 
    +          
    $ go run channels.go 
     ping
     
    @@ -153,7 +151,7 @@ message without having to use any other synchronization.

    - + @@ -168,5 +166,10 @@ message without having to use any other synchronization.

    by Mark McGranaghan | source | license

    + + diff --git a/public/clipboard.png b/public/clipboard.png new file mode 100644 index 0000000000000000000000000000000000000000..0e262fec70a6efb70c8c03c67e4cfea0b230d5ab GIT binary patch literal 488 zcmVP)vs0+u6@oUjF!il?f%*EGIz@kHuY0Jz-x!^TP`0I+j#4M3yOun`C$0GLY;0}N!> z@?HR!^uMdY?T0(;4FS(8K`+4e{$(p$r=i9GO#pFzR`vm!Q+6ka*jT(SNo?u|Lt!d6 zSGM3_C`@*F72plf0fhAVfD0h{U)v;(fF70L6Q}@Ds{#v|#T@yq_0~Ezo&p%OgcqtH ze?6R7A=SQhZwYS^XuznG2EkC6sp+&;0f49d3Xi}@mm2i7x*%siPzKUY8ptjfQgpvc zU|4PGLW39J38<u`lTp#J+Cizm8Ecyw8bkh1}(e_fNd33!{0 eZzG - + @@ -43,10 +43,8 @@ completion to the channel’s receivers.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -58,7 +56,7 @@ completion to the channel’s receivers.

    -
    import "fmt"
    +          
    import "fmt"
     
    @@ -74,7 +72,7 @@ the worker we’ll close the jobs channel.

    -
    func main() {
    +          
    func main() {
         jobs := make(chan int, 5)
         done := make(chan bool)
     
    @@ -95,7 +93,7 @@ all our jobs.

    -
        go func() {
    +          
        go func() {
             for {
                 j, more := <-jobs
                 if more {
    @@ -120,7 +118,7 @@ channel, then closes it.

    -
        for j := 1; j <= 3; j++ {
    +          
        for j := 1; j <= 3; j++ {
             jobs <- j
             fmt.Println("sent job", j)
         }
    @@ -140,7 +138,7 @@ we saw earlier.

    -
        <-done
    +          
        <-done
     }
     
    @@ -157,7 +155,7 @@ we saw earlier.

    -
    $ go run closing-channels.go 
    +          
    $ go run closing-channels.go 
     sent job 1
     received job 1
     sent job 2
    @@ -179,7 +177,7 @@ example: range over channels.

    - + @@ -194,5 +192,10 @@ example: range over channels.

    by Mark McGranaghan | source | license

    + + diff --git a/public/closures b/public/closures index 0bb3852..36d6dc4 100644 --- a/public/closures +++ b/public/closures @@ -35,7 +35,7 @@ a function inline without having to name it.

    - + @@ -44,10 +44,8 @@ a function inline without having to name it.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -59,7 +57,7 @@ a function inline without having to name it.

    -
    import "fmt"
    +          
    import "fmt"
     
    @@ -75,7 +73,7 @@ form a closure.

    -
    func intSeq() func() int {
    +          
    func intSeq() func() int {
         i := 0
         return func() int {
             i++
    @@ -93,7 +91,7 @@ form a closure.

    -
    func main() {
    +          
    func main() {
     
    @@ -109,7 +107,7 @@ we call nextInt.

    -
        nextInt := intSeq()
    +          
        nextInt := intSeq()
     
    @@ -123,7 +121,7 @@ a few times.

    -
        fmt.Println(nextInt())
    +          
        fmt.Println(nextInt())
         fmt.Println(nextInt())
         fmt.Println(nextInt())
     
    @@ -139,7 +137,7 @@ particular function, create and test a new one.

    -
        newInts := intSeq()
    +          
        newInts := intSeq()
         fmt.Println(newInts())
     }
     
    @@ -157,7 +155,7 @@ particular function, create and test a new one.

    -
    $ go run closures.go
    +          
    $ go run closures.go
     1
     2
     3
    @@ -175,7 +173,7 @@ recursion.

    - + @@ -190,5 +188,10 @@ recursion.

    by Mark McGranaghan | source | license

    + + diff --git a/public/collection-functions b/public/collection-functions index fce4ddd..2acb092 100644 --- a/public/collection-functions +++ b/public/collection-functions @@ -35,7 +35,7 @@ collection with a custom function.

    - + @@ -50,7 +50,7 @@ your program and data types.

    - + @@ -66,7 +66,7 @@ helper function.

    - + @@ -75,10 +75,8 @@ helper function.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -90,7 +88,7 @@ helper function.

    -
    import "strings"
    +          
    import "strings"
     import "fmt"
     
    @@ -105,7 +103,7 @@ helper function.

    -
    func Index(vs []string, t string) int {
    +          
    func Index(vs []string, t string) int {
         for i, v := range vs {
             if v == t {
                 return i
    @@ -126,7 +124,7 @@ slice.

    -
    func Include(vs []string, t string) bool {
    +          
    func Include(vs []string, t string) bool {
         return Index(vs, t) >= 0
     }
     
    @@ -142,7 +140,7 @@ satisfies the predicate f.

    -
    func Any(vs []string, f func(string) bool) bool {
    +          
    func Any(vs []string, f func(string) bool) bool {
         for _, v := range vs {
             if f(v) {
                 return true
    @@ -163,7 +161,7 @@ satisfy the predicate f.

    -
    func All(vs []string, f func(string) bool) bool {
    +          
    func All(vs []string, f func(string) bool) bool {
         for _, v := range vs {
             if !f(v) {
                 return false
    @@ -184,7 +182,7 @@ slice that satisfy the predicate f.

    -
    func Filter(vs []string, f func(string) bool) []string {
    +          
    func Filter(vs []string, f func(string) bool) []string {
         vsf := make([]string, 0)
         for _, v := range vs {
             if f(v) {
    @@ -206,7 +204,7 @@ the function f to each string in the original slice.

    -
    func Map(vs []string, f func(string) string) []string {
    +          
    func Map(vs []string, f func(string) string) []string {
         vsm := make([]string, len(vs))
         for i, v := range vs {
             vsm[i] = f(v)
    @@ -224,7 +222,7 @@ the function f to each string in the original slice.

    -
    func main() {
    +          
    func main() {
     
    @@ -237,7 +235,7 @@ the function f to each string in the original slice.

    -
        var strs = []string{"peach", "apple", "pear", "plum"}
    +          
        var strs = []string{"peach", "apple", "pear", "plum"}
     
    @@ -249,7 +247,7 @@ the function f to each string in the original slice.

    -
        fmt.Println(Index(strs, "pear"))
    +          
        fmt.Println(Index(strs, "pear"))
     
    @@ -261,7 +259,7 @@ the function f to each string in the original slice.

    -
        fmt.Println(Include(strs, "grape"))
    +          
        fmt.Println(Include(strs, "grape"))
     
    @@ -273,7 +271,7 @@ the function f to each string in the original slice.

    -
        fmt.Println(Any(strs, func(v string) bool {
    +          
        fmt.Println(Any(strs, func(v string) bool {
             return strings.HasPrefix(v, "p")
         }))
     
    @@ -287,7 +285,7 @@ the function f to each string in the original slice.

    -
        fmt.Println(All(strs, func(v string) bool {
    +          
        fmt.Println(All(strs, func(v string) bool {
             return strings.HasPrefix(v, "p")
         }))
     
    @@ -301,7 +299,7 @@ the function f to each string in the original slice.

    -
        fmt.Println(Filter(strs, func(v string) bool {
    +          
        fmt.Println(Filter(strs, func(v string) bool {
             return strings.Contains(v, "e")
         }))
     
    @@ -318,7 +316,7 @@ type.

    -
        fmt.Println(Map(strs, strings.ToUpper))
    +          
        fmt.Println(Map(strs, strings.ToUpper))
     
    @@ -330,7 +328,7 @@ type.

    -
    }
    +          
    }
     
    @@ -346,7 +344,7 @@ type.

    -
    $ go run collection-functions.go 
    +          
    $ go run collection-functions.go 
     2
     false
     true
    @@ -369,5 +367,10 @@ type.

    by Mark McGranaghan | source | license

    + + diff --git a/public/command-line-arguments b/public/command-line-arguments index fc80282..1cb6ffd 100644 --- a/public/command-line-arguments +++ b/public/command-line-arguments @@ -35,7 +35,7 @@ For example, go run hello.go uses run and - + @@ -44,10 +44,8 @@ For example, go run hello.go uses run and - - - -
    package main
    +            
    +          
    package main
     
    @@ -59,7 +57,7 @@ For example, go run hello.go uses run and -
    import "os"
    +          
    import "os"
     import "fmt"
     
    @@ -72,7 +70,7 @@ For example, go run hello.go uses run and -
    func main() {
    +          
    func main() {
     
    @@ -88,7 +86,7 @@ holds the arguments to the program.

    -
        argsWithProg := os.Args
    +          
        argsWithProg := os.Args
         argsWithoutProg := os.Args[1:]
     
    @@ -102,7 +100,7 @@ holds the arguments to the program.

    -
        arg := os.Args[3]
    +          
        arg := os.Args[3]
     
    @@ -114,7 +112,7 @@ holds the arguments to the program.

    -
        fmt.Println(argsWithProg)
    +          
        fmt.Println(argsWithProg)
         fmt.Println(argsWithoutProg)
         fmt.Println(arg)
     }
    @@ -135,7 +133,7 @@ build a binary with go build first.

    -
    $ go build command-line-arguments.go
    +          
    $ go build command-line-arguments.go
     $ ./command-line-arguments a b c d
     [./command-line-arguments a b c d]       
     [a b c d]
    @@ -153,7 +151,7 @@ with flags.

    - + @@ -168,5 +166,10 @@ with flags.

    by Mark McGranaghan | source | license

    + + diff --git a/public/command-line-flags b/public/command-line-flags index 32c7abe..b2230fa 100644 --- a/public/command-line-flags +++ b/public/command-line-flags @@ -35,7 +35,7 @@ command-line flag.

    - + @@ -44,10 +44,8 @@ command-line flag.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -62,7 +60,7 @@ implement our example command-line program.

    -
    import "flag"
    +          
    import "flag"
     import "fmt"
     
    @@ -75,7 +73,7 @@ implement our example command-line program.

    -
    func main() {
    +          
    func main() {
     
    @@ -93,7 +91,7 @@ we’ll see how to use this pointer below.

    -
        wordPtr := flag.String("word", "foo", "a string")
    +          
        wordPtr := flag.String("word", "foo", "a string")
     
    @@ -107,7 +105,7 @@ similar approach to the word flag.

    -
        numbPtr := flag.Int("numb", 42, "an int")
    +          
        numbPtr := flag.Int("numb", 42, "an int")
         boolPtr := flag.Bool("fork", false, "a bool")
     
    @@ -124,7 +122,7 @@ declaration function.

    -
        var svar string
    +          
        var svar string
         flag.StringVar(&svar, "svar", "bar", "a string var")
     
    @@ -139,7 +137,7 @@ to execute the command-line parsing.

    -
        flag.Parse()
    +          
        flag.Parse()
     
    @@ -155,7 +153,7 @@ to get the actual option values.

    -
        fmt.Println("word:", *wordPtr)
    +          
        fmt.Println("word:", *wordPtr)
         fmt.Println("numb:", *numbPtr)
         fmt.Println("fork:", *boolPtr)
         fmt.Println("svar:", svar)
    @@ -179,7 +177,7 @@ binary directly.

    -
    $ go build command-line-flags.go
    +          
    $ go build command-line-flags.go
     
    @@ -193,7 +191,7 @@ all flags.

    -
    $ ./command-line-flags -word=opt -numb=7 -fork -svar=flag
    +          
    $ ./command-line-flags -word=opt -numb=7 -fork -svar=flag
     word: opt
     numb: 7
     fork: true
    @@ -212,7 +210,7 @@ their default values.

    -
    $ ./command-line-flags -word=opt
    +          
    $ ./command-line-flags -word=opt
     word: opt
     numb: 42
     fork: false
    @@ -231,7 +229,7 @@ any flags.

    -
    $ ./command-line-flags -word=opt a1 a2 a3
    +          
    $ ./command-line-flags -word=opt a1 a2 a3
     word: opt
     ...
     tail: [a1 a2 a3]
    @@ -249,7 +247,7 @@ will be interpreted as positional arguments).

    -
    $ ./command-line-flags -word=opt a1 a2 a3 -numb=7
    +          
    $ ./command-line-flags -word=opt a1 a2 a3 -numb=7
     word: opt
     numb: 42
     fork: false
    @@ -268,7 +266,7 @@ generated help text for the command-line program.

    -
    $ ./command-line-flags -h
    +          
    $ ./command-line-flags -h
     Usage of ./command-line-flags:
       -fork=false: a bool
       -numb=42: an int
    @@ -288,7 +286,7 @@ and show the help text again.

    -
    $ ./command-line-flags -wat
    +          
    $ ./command-line-flags -wat
     flag provided but not defined: -wat
     Usage of ./command-line-flags:
     ...
    @@ -308,5 +306,10 @@ and show the help text again.

    by Mark McGranaghan | source | license

    + + diff --git a/public/command-line-subcommands b/public/command-line-subcommands index 333e048..f5add93 100644 --- a/public/command-line-subcommands +++ b/public/command-line-subcommands @@ -37,7 +37,7 @@ subcommands that have their own flags.

    - + @@ -46,10 +46,8 @@ subcommands that have their own flags.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -61,7 +59,7 @@ subcommands that have their own flags.

    -
    import (
    +          
    import (
         "flag"
         "fmt"
         "os"
    @@ -77,7 +75,7 @@ subcommands that have their own flags.

    -
    func main() {
    +          
    func main() {
     
    @@ -92,7 +90,7 @@ for this subcommand.

    -
        fooCmd := flag.NewFlagSet("foo", flag.ExitOnError)
    +          
        fooCmd := flag.NewFlagSet("foo", flag.ExitOnError)
         fooEnable := fooCmd.Bool("enable", false, "enable")
         fooName := fooCmd.String("name", "", "name")
     
    @@ -108,7 +106,7 @@ supported flags.

    -
        barCmd := flag.NewFlagSet("bar", flag.ExitOnError)
    +          
        barCmd := flag.NewFlagSet("bar", flag.ExitOnError)
         barLevel := barCmd.Int("level", 0, "level")
     
    @@ -123,7 +121,7 @@ to the program.

    -
        if len(os.Args) < 2 {
    +          
        if len(os.Args) < 2 {
             fmt.Println("expected 'foo' or 'bar' subcommands")
             os.Exit(1)
         }
    @@ -139,7 +137,7 @@ to the program.

    -
        switch os.Args[1] {
    +          
        switch os.Args[1] {
     
    @@ -153,7 +151,7 @@ have access to trailing positional arguments.

    -
        case "foo":
    +          
        case "foo":
             fooCmd.Parse(os.Args[2:])
             fmt.Println("subcommand 'foo'")
             fmt.Println("  enable:", *fooEnable)
    @@ -184,7 +182,7 @@ have access to trailing positional arguments.

    -
    $ go build command-line-subcommands.go 
    +          
    $ go build command-line-subcommands.go 
     
    @@ -197,7 +195,7 @@ have access to trailing positional arguments.

    -
    $ ./command-line-subcommands foo -enable -name=joe a1 a2
    +          
    $ ./command-line-subcommands foo -enable -name=joe a1 a2
     subcommand 'foo'
       enable: true
       name: joe
    @@ -214,7 +212,7 @@ have access to trailing positional arguments.

    -
    $ ./command-line-subcommands bar -level 8 a1
    +          
    $ ./command-line-subcommands bar -level 8 a1
     subcommand 'bar'
       level: 8
       tail: [a1]
    @@ -230,7 +228,7 @@ have access to trailing positional arguments.

    -
    $ ./command-line-subcommands bar -enable a1
    +          
    $ ./command-line-subcommands bar -enable a1
     flag provided but not defined: -enable
     Usage of bar:
       -level int
    @@ -248,7 +246,7 @@ way to parameterize programs.

    - + @@ -263,5 +261,10 @@ way to parameterize programs.

    by Mark McGranaghan | source | license

    + + diff --git a/public/constants b/public/constants index 0609217..17379bf 100644 --- a/public/constants +++ b/public/constants @@ -33,7 +33,7 @@ and numeric values.

    - + @@ -42,10 +42,8 @@ and numeric values.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -57,7 +55,7 @@ and numeric values.

    -
    import "fmt"
    +          
    import "fmt"
     import "math"
     
    @@ -71,7 +69,7 @@ and numeric values.

    -
    const s string = "constant"
    +          
    const s string = "constant"
     
    @@ -83,7 +81,7 @@ and numeric values.

    -
    func main() {
    +          
    func main() {
         fmt.Println(s)
     
    @@ -98,7 +96,7 @@ statement can.

    -
        const n = 500000000
    +          
        const n = 500000000
     
    @@ -112,7 +110,7 @@ arbitrary precision.

    -
        const d = 3e20 / n
    +          
        const d = 3e20 / n
         fmt.Println(d)
     
    @@ -127,7 +125,7 @@ one, such as by an explicit conversion.

    -
        fmt.Println(int64(d))
    +          
        fmt.Println(int64(d))
     
    @@ -143,7 +141,7 @@ assignment or function call. For example, here -
        fmt.Println(math.Sin(n))
    +          
        fmt.Println(math.Sin(n))
     }
     
    @@ -160,7 +158,7 @@ assignment or function call. For example, here -
    $ go run constant.go 
    +          
    $ go run constant.go 
     constant
     6e+11
     600000000000
    @@ -181,5 +179,10 @@ assignment or function call. For example, here
             by Mark McGranaghan | source | license
           

    + + diff --git a/public/defer b/public/defer index 42299e5..6c62c64 100644 --- a/public/defer +++ b/public/defer @@ -35,7 +35,7 @@ purposes of cleanup. defer is often used where e.g. - + @@ -44,10 +44,8 @@ purposes of cleanup. defer is often used where e.g. - - - -
    package main
    +            
    +          
    package main
     
    @@ -59,7 +57,7 @@ purposes of cleanup. defer is often used where e.g. -
    import "fmt"
    +          
    import "fmt"
     import "os"
     
    @@ -75,7 +73,7 @@ do that with defer.

    -
    func main() {
    +          
    func main() {
     
    @@ -92,7 +90,7 @@ of the enclosing function (main), after -
        f := createFile("/tmp/defer.txt")
    +          
        f := createFile("/tmp/defer.txt")
         defer closeFile(f)
         writeFile(f)
     }
    @@ -107,7 +105,7 @@ of the enclosing function (main), after
               
               
                 
    -            
    func createFile(p string) *os.File {
    +          
    func createFile(p string) *os.File {
         fmt.Println("creating")
         f, err := os.Create(p)
         if err != nil {
    @@ -126,7 +124,7 @@ of the enclosing function (main), after
               
               
                 
    -            
    func writeFile(f *os.File) {
    +          
    func writeFile(f *os.File) {
         fmt.Println("writing")
         fmt.Fprintln(f, "data")
     
    @@ -140,7 +138,7 @@ of the enclosing function (main), after -
    }
    +          
    }
     
    @@ -154,7 +152,7 @@ file, even in a deferred function.

    -
    func closeFile(f *os.File) {
    +          
    func closeFile(f *os.File) {
         fmt.Println("closing")
         err := f.Close()
     
    @@ -168,7 +166,7 @@ file, even in a deferred function.

    -
        if err != nil {
    +          
        if err != nil {
             fmt.Fprintf(os.Stderr, "error: %v\n", err)
             os.Exit(1)
         }
    @@ -190,7 +188,7 @@ after being written.

    -
    $ go run defer.go
    +          
    $ go run defer.go
     creating
     writing
     closing
    @@ -210,5 +208,10 @@ after being written.

    by Mark McGranaghan | source | license

    + + diff --git a/public/directories b/public/directories index beb7a7e..5cfc5b0 100644 --- a/public/directories +++ b/public/directories @@ -33,7 +33,7 @@ - + @@ -42,10 +42,8 @@ - - - -
    package main
    +            
    +          
    package main
     
    @@ -57,7 +55,7 @@ -
    import (
    +          
    import (
         "fmt"
         "io/ioutil"
         "os"
    @@ -74,7 +72,7 @@
               
               
                 
    -            
    func check(e error) {
    +          
    func check(e error) {
         if e != nil {
             panic(e)
         }
    @@ -90,7 +88,7 @@
               
               
                 
    -            
    func main() {
    +          
    func main() {
     
    @@ -104,7 +102,7 @@ directory.

    -
        err := os.Mkdir("subdir", 0755)
    +          
        err := os.Mkdir("subdir", 0755)
         check(err)
     
    @@ -121,7 +119,7 @@ will delete a whole directory tree (similarly to -
        defer os.RemoveAll("subdir")
    +          
        defer os.RemoveAll("subdir")
     
    @@ -134,7 +132,7 @@ will delete a whole directory tree (similarly to -
        createEmptyFile := func(name string) {
    +          
        createEmptyFile := func(name string) {
             d := []byte("")
             check(ioutil.WriteFile(name, d, 0644))
         }
    @@ -149,7 +147,7 @@ will delete a whole directory tree (similarly to
               
               
                 
    -            
        createEmptyFile("subdir/file1")
    +          
        createEmptyFile("subdir/file1")
     
    @@ -164,7 +162,7 @@ command-line mkdir -p.

    -
        err = os.MkdirAll("subdir/parent/child", 0755)
    +          
        err = os.MkdirAll("subdir/parent/child", 0755)
         check(err)
     
    @@ -177,7 +175,7 @@ command-line mkdir -p.

    -
        createEmptyFile("subdir/parent/file2")
    +          
        createEmptyFile("subdir/parent/file2")
         createEmptyFile("subdir/parent/file3")
         createEmptyFile("subdir/parent/child/file4")
     
    @@ -193,7 +191,7 @@ slice of os.FileInfo objects.

    -
        c, err := ioutil.ReadDir("subdir/parent")
    +          
        c, err := ioutil.ReadDir("subdir/parent")
         check(err)
     
    @@ -206,7 +204,7 @@ slice of os.FileInfo objects.

    -
        fmt.Println("Listing subdir/parent")
    +          
        fmt.Println("Listing subdir/parent")
         for _, entry := range c {
             fmt.Println(" ", entry.Name(), entry.IsDir())
         }
    @@ -223,7 +221,7 @@ similarly to cd.

    -
        err = os.Chdir("subdir/parent/child")
    +          
        err = os.Chdir("subdir/parent/child")
         check(err)
     
    @@ -238,7 +236,7 @@ when listing the current directory.

    -
        c, err = ioutil.ReadDir(".")
    +          
        c, err = ioutil.ReadDir(".")
         check(err)
     
    @@ -251,7 +249,7 @@ when listing the current directory.

    -
        fmt.Println("Listing subdir/parent/child")
    +          
        fmt.Println("Listing subdir/parent/child")
         for _, entry := range c {
             fmt.Println(" ", entry.Name(), entry.IsDir())
         }
    @@ -267,7 +265,7 @@ when listing the current directory.

    -
        err = os.Chdir("../../..")
    +          
        err = os.Chdir("../../..")
         check(err)
     
    @@ -284,7 +282,7 @@ directory visited.

    -
        fmt.Println("Visiting subdir")
    +          
        fmt.Println("Visiting subdir")
         err = filepath.Walk("subdir", visit)
     }
     
    @@ -300,7 +298,7 @@ recursively by filepath.Walk.

    -
    func visit(p string, info os.FileInfo, err error) error {
    +          
    func visit(p string, info os.FileInfo, err error) error {
         if err != nil {
             return err
         }
    @@ -322,7 +320,7 @@ recursively by filepath.Walk.

    -
    $ go run directories.go
    +          
    $ go run directories.go
     Listing subdir/parent
       child true
       file2 false
    @@ -353,5 +351,10 @@ recursively by filepath.Walk.

    by Mark McGranaghan | source | license

    + + diff --git a/public/environment-variables b/public/environment-variables index 56a1cc3..c452feb 100644 --- a/public/environment-variables +++ b/public/environment-variables @@ -35,7 +35,7 @@ Let’s look at how to set, get, and list environment variables.

    - + @@ -44,10 +44,8 @@ Let’s look at how to set, get, and list environment variables.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -59,7 +57,7 @@ Let’s look at how to set, get, and list environment variables.

    -
    import "os"
    +          
    import "os"
     import "strings"
     import "fmt"
     
    @@ -73,7 +71,7 @@ Let’s look at how to set, get, and list environment variables.

    -
    func main() {
    +          
    func main() {
     
    @@ -89,7 +87,7 @@ environment.

    -
        os.Setenv("FOO", "1")
    +          
        os.Setenv("FOO", "1")
         fmt.Println("FOO:", os.Getenv("FOO"))
         fmt.Println("BAR:", os.Getenv("BAR"))
     
    @@ -107,7 +105,7 @@ get the key and value. Here we print all the keys.

    -
        fmt.Println()
    +          
        fmt.Println()
         for _, e := range os.Environ() {
             pair := strings.Split(e, "=")
             fmt.Println(pair[0])
    @@ -131,7 +129,7 @@ for FOO that we set in the program, but that
               
               
                 
    -            
    $ go run environment-variables.go
    +          
    $ go run environment-variables.go
     FOO: 1
     BAR: 
     
    @@ -147,7 +145,7 @@ particular machine.

    -
    TERM_PROGRAM
    +          
    TERM_PROGRAM
     PATH
     SHELL
     ...
    @@ -164,7 +162,7 @@ program picks that value up.

    -
    $ BAR=2 go run environment-variables.go
    +          
    $ BAR=2 go run environment-variables.go
     FOO: 1
     BAR: 2
     ...
    @@ -184,5 +182,10 @@ program picks that value up.

    by Mark McGranaghan | source | license

    + + diff --git a/public/epoch b/public/epoch index 60ecde3..644ef79 100644 --- a/public/epoch +++ b/public/epoch @@ -35,7 +35,7 @@ Here’s how to do it in Go.

    - + @@ -44,10 +44,8 @@ Here’s how to do it in Go.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -59,7 +57,7 @@ Here’s how to do it in Go.

    -
    import "fmt"
    +          
    import "fmt"
     import "time"
     
    @@ -72,7 +70,7 @@ Here’s how to do it in Go.

    -
    func main() {
    +          
    func main() {
     
    @@ -87,7 +85,7 @@ nanoseconds, respectively.

    -
        now := time.Now()
    +          
        now := time.Now()
         secs := now.Unix()
         nanos := now.UnixNano()
         fmt.Println(now)
    @@ -105,7 +103,7 @@ divide from nanoseconds.

    -
        millis := nanos / 1000000
    +          
        millis := nanos / 1000000
         fmt.Println(secs)
         fmt.Println(millis)
         fmt.Println(nanos)
    @@ -122,7 +120,7 @@ since the epoch into the corresponding time.

    -
        fmt.Println(time.Unix(secs, 0))
    +          
        fmt.Println(time.Unix(secs, 0))
         fmt.Println(time.Unix(0, nanos))
     }
     
    @@ -140,7 +138,7 @@ since the epoch into the corresponding time.

    -
    $ go run epoch.go 
    +          
    $ go run epoch.go 
     2012-10-31 16:13:58.292387 +0000 UTC
     1351700038
     1351700038292
    @@ -160,7 +158,7 @@ parsing and formatting.

    - + @@ -175,5 +173,10 @@ parsing and formatting.

    by Mark McGranaghan | source | license

    + + diff --git a/public/errors b/public/errors index a473c1b..b0ea98e 100644 --- a/public/errors +++ b/public/errors @@ -39,7 +39,7 @@ non-error tasks.

    - + @@ -48,10 +48,8 @@ non-error tasks.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -63,7 +61,7 @@ non-error tasks.

    -
    import "errors"
    +          
    import "errors"
     import "fmt"
     
    @@ -78,7 +76,7 @@ have type error, a built-in interface.

    -
    func f1(arg int) (int, error) {
    +          
    func f1(arg int) (int, error) {
         if arg == 42 {
     
    @@ -93,7 +91,7 @@ with the given error message.

    -
            return -1, errors.New("can't work with 42")
    +          
            return -1, errors.New("can't work with 42")
     
    @@ -105,7 +103,7 @@ with the given error message.

    -
        }
    +          
        }
     
    @@ -119,7 +117,7 @@ there was no error.

    -
        return arg + 3, nil
    +          
        return arg + 3, nil
     }
     
    @@ -136,7 +134,7 @@ to explicitly represent an argument error.

    -
    type argError struct {
    +          
    type argError struct {
         arg  int
         prob string
     }
    @@ -151,7 +149,7 @@ to explicitly represent an argument error.

    -
    func (e *argError) Error() string {
    +          
    func (e *argError) Error() string {
         return fmt.Sprintf("%d - %s", e.arg, e.prob)
     }
     
    @@ -165,7 +163,7 @@ to explicitly represent an argument error.

    -
    func f2(arg int) (int, error) {
    +          
    func f2(arg int) (int, error) {
         if arg == 42 {
     
    @@ -181,7 +179,7 @@ fields arg and prob.

    -
            return -1, &argError{arg, "can't work with it"}
    +          
            return -1, &argError{arg, "can't work with it"}
         }
         return arg + 3, nil
     }
    @@ -196,7 +194,7 @@ fields arg and prob.

    -
    func main() {
    +          
    func main() {
     
    @@ -212,7 +210,7 @@ idiom in Go code.

    -
        for _, i := range []int{7, 42} {
    +          
        for _, i := range []int{7, 42} {
             if r, e := f1(i); e != nil {
                 fmt.Println("f1 failed:", e)
             } else {
    @@ -241,7 +239,7 @@ assertion.

    -
        _, e := f2(42)
    +          
        _, e := f2(42)
         if ae, ok := e.(*argError); ok {
             fmt.Println(ae.arg)
             fmt.Println(ae.prob)
    @@ -262,7 +260,7 @@ assertion.

    -
    $ go run errors.go
    +          
    $ go run errors.go
     f1 worked: 10
     f1 failed: can't work with 42
     f2 worked: 10
    @@ -282,7 +280,7 @@ on the Go blog for more on error handling.

    - + @@ -297,5 +295,10 @@ on the Go blog for more on error handling.

    by Mark McGranaghan | source | license

    + + diff --git a/public/execing-processes b/public/execing-processes index 2d26b21..500d807 100644 --- a/public/execing-processes +++ b/public/execing-processes @@ -40,7 +40,7 @@ function.

    - + @@ -49,10 +49,8 @@ function.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -64,7 +62,7 @@ function.

    -
    import "syscall"
    +          
    import "syscall"
     import "os"
     import "os/exec"
     
    @@ -78,7 +76,7 @@ function.

    -
    func main() {
    +          
    func main() {
     
    @@ -94,7 +92,7 @@ we’ll use exec.LookPath to find it (probably -
        binary, lookErr := exec.LookPath("ls")
    +          
        binary, lookErr := exec.LookPath("ls")
         if lookErr != nil {
             panic(lookErr)
         }
    @@ -113,7 +111,7 @@ be the program name.

    -
        args := []string{"ls", "-a", "-l", "-h"}
    +          
        args := []string{"ls", "-a", "-l", "-h"}
     
    @@ -128,7 +126,7 @@ environment.

    -
        env := os.Environ()
    +          
        env := os.Environ()
     
    @@ -145,7 +143,7 @@ value.

    -
        execErr := syscall.Exec(binary, args, env)
    +          
        execErr := syscall.Exec(binary, args, env)
         if execErr != nil {
             panic(execErr)
         }
    @@ -166,7 +164,7 @@ value.

    -
    $ go run execing-processes.go
    +          
    $ go run execing-processes.go
     total 16
     drwxr-xr-x  4 mark 136B Oct 3 16:29 .
     drwxr-xr-x 91 mark 3.0K Oct 3 12:50 ..
    @@ -186,7 +184,7 @@ processes covers most use cases for fork.

    - + @@ -201,5 +199,10 @@ processes covers most use cases for fork.

    by Mark McGranaghan | source | license

    + + diff --git a/public/exit b/public/exit index 7b32b81..b8c38a6 100644 --- a/public/exit +++ b/public/exit @@ -29,7 +29,7 @@ status.

    - + @@ -38,10 +38,8 @@ status.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -53,7 +51,7 @@ status.

    -
    import "fmt"
    +          
    import "fmt"
     import "os"
     
    @@ -66,7 +64,7 @@ status.

    -
    func main() {
    +          
    func main() {
     
    @@ -80,7 +78,7 @@ this fmt.Println will never be called.

    -
        defer fmt.Println("!")
    +          
        defer fmt.Println("!")
     
    @@ -93,7 +91,7 @@ this fmt.Println will never be called.

    -
        os.Exit(3)
    +          
        os.Exit(3)
     }
     
    @@ -110,7 +108,7 @@ use os.Exit.

    - + @@ -126,7 +124,7 @@ will be picked up by go and printed.

    -
    $ go run exit.go
    +          
    $ go run exit.go
     exit status 3
     
    @@ -141,7 +139,7 @@ the status in the terminal.

    -
    $ go build exit.go
    +          
    $ go build exit.go
     $ ./exit
     $ echo $?
     3
    @@ -157,7 +155,7 @@ the status in the terminal.

    - + @@ -168,5 +166,10 @@ the status in the terminal.

    by Mark McGranaghan | source | license

    + + diff --git a/public/file-paths b/public/file-paths index 44a1faf..2351954 100644 --- a/public/file-paths +++ b/public/file-paths @@ -34,10 +34,8 @@ between operating systems; dir/file on Linux vs. - - - -
    package main
    +            
    +          
    package main
     
    @@ -49,7 +47,7 @@ between operating systems; dir/file on Linux vs. -
    import (
    +          
    import (
         "fmt"
         "path/filepath"
         "strings"
    @@ -65,7 +63,7 @@ between operating systems; dir/file on Linux vs.
               
               
                 
    -            
    func main() {
    +          
    func main() {
     
    @@ -80,7 +78,7 @@ and constructs a hierarchical path from them.

    -
        p := filepath.Join("dir1", "dir2", "filename")
    +          
        p := filepath.Join("dir1", "dir2", "filename")
         fmt.Println("p:", p)
     
    @@ -98,7 +96,7 @@ and directory changes.

    -
        fmt.Println(filepath.Join("dir1//", "filename"))
    +          
        fmt.Println(filepath.Join("dir1//", "filename"))
         fmt.Println(filepath.Join("dir1/../dir1", "filename"))
     
    @@ -114,7 +112,7 @@ return both in the same call.

    -
        fmt.Println("Dir(p):", filepath.Dir(p))
    +          
        fmt.Println("Dir(p):", filepath.Dir(p))
         fmt.Println("Base(p):", filepath.Base(p))
     
    @@ -128,7 +126,7 @@ return both in the same call.

    -
        fmt.Println(filepath.IsAbs("dir/file"))
    +          
        fmt.Println(filepath.IsAbs("dir/file"))
         fmt.Println(filepath.IsAbs("/dir/file"))
     
    @@ -141,7 +139,7 @@ return both in the same call.

    -
        filename := "config.json"
    +          
        filename := "config.json"
     
    @@ -155,7 +153,7 @@ can split the extension out of such names with Ext.

    -
        ext := filepath.Ext(filename)
    +          
        ext := filepath.Ext(filename)
         fmt.Println(ext)
     
    @@ -170,7 +168,7 @@ use strings.TrimSuffix.

    -
        fmt.Println(strings.TrimSuffix(filename, ext))
    +          
        fmt.Println(strings.TrimSuffix(filename, ext))
     
    @@ -185,7 +183,7 @@ be made relative to base.

    -
        rel, err := filepath.Rel("a/b", "a/b/t/file")
    +          
        rel, err := filepath.Rel("a/b", "a/b/t/file")
         if err != nil {
             panic(err)
         }
    @@ -201,7 +199,7 @@ be made relative to base.

    -
        rel, err = filepath.Rel("a/b", "a/c/t/file")
    +          
        rel, err = filepath.Rel("a/b", "a/c/t/file")
         if err != nil {
             panic(err)
         }
    @@ -222,7 +220,7 @@ be made relative to base.

    -
    $ go run file-paths.go
    +          
    $ go run file-paths.go
     p: dir1/dir2/filename
     dir1/filename
     dir1/filename
    @@ -250,5 +248,10 @@ be made relative to base.

    by Mark McGranaghan | source | license

    + + diff --git a/public/for b/public/for index 47f39c9..81b98d9 100644 --- a/public/for +++ b/public/for @@ -33,7 +33,7 @@ three basic types of for loops.

    - + @@ -42,10 +42,8 @@ three basic types of for loops.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -57,7 +55,7 @@ three basic types of for loops.

    -
    import "fmt"
    +          
    import "fmt"
     
    @@ -69,7 +67,7 @@ three basic types of for loops.

    -
    func main() {
    +          
    func main() {
     
    @@ -82,7 +80,7 @@ three basic types of for loops.

    -
        i := 1
    +          
        i := 1
         for i <= 3 {
             fmt.Println(i)
             i = i + 1
    @@ -99,7 +97,7 @@ three basic types of for loops.

    -
        for j := 7; j <= 9; j++ {
    +          
        for j := 7; j <= 9; j++ {
             fmt.Println(j)
         }
     
    @@ -116,7 +114,7 @@ the enclosing function.

    -
        for {
    +          
        for {
             fmt.Println("loop")
             break
         }
    @@ -133,7 +131,7 @@ the loop.

    -
        for n := 0; n <= 5; n++ {
    +          
        for n := 0; n <= 5; n++ {
             if n%2 == 0 {
                 continue
             }
    @@ -155,7 +153,7 @@ the loop.

    -
    $ go run for.go
    +          
    $ go run for.go
     1
     2
     3
    @@ -180,7 +178,7 @@ structures.

    - + @@ -195,5 +193,10 @@ structures.

    by Mark McGranaghan | source | license

    + + diff --git a/public/functions b/public/functions index 8eeca6c..8880847 100644 --- a/public/functions +++ b/public/functions @@ -33,7 +33,7 @@ functions with a few different examples.

    - + @@ -42,10 +42,8 @@ functions with a few different examples.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -57,7 +55,7 @@ functions with a few different examples.

    -
    import "fmt"
    +          
    import "fmt"
     
    @@ -71,7 +69,7 @@ their sum as an int.

    -
    func plus(a int, b int) int {
    +          
    func plus(a int, b int) int {
     
    @@ -86,7 +84,7 @@ expression.

    -
        return a + b
    +          
        return a + b
     }
     
    @@ -103,7 +101,7 @@ declares the type.

    -
    func plusPlus(a, b, c int) int {
    +          
    func plusPlus(a, b, c int) int {
         return a + b + c
     }
     
    @@ -117,7 +115,7 @@ declares the type.

    -
    func main() {
    +          
    func main() {
     
    @@ -131,7 +129,7 @@ declares the type.

    -
        res := plus(1, 2)
    +          
        res := plus(1, 2)
         fmt.Println("1+2 =", res)
     
    @@ -144,7 +142,7 @@ declares the type.

    -
        res = plusPlus(1, 2, 3)
    +          
        res = plusPlus(1, 2, 3)
         fmt.Println("1+2+3 =", res)
     }
     
    @@ -162,7 +160,7 @@ declares the type.

    -
    $ go run functions.go 
    +          
    $ go run functions.go 
     1+2 = 3
     1+2+3 = 6
     
    @@ -178,7 +176,7 @@ multiple return values, which we’ll look at next.

    - + @@ -193,5 +191,10 @@ multiple return values, which we’ll look at next.

    by Mark McGranaghan | source | license

    + + diff --git a/public/goroutines b/public/goroutines index 06f5e9b..a7a4222 100644 --- a/public/goroutines +++ b/public/goroutines @@ -32,7 +32,7 @@ - + @@ -41,10 +41,8 @@ - - - -
    package main
    +            
    +          
    package main
     
    @@ -56,7 +54,7 @@ -
    import "fmt"
    +          
    import "fmt"
     
    @@ -68,7 +66,7 @@ -
    func f(from string) {
    +          
    func f(from string) {
         for i := 0; i < 3; i++ {
             fmt.Println(from, ":", i)
         }
    @@ -84,7 +82,7 @@
               
               
                 
    -            
    func main() {
    +          
    func main() {
     
    @@ -99,7 +97,7 @@ synchronously.

    -
        f("direct")
    +          
        f("direct")
     
    @@ -114,7 +112,7 @@ concurrently with the calling one.

    -
        go f("goroutine")
    +          
        go f("goroutine")
     
    @@ -128,7 +126,7 @@ function call.

    -
        go func(msg string) {
    +          
        go func(msg string) {
             fmt.Println(msg)
         }("going")
     
    @@ -146,7 +144,7 @@ before the program exits.

    -
        fmt.Scanln()
    +          
        fmt.Scanln()
         fmt.Println("done")
     }
     
    @@ -168,7 +166,7 @@ goroutines being run concurrently by the Go runtime.

    -
    $ go run goroutines.go
    +          
    $ go run goroutines.go
     direct : 0
     direct : 1
     direct : 2
    @@ -191,7 +189,7 @@ concurrent Go programs: channels.

    - + @@ -206,5 +204,10 @@ concurrent Go programs: channels.

    by Mark McGranaghan | source | license

    + + diff --git a/public/hello-world b/public/hello-world index f33d703..4c2373a 100644 --- a/public/hello-world +++ b/public/hello-world @@ -28,10 +28,8 @@ message. Here’s the full source code.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -43,7 +41,7 @@ message. Here’s the full source code.

    -
    import "fmt"
    +          
    import "fmt"
     
    @@ -55,7 +53,7 @@ message. Here’s the full source code.

    -
    func main() {
    +          
    func main() {
         fmt.Println("hello world")
     }
     
    @@ -75,7 +73,7 @@ use go run.

    -
    $ go run hello-world.go
    +          
    $ go run hello-world.go
     hello world
     
    @@ -90,7 +88,7 @@ binaries. We can do this using go build.

    -
    $ go build hello-world.go
    +          
    $ go build hello-world.go
     $ ls
     hello-world    hello-world.go
     
    @@ -105,7 +103,7 @@ binaries. We can do this using go build.

    -
    $ ./hello-world
    +          
    $ ./hello-world
     hello world
     
    @@ -120,7 +118,7 @@ learn more about the language.

    - + @@ -135,5 +133,10 @@ learn more about the language.

    by Mark McGranaghan | source | license

    + + diff --git a/public/http-clients b/public/http-clients index d1a9f50..7bdaa06 100644 --- a/public/http-clients +++ b/public/http-clients @@ -34,10 +34,8 @@ HTTP requests.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -49,7 +47,7 @@ HTTP requests.

    -
    import (
    +          
    import (
         "bufio"
         "fmt"
         "net/http"
    @@ -65,7 +63,7 @@ HTTP requests.

    -
    func main() {
    +          
    func main() {
     
    @@ -82,7 +80,7 @@ settings.

    -
        resp, err := http.Get("http://gobyexample.com")
    +          
        resp, err := http.Get("http://gobyexample.com")
         if err != nil {
             panic(err)
         }
    @@ -99,7 +97,7 @@ settings.

    -
        fmt.Println("Response status:", resp.Status)
    +          
        fmt.Println("Response status:", resp.Status)
     
    @@ -112,7 +110,7 @@ settings.

    -
        scanner := bufio.NewScanner(resp.Body)
    +          
        scanner := bufio.NewScanner(resp.Body)
         for i := 0; scanner.Scan() && i < 5; i++ {
             fmt.Println(scanner.Text())
         }
    @@ -127,7 +125,7 @@ settings.

    -
        if err := scanner.Err(); err != nil {
    +          
        if err := scanner.Err(); err != nil {
             panic(err)
         }
     }
    @@ -146,7 +144,7 @@ settings.

    -
    $ go run http-clients.go
    +          
    $ go run http-clients.go
     Response status: 200 OK
     <!DOCTYPE html>
     <html>
    @@ -169,5 +167,10 @@ settings.

    by Mark McGranaghan | source | license

    + + diff --git a/public/http-servers b/public/http-servers index b9f74d6..aa2802d 100644 --- a/public/http-servers +++ b/public/http-servers @@ -32,10 +32,8 @@ - - - -
    package main
    +            
    +          
    package main
     
    @@ -47,7 +45,7 @@ -
    import (
    +          
    import (
         "fmt"
         "net/http"
     )
    @@ -67,7 +65,7 @@ on functions with the appropriate signature.

    -
    func hello(w http.ResponseWriter, req *http.Request) {
    +          
    func hello(w http.ResponseWriter, req *http.Request) {
     
    @@ -84,7 +82,7 @@ HTTP response. Here our simple response is just -
        fmt.Fprintf(w, "hello\n")
    +          
        fmt.Fprintf(w, "hello\n")
     }
     
    @@ -97,7 +95,7 @@ HTTP response. Here our simple response is just -
    func headers(w http.ResponseWriter, req *http.Request) {
    +          
    func headers(w http.ResponseWriter, req *http.Request) {
     
    @@ -112,7 +110,7 @@ headers and echoing them into the response body.

    -
        for name, headers := range req.Header {
    +          
        for name, headers := range req.Header {
             for _, h := range headers {
                 fmt.Fprintf(w, "%v: %v\n", name, h)
             }
    @@ -129,7 +127,7 @@ headers and echoing them into the response body.

    -
    func main() {
    +          
    func main() {
     
    @@ -145,7 +143,7 @@ takes a function as an argument.

    -
        http.HandleFunc("/hello", hello)
    +          
        http.HandleFunc("/hello", hello)
         http.HandleFunc("/headers", headers)
     
    @@ -161,7 +159,7 @@ router we’ve just set up.

    -
        http.ListenAndServe(":8090", nil)
    +          
        http.ListenAndServe(":8090", nil)
     }
     
    @@ -179,7 +177,7 @@ router we’ve just set up.

    -
    $ go run http-servers.go &
    +          
    $ go run http-servers.go &
     
    @@ -192,7 +190,7 @@ router we’ve just set up.

    -
    $ curl localhost:8090/hello
    +          
    $ curl localhost:8090/hello
     hello
     
    @@ -210,5 +208,10 @@ router we’ve just set up.

    by Mark McGranaghan | source | license

    + + diff --git a/public/if-else b/public/if-else index dcc5aec..f00d6b5 100644 --- a/public/if-else +++ b/public/if-else @@ -33,7 +33,7 @@ straight-forward.

    - + @@ -42,10 +42,8 @@ straight-forward.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -57,7 +55,7 @@ straight-forward.

    -
    import "fmt"
    +          
    import "fmt"
     
    @@ -69,7 +67,7 @@ straight-forward.

    -
    func main() {
    +          
    func main() {
     
    @@ -82,7 +80,7 @@ straight-forward.

    -
        if 7%2 == 0 {
    +          
        if 7%2 == 0 {
             fmt.Println("7 is even")
         } else {
             fmt.Println("7 is odd")
    @@ -99,7 +97,7 @@ straight-forward.

    -
        if 8%4 == 0 {
    +          
        if 8%4 == 0 {
             fmt.Println("8 is divisible by 4")
         }
     
    @@ -116,7 +114,7 @@ branches.

    -
        if num := 9; num < 0 {
    +          
        if num := 9; num < 0 {
             fmt.Println(num, "is negative")
         } else if num < 10 {
             fmt.Println(num, "has 1 digit")
    @@ -137,7 +135,7 @@ in Go, but that the braces are required.

    - + @@ -151,7 +149,7 @@ in Go, but that the braces are required.

    -
    $ go run if-else.go 
    +          
    $ go run if-else.go 
     7 is odd
     8 is divisible by 4
     9 has 1 digit
    @@ -169,7 +167,7 @@ for basic conditions.

    - + @@ -184,5 +182,10 @@ for basic conditions.

    by Mark McGranaghan | source | license

    + + diff --git a/public/interfaces b/public/interfaces index 909465b..eddb066 100644 --- a/public/interfaces +++ b/public/interfaces @@ -33,7 +33,7 @@ signatures.

    - + @@ -42,10 +42,8 @@ signatures.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -57,7 +55,7 @@ signatures.

    -
    import "fmt"
    +          
    import "fmt"
     import "math"
     
    @@ -71,7 +69,7 @@ signatures.

    -
    type geometry interface {
    +          
    type geometry interface {
         area() float64
         perim() float64
     }
    @@ -88,7 +86,7 @@ signatures.

    -
    type rect struct {
    +          
    type rect struct {
         width, height float64
     }
     type circle struct {
    @@ -108,7 +106,7 @@ implement geometry on rects.

    -
    func (r rect) area() float64 {
    +          
    func (r rect) area() float64 {
         return r.width * r.height
     }
     func (r rect) perim() float64 {
    @@ -126,7 +124,7 @@ implement geometry on rects.

    -
    func (c circle) area() float64 {
    +          
    func (c circle) area() float64 {
         return math.Pi * c.radius * c.radius
     }
     func (c circle) perim() float64 {
    @@ -147,7 +145,7 @@ to work on any geometry.

    -
    func measure(g geometry) {
    +          
    func measure(g geometry) {
         fmt.Println(g)
         fmt.Println(g.area())
         fmt.Println(g.perim())
    @@ -163,7 +161,7 @@ to work on any geometry.

    -
    func main() {
    +          
    func main() {
         r := rect{width: 3, height: 4}
         c := circle{radius: 5}
     
    @@ -181,7 +179,7 @@ these structs as arguments to measure.

    -
        measure(r)
    +          
        measure(r)
         measure(c)
     }
     
    @@ -199,7 +197,7 @@ these structs as arguments to measure.

    -
    $ go run interfaces.go
    +          
    $ go run interfaces.go
     {3 4}
     12
     14
    @@ -219,7 +217,7 @@ these structs as arguments to measure.

    - + @@ -234,5 +232,10 @@ these structs as arguments to measure.

    by Mark McGranaghan | source | license

    + + diff --git a/public/json b/public/json index f6a4146..fb7b9c8 100644 --- a/public/json +++ b/public/json @@ -34,7 +34,7 @@ data types.

    - + @@ -43,10 +43,8 @@ data types.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -58,7 +56,7 @@ data types.

    -
    import "encoding/json"
    +          
    import "encoding/json"
     import "fmt"
     import "os"
     
    @@ -74,7 +72,7 @@ decoding of custom types below.

    -
    type response1 struct {
    +          
    type response1 struct {
         Page   int
         Fruits []string
     }
    @@ -93,7 +91,7 @@ decoding of custom types below.

    -
    func main() {
    +          
    func main() {
     
    @@ -108,7 +106,7 @@ values.

    -
        bolB, _ := json.Marshal(true)
    +          
        bolB, _ := json.Marshal(true)
         fmt.Println(string(bolB))
     
    @@ -121,7 +119,7 @@ values.

    -
        intB, _ := json.Marshal(1)
    +          
        intB, _ := json.Marshal(1)
         fmt.Println(string(intB))
     
    @@ -134,7 +132,7 @@ values.

    -
        fltB, _ := json.Marshal(2.34)
    +          
        fltB, _ := json.Marshal(2.34)
         fmt.Println(string(fltB))
     
    @@ -147,7 +145,7 @@ values.

    -
        strB, _ := json.Marshal("gopher")
    +          
        strB, _ := json.Marshal("gopher")
         fmt.Println(string(strB))
     
    @@ -162,7 +160,7 @@ to JSON arrays and objects as you’d expect.

    -
        slcD := []string{"apple", "peach", "pear"}
    +          
        slcD := []string{"apple", "peach", "pear"}
         slcB, _ := json.Marshal(slcD)
         fmt.Println(string(slcB))
     
    @@ -176,7 +174,7 @@ to JSON arrays and objects as you’d expect.

    -
        mapD := map[string]int{"apple": 5, "lettuce": 7}
    +          
        mapD := map[string]int{"apple": 5, "lettuce": 7}
         mapB, _ := json.Marshal(mapD)
         fmt.Println(string(mapB))
     
    @@ -194,7 +192,7 @@ use those names as the JSON keys.

    -
        res1D := &response1{
    +          
        res1D := &response1{
             Page:   1,
             Fruits: []string{"apple", "peach", "pear"}}
         res1B, _ := json.Marshal(res1D)
    @@ -214,7 +212,7 @@ of such tags.

    -
        res2D := &response2{
    +          
        res2D := &response2{
             Page:   1,
             Fruits: []string{"apple", "peach", "pear"}}
         res2B, _ := json.Marshal(res2D)
    @@ -233,7 +231,7 @@ structure.

    -
        byt := []byte(`{"num":6.13,"strs":["a","b"]}`)
    +          
        byt := []byte(`{"num":6.13,"strs":["a","b"]}`)
     
    @@ -249,7 +247,7 @@ to arbitrary data types.

    -
        var dat map[string]interface{}
    +          
        var dat map[string]interface{}
     
    @@ -263,7 +261,7 @@ associated errors.

    -
        if err := json.Unmarshal(byt, &dat); err != nil {
    +          
        if err := json.Unmarshal(byt, &dat); err != nil {
             panic(err)
         }
         fmt.Println(dat)
    @@ -282,7 +280,7 @@ the expected float64 type.

    -
        num := dat["num"].(float64)
    +          
        num := dat["num"].(float64)
         fmt.Println(num)
     
    @@ -297,7 +295,7 @@ conversions.

    -
        strs := dat["strs"].([]interface{})
    +          
        strs := dat["strs"].([]interface{})
         str1 := strs[0].(string)
         fmt.Println(str1)
     
    @@ -316,7 +314,7 @@ data.

    -
        str := `{"page": 1, "fruits": ["apple", "peach"]}`
    +          
        str := `{"page": 1, "fruits": ["apple", "peach"]}`
         res := response2{}
         json.Unmarshal([]byte(str), &res)
         fmt.Println(res)
    @@ -337,7 +335,7 @@ stream JSON encodings directly to os.Writers like
               
               
                 
    -            
        enc := json.NewEncoder(os.Stdout)
    +          
        enc := json.NewEncoder(os.Stdout)
         d := map[string]int{"apple": 5, "lettuce": 7}
         enc.Encode(d)
     }
    @@ -356,7 +354,7 @@ stream JSON encodings directly to os.Writers like
               
               
                 
    -            
    $ go run json.go
    +          
    $ go run json.go
     true
     1
     2.34
    @@ -386,7 +384,7 @@ for more.

    - + @@ -401,5 +399,10 @@ for more.

    by Mark McGranaghan | source | license

    + + diff --git a/public/line-filters b/public/line-filters index d673b55..f7796d0 100644 --- a/public/line-filters +++ b/public/line-filters @@ -35,7 +35,7 @@ line filters.

    - + @@ -47,10 +47,8 @@ pattern to write your own Go line filters.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -62,7 +60,7 @@ pattern to write your own Go line filters.

    -
    import (
    +          
    import (
         "bufio"
         "fmt"
         "os"
    @@ -79,7 +77,7 @@ pattern to write your own Go line filters.

    -
    func main() {
    +          
    func main() {
     
    @@ -95,7 +93,7 @@ the next line in the default scanner.

    -
        scanner := bufio.NewScanner(os.Stdin)
    +          
        scanner := bufio.NewScanner(os.Stdin)
     
    @@ -109,7 +107,7 @@ from the input.

    -
        for scanner.Scan() {
    +          
        for scanner.Scan() {
     
    @@ -121,7 +119,7 @@ from the input.

    -
            ucl := strings.ToUpper(scanner.Text())
    +          
            ucl := strings.ToUpper(scanner.Text())
     
    @@ -134,7 +132,7 @@ from the input.

    -
            fmt.Println(ucl)
    +          
            fmt.Println(ucl)
         }
     
    @@ -149,7 +147,7 @@ expected and not reported by Scan as an error.

    -
        if err := scanner.Err(); err != nil {
    +          
        if err := scanner.Err(); err != nil {
             fmt.Fprintln(os.Stderr, "error:", err)
             os.Exit(1)
         }
    @@ -171,7 +169,7 @@ lowercase lines.

    -
    $ echo 'hello'   > /tmp/lines
    +          
    $ echo 'hello'   > /tmp/lines
     $ echo 'filter' >> /tmp/lines
     
    @@ -185,7 +183,7 @@ lowercase lines.

    -
    $ cat /tmp/lines | go run line-filters.go
    +          
    $ cat /tmp/lines | go run line-filters.go
     HELLO
     FILTER
     
    @@ -204,5 +202,10 @@ lowercase lines.

    by Mark McGranaghan | source | license

    + + diff --git a/public/maps b/public/maps index bfaefce..443efd7 100644 --- a/public/maps +++ b/public/maps @@ -33,7 +33,7 @@ - + @@ -42,10 +42,8 @@ - - - -
    package main
    +            
    +          
    package main
     
    @@ -57,7 +55,7 @@ -
    import "fmt"
    +          
    import "fmt"
     
    @@ -69,7 +67,7 @@ -
    func main() {
    +          
    func main() {
     
    @@ -83,7 +81,7 @@ -
        m := make(map[string]int)
    +          
        m := make(map[string]int)
     
    @@ -97,7 +95,7 @@ syntax.

    -
        m["k1"] = 7
    +          
        m["k1"] = 7
         m["k2"] = 13
     
    @@ -112,7 +110,7 @@ its key/value pairs.

    -
        fmt.Println("map:", m)
    +          
        fmt.Println("map:", m)
     
    @@ -125,7 +123,7 @@ its key/value pairs.

    -
        v1 := m["k1"]
    +          
        v1 := m["k1"]
         fmt.Println("v1: ", v1)
     
    @@ -140,7 +138,7 @@ pairs when called on a map.

    -
        fmt.Println("len:", len(m))
    +          
        fmt.Println("len:", len(m))
     
    @@ -154,7 +152,7 @@ a map.

    -
        delete(m, "k2")
    +          
        delete(m, "k2")
         fmt.Println("map:", m)
     
    @@ -174,7 +172,7 @@ itself, so we ignored it with the blank identifier -
        _, prs := m["k2"]
    +          
        _, prs := m["k2"]
         fmt.Println("prs:", prs)
     
    @@ -189,7 +187,7 @@ the same line with this syntax.

    -
        n := map[string]int{"foo": 1, "bar": 2}
    +          
        n := map[string]int{"foo": 1, "bar": 2}
         fmt.Println("map:", n)
     }
     
    @@ -209,7 +207,7 @@ printed with fmt.Println.

    -
    $ go run maps.go 
    +          
    $ go run maps.go 
     map: map[k1:7 k2:13]
     v1:  7
     len: 2
    @@ -232,5 +230,10 @@ printed with fmt.Println.

    by Mark McGranaghan | source | license

    + + diff --git a/public/methods b/public/methods index cf9f7f7..ca0589a 100644 --- a/public/methods +++ b/public/methods @@ -32,7 +32,7 @@ - + @@ -41,10 +41,8 @@ - - - -
    package main
    +            
    +          
    package main
     
    @@ -56,7 +54,7 @@ -
    import "fmt"
    +          
    import "fmt"
     
    @@ -68,7 +66,7 @@ -
    type rect struct {
    +          
    type rect struct {
         width, height int
     }
     
    @@ -83,7 +81,7 @@ -
    func (r *rect) area() int {
    +          
    func (r *rect) area() int {
         return r.width * r.height
     }
     
    @@ -99,7 +97,7 @@ receiver types. Here’s an example of a value receiver.

    -
    func (r rect) perim() int {
    +          
    func (r rect) perim() int {
         return 2*r.width + 2*r.height
     }
     
    @@ -113,7 +111,7 @@ receiver types. Here’s an example of a value receiver.

    -
    func main() {
    +          
    func main() {
         r := rect{width: 10, height: 5}
     
    @@ -127,7 +125,7 @@ receiver types. Here’s an example of a value receiver.

    -
        fmt.Println("area: ", r.area())
    +          
        fmt.Println("area: ", r.area())
         fmt.Println("perim:", r.perim())
     
    @@ -145,7 +143,7 @@ receiving struct.

    -
        rp := &r
    +          
        rp := &r
         fmt.Println("area: ", rp.area())
         fmt.Println("perim:", rp.perim())
     }
    @@ -164,7 +162,7 @@ receiving struct.

    -
    $ go run methods.go 
    +          
    $ go run methods.go 
     area:  50
     perim: 30
     area:  50
    @@ -182,7 +180,7 @@ naming related sets of methods: interfaces.

    - + @@ -197,5 +195,10 @@ naming related sets of methods: interfaces.

    by Mark McGranaghan | source | license

    + + diff --git a/public/multiple-return-values b/public/multiple-return-values index 1bd021d..bd16bd1 100644 --- a/public/multiple-return-values +++ b/public/multiple-return-values @@ -34,7 +34,7 @@ to return both result and error values from a function.

    - + @@ -43,10 +43,8 @@ to return both result and error values from a function.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -58,7 +56,7 @@ to return both result and error values from a function.

    -
    import "fmt"
    +          
    import "fmt"
     
    @@ -72,7 +70,7 @@ the function returns 2 ints.

    -
    func vals() (int, int) {
    +          
    func vals() (int, int) {
         return 3, 7
     }
     
    @@ -86,7 +84,7 @@ the function returns 2 ints.

    -
    func main() {
    +          
    func main() {
     
    @@ -100,7 +98,7 @@ call with multiple assignment.

    -
        a, b := vals()
    +          
        a, b := vals()
         fmt.Println(a)
         fmt.Println(b)
     
    @@ -116,7 +114,7 @@ use the blank identifier _.

    -
        _, c := vals()
    +          
        _, c := vals()
         fmt.Println(c)
     }
     
    @@ -134,7 +132,7 @@ use the blank identifier _.

    -
    $ go run multiple-return-values.go
    +          
    $ go run multiple-return-values.go
     3
     7
     7
    @@ -151,7 +149,7 @@ feature of Go functions; we’ll look at this next.

    - + @@ -166,5 +164,10 @@ feature of Go functions; we’ll look at this next.

    by Mark McGranaghan | source | license

    + + diff --git a/public/mutexes b/public/mutexes index f3c8476..14d8137 100644 --- a/public/mutexes +++ b/public/mutexes @@ -35,7 +35,7 @@ to safely access data across multiple goroutines.

    - + @@ -44,10 +44,8 @@ to safely access data across multiple goroutines.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -59,7 +57,7 @@ to safely access data across multiple goroutines.

    -
    import (
    +          
    import (
         "fmt"
         "math/rand"
         "sync"
    @@ -77,7 +75,7 @@ to safely access data across multiple goroutines.

    -
    func main() {
    +          
    func main() {
     
    @@ -90,7 +88,7 @@ to safely access data across multiple goroutines.

    -
        var state = make(map[int]int)
    +          
        var state = make(map[int]int)
     
    @@ -103,7 +101,7 @@ to safely access data across multiple goroutines.

    -
        var mutex = &sync.Mutex{}
    +          
        var mutex = &sync.Mutex{}
     
    @@ -117,7 +115,7 @@ operations we do.

    -
        var readOps uint64
    +          
        var readOps uint64
         var writeOps uint64
     
    @@ -133,7 +131,7 @@ each goroutine.

    -
        for r := 0; r < 100; r++ {
    +          
        for r := 0; r < 100; r++ {
             go func() {
                 total := 0
                 for {
    @@ -154,7 +152,7 @@ the readOps count.

    -
                    key := rand.Intn(5)
    +          
                    key := rand.Intn(5)
                     mutex.Lock()
                     total += state[key]
                     mutex.Unlock()
    @@ -171,7 +169,7 @@ the readOps count.

    -
                    time.Sleep(time.Millisecond)
    +          
                    time.Sleep(time.Millisecond)
                 }
             }()
         }
    @@ -188,7 +186,7 @@ using the same pattern we did for reads.

    -
        for w := 0; w < 10; w++ {
    +          
        for w := 0; w < 10; w++ {
             go func() {
                 for {
                     key := rand.Intn(5)
    @@ -214,7 +212,7 @@ using the same pattern we did for reads.

    -
        time.Sleep(time.Second)
    +          
        time.Sleep(time.Second)
     
    @@ -227,7 +225,7 @@ using the same pattern we did for reads.

    -
        readOpsFinal := atomic.LoadUint64(&readOps)
    +          
        readOpsFinal := atomic.LoadUint64(&readOps)
         fmt.Println("readOps:", readOpsFinal)
         writeOpsFinal := atomic.LoadUint64(&writeOps)
         fmt.Println("writeOps:", writeOpsFinal)
    @@ -243,7 +241,7 @@ using the same pattern we did for reads.

    -
        mutex.Lock()
    +          
        mutex.Lock()
         fmt.Println("state:", state)
         mutex.Unlock()
     }
    @@ -265,7 +263,7 @@ using the same pattern we did for reads.

    -
    $ go run mutexes.go
    +          
    $ go run mutexes.go
     readOps: 83285
     writeOps: 8320
     state: map[1:97 4:53 0:33 2:15 3:2]
    @@ -282,7 +280,7 @@ management task using only goroutines and channels.

    - + @@ -297,5 +295,10 @@ management task using only goroutines and channels.

    by Mark McGranaghan | source | license

    + + diff --git a/public/non-blocking-channel-operations b/public/non-blocking-channel-operations index 64c17ca..bbe6d55 100644 --- a/public/non-blocking-channel-operations +++ b/public/non-blocking-channel-operations @@ -35,7 +35,7 @@ non-blocking multi-way selects.

    - + @@ -44,10 +44,8 @@ non-blocking multi-way selects.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -59,7 +57,7 @@ non-blocking multi-way selects.

    -
    import "fmt"
    +          
    import "fmt"
     
    @@ -71,7 +69,7 @@ non-blocking multi-way selects.

    -
    func main() {
    +          
    func main() {
         messages := make(chan string)
         signals := make(chan bool)
     
    @@ -89,7 +87,7 @@ it will immediately take the default case.

    -
        select {
    +          
        select {
         case msg := <-messages:
             fmt.Println("received message", msg)
         default:
    @@ -110,7 +108,7 @@ Therefore the default case is selected.

    -
        msg := "hi"
    +          
        msg := "hi"
         select {
         case messages <- msg:
             fmt.Println("sent message", msg)
    @@ -132,7 +130,7 @@ on both messages and signals.

    -
        select {
    +          
        select {
         case msg := <-messages:
             fmt.Println("received message", msg)
         case sig := <-signals:
    @@ -156,7 +154,7 @@ on both messages and signals.

    -
    $ go run non-blocking-channel-operations.go 
    +          
    $ go run non-blocking-channel-operations.go 
     no message received
     no message sent
     no activity
    @@ -176,5 +174,10 @@ on both messages and signals.

    by Mark McGranaghan | source | license

    + + diff --git a/public/number-parsing b/public/number-parsing index e8c4f81..db31e0d 100644 --- a/public/number-parsing +++ b/public/number-parsing @@ -33,7 +33,7 @@ in many programs; here’s how to do it in Go.

    - + @@ -42,10 +42,8 @@ in many programs; here’s how to do it in Go.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -59,7 +57,7 @@ parsing.

    -
    import "strconv"
    +          
    import "strconv"
     import "fmt"
     
    @@ -72,7 +70,7 @@ parsing.

    -
    func main() {
    +          
    func main() {
     
    @@ -86,7 +84,7 @@ precision to parse.

    -
        f, _ := strconv.ParseFloat("1.234", 64)
    +          
        f, _ := strconv.ParseFloat("1.234", 64)
         fmt.Println(f)
     
    @@ -102,7 +100,7 @@ bits.

    -
        i, _ := strconv.ParseInt("123", 0, 64)
    +          
        i, _ := strconv.ParseInt("123", 0, 64)
         fmt.Println(i)
     
    @@ -116,7 +114,7 @@ bits.

    -
        d, _ := strconv.ParseInt("0x1c8", 0, 64)
    +          
        d, _ := strconv.ParseInt("0x1c8", 0, 64)
         fmt.Println(d)
     
    @@ -130,7 +128,7 @@ bits.

    -
        u, _ := strconv.ParseUint("789", 0, 64)
    +          
        u, _ := strconv.ParseUint("789", 0, 64)
         fmt.Println(u)
     
    @@ -145,7 +143,7 @@ bits.

    -
        k, _ := strconv.Atoi("135")
    +          
        k, _ := strconv.Atoi("135")
         fmt.Println(k)
     
    @@ -159,7 +157,7 @@ bits.

    -
        _, e := strconv.Atoi("wat")
    +          
        _, e := strconv.Atoi("wat")
         fmt.Println(e)
     }
     
    @@ -177,7 +175,7 @@ bits.

    -
    $ go run number-parsing.go 
    +          
    $ go run number-parsing.go 
     1.234
     123
     456
    @@ -196,7 +194,7 @@ bits.

    - + @@ -211,5 +209,10 @@ bits.

    by Mark McGranaghan | source | license

    + + diff --git a/public/panic b/public/panic index 4b08f98..6a9b834 100644 --- a/public/panic +++ b/public/panic @@ -35,7 +35,7 @@ aren’t prepared to handle gracefully.

    - + @@ -44,10 +44,8 @@ aren’t prepared to handle gracefully.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -59,7 +57,7 @@ aren’t prepared to handle gracefully.

    -
    import "os"
    +          
    import "os"
     
    @@ -71,7 +69,7 @@ aren’t prepared to handle gracefully.

    -
    func main() {
    +          
    func main() {
     
    @@ -86,7 +84,7 @@ site designed to panic.

    -
        panic("a problem")
    +          
        panic("a problem")
     
    @@ -102,7 +100,7 @@ returns an error value that we don’t know how to -
        _, err := os.Create("/tmp/file")
    +          
        _, err := os.Create("/tmp/file")
         if err != nil {
             panic(err)
         }
    @@ -125,7 +123,7 @@ a non-zero status.

    -
    $ go run panic.go
    +          
    $ go run panic.go
     panic: a problem
     
    @@ -138,7 +136,7 @@ a non-zero status.

    -
    goroutine 1 [running]:
    +          
    goroutine 1 [running]:
     main.main()
         /.../panic.go:12 +0x47
     ...
    @@ -157,7 +155,7 @@ to use error-indicating return values wherever possible.

    - + @@ -172,5 +170,10 @@ to use error-indicating return values wherever possible.

    by Mark McGranaghan | source | license

    + + diff --git a/public/pointers b/public/pointers index 2caca80..4d10527 100644 --- a/public/pointers +++ b/public/pointers @@ -34,7 +34,7 @@ within your program.

    - + @@ -43,10 +43,8 @@ within your program.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -58,7 +56,7 @@ within your program.

    -
    import "fmt"
    +          
    import "fmt"
     
    @@ -75,7 +73,7 @@ from the one in the calling function.

    -
    func zeroval(ival int) {
    +          
    func zeroval(ival int) {
         ival = 0
     }
     
    @@ -95,7 +93,7 @@ value at the referenced address.

    -
    func zeroptr(iptr *int) {
    +          
    func zeroptr(iptr *int) {
         *iptr = 0
     }
     
    @@ -109,7 +107,7 @@ value at the referenced address.

    -
    func main() {
    +          
    func main() {
         i := 1
         fmt.Println("initial:", i)
     
    @@ -123,7 +121,7 @@ value at the referenced address.

    -
        zeroval(i)
    +          
        zeroval(i)
         fmt.Println("zeroval:", i)
     
    @@ -138,7 +136,7 @@ i.e. a pointer to i.

    -
        zeroptr(&i)
    +          
        zeroptr(&i)
         fmt.Println("zeroptr:", i)
     
    @@ -152,7 +150,7 @@ i.e. a pointer to i.

    -
        fmt.Println("pointer:", &i)
    +          
        fmt.Println("pointer:", &i)
     }
     
    @@ -172,7 +170,7 @@ the memory address for that variable.

    -
    $ go run pointers.go
    +          
    $ go run pointers.go
     initial: 1
     zeroval: 1
     zeroptr: 0
    @@ -193,5 +191,10 @@ the memory address for that variable.

    by Mark McGranaghan | source | license

    + + diff --git a/public/random-numbers b/public/random-numbers index 29f47e9..ffafb29 100644 --- a/public/random-numbers +++ b/public/random-numbers @@ -34,7 +34,7 @@ generation.

    - + @@ -43,10 +43,8 @@ generation.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -58,7 +56,7 @@ generation.

    -
    import "time"
    +          
    import "time"
     import "fmt"
     import "math/rand"
     
    @@ -72,7 +70,7 @@ generation.

    -
    func main() {
    +          
    func main() {
     
    @@ -86,7 +84,7 @@ generation.

    -
        fmt.Print(rand.Intn(100), ",")
    +          
        fmt.Print(rand.Intn(100), ",")
         fmt.Print(rand.Intn(100))
         fmt.Println()
     
    @@ -102,7 +100,7 @@ generation.

    -
        fmt.Println(rand.Float64())
    +          
        fmt.Println(rand.Float64())
     
    @@ -116,7 +114,7 @@ other ranges, for example 5.0 <= f' < 10.0.

    -
        fmt.Print((rand.Float64()*5)+5, ",")
    +          
        fmt.Print((rand.Float64()*5)+5, ",")
         fmt.Print((rand.Float64() * 5) + 5)
         fmt.Println()
     
    @@ -135,7 +133,7 @@ intend to be secret, use crypto/rand for those.

    -
        s1 := rand.NewSource(time.Now().UnixNano())
    +          
        s1 := rand.NewSource(time.Now().UnixNano())
         r1 := rand.New(s1)
     
    @@ -150,7 +148,7 @@ functions on the rand package.

    -
        fmt.Print(r1.Intn(100), ",")
    +          
        fmt.Print(r1.Intn(100), ",")
         fmt.Print(r1.Intn(100))
         fmt.Println()
     
    @@ -166,7 +164,7 @@ produces the same sequence of random numbers.

    -
        s2 := rand.NewSource(42)
    +          
        s2 := rand.NewSource(42)
         r2 := rand.New(s2)
         fmt.Print(r2.Intn(100), ",")
         fmt.Print(r2.Intn(100))
    @@ -191,7 +189,7 @@ produces the same sequence of random numbers.

    -
    $ go run random-numbers.go
    +          
    $ go run random-numbers.go
     81,87
     0.6645600532184904
     7.123187485356329,8.434115364335547
    @@ -212,7 +210,7 @@ that Go can provide.

    - + @@ -227,5 +225,10 @@ that Go can provide.

    by Mark McGranaghan | source | license

    + + diff --git a/public/range b/public/range index 688bbdb..f09b0c7 100644 --- a/public/range +++ b/public/range @@ -34,7 +34,7 @@ of the data structures we’ve already learned.

    - + @@ -43,10 +43,8 @@ of the data structures we’ve already learned.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -58,7 +56,7 @@ of the data structures we’ve already learned.

    -
    import "fmt"
    +          
    import "fmt"
     
    @@ -70,7 +68,7 @@ of the data structures we’ve already learned.

    -
    func main() {
    +          
    func main() {
     
    @@ -84,7 +82,7 @@ Arrays work like this too.

    -
        nums := []int{2, 3, 4}
    +          
        nums := []int{2, 3, 4}
         sum := 0
         for _, num := range nums {
             sum += num
    @@ -106,7 +104,7 @@ the indexes though.

    -
        for i, num := range nums {
    +          
        for i, num := range nums {
             if num == 3 {
                 fmt.Println("index:", i)
             }
    @@ -123,7 +121,7 @@ the indexes though.

    -
        kvs := map[string]string{"a": "apple", "b": "banana"}
    +          
        kvs := map[string]string{"a": "apple", "b": "banana"}
         for k, v := range kvs {
             fmt.Printf("%s -> %s\n", k, v)
         }
    @@ -139,7 +137,7 @@ the indexes though.

    -
        for k := range kvs {
    +          
        for k := range kvs {
             fmt.Println("key:", k)
         }
     
    @@ -156,7 +154,7 @@ of the rune and the second the rune itself.

    -
        for i, c := range "go" {
    +          
        for i, c := range "go" {
             fmt.Println(i, c)
         }
     }
    @@ -175,7 +173,7 @@ of the rune and the second the rune itself.

    -
    $ go run range.go
    +          
    $ go run range.go
     sum: 9
     index: 1
     a -> apple
    @@ -200,5 +198,10 @@ of the rune and the second the rune itself.

    by Mark McGranaghan | source | license

    + + diff --git a/public/range-over-channels b/public/range-over-channels index 5b6e160..1b7354c 100644 --- a/public/range-over-channels +++ b/public/range-over-channels @@ -35,7 +35,7 @@ values received from a channel.

    - + @@ -44,10 +44,8 @@ values received from a channel.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -59,7 +57,7 @@ values received from a channel.

    -
    import "fmt"
    +          
    import "fmt"
     
    @@ -71,7 +69,7 @@ values received from a channel.

    -
    func main() {
    +          
    func main() {
     
    @@ -84,7 +82,7 @@ values received from a channel.

    -
        queue := make(chan string, 2)
    +          
        queue := make(chan string, 2)
         queue <- "one"
         queue <- "two"
         close(queue)
    @@ -103,7 +101,7 @@ receiving the 2 elements.

    -
        for elem := range queue {
    +          
        for elem := range queue {
             fmt.Println(elem)
         }
     }
    @@ -122,7 +120,7 @@ receiving the 2 elements.

    -
    $ go run range-over-channels.go
    +          
    $ go run range-over-channels.go
     one
     two
     
    @@ -139,7 +137,7 @@ values be received.

    - + @@ -154,5 +152,10 @@ values be received.

    by Mark McGranaghan | source | license

    + + diff --git a/public/rate-limiting b/public/rate-limiting index 30b739f..897642b 100644 --- a/public/rate-limiting +++ b/public/rate-limiting @@ -36,7 +36,7 @@ channels, and tickers.

    - + @@ -45,10 +45,8 @@ channels, and tickers.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -60,7 +58,7 @@ channels, and tickers.

    -
    import "time"
    +          
    import "time"
     import "fmt"
     
    @@ -73,7 +71,7 @@ channels, and tickers.

    -
    func main() {
    +          
    func main() {
     
    @@ -89,7 +87,7 @@ same name.

    -
        requests := make(chan int, 5)
    +          
        requests := make(chan int, 5)
         for i := 1; i <= 5; i++ {
             requests <- i
         }
    @@ -108,7 +106,7 @@ our rate limiting scheme.

    -
        limiter := time.Tick(200 * time.Millisecond)
    +          
        limiter := time.Tick(200 * time.Millisecond)
     
    @@ -123,7 +121,7 @@ before serving each request, we limit ourselves to -
        for req := range requests {
    +          
        for req := range requests {
             <-limiter
             fmt.Println("request", req, time.Now())
         }
    @@ -143,7 +141,7 @@ channel will allow bursts of up to 3 events.

    -
        burstyLimiter := make(chan time.Time, 3)
    +          
        burstyLimiter := make(chan time.Time, 3)
     
    @@ -156,7 +154,7 @@ channel will allow bursts of up to 3 events.

    -
        for i := 0; i < 3; i++ {
    +          
        for i := 0; i < 3; i++ {
             burstyLimiter <- time.Now()
         }
     
    @@ -172,7 +170,7 @@ value to burstyLimiter, up to its limit of 3.

    -
        go func() {
    +          
        go func() {
             for t := range time.Tick(200 * time.Millisecond) {
                 burstyLimiter <- t
             }
    @@ -191,7 +189,7 @@ of burstyLimiter.

    -
        burstyRequests := make(chan int, 5)
    +          
        burstyRequests := make(chan int, 5)
         for i := 1; i <= 5; i++ {
             burstyRequests <- i
         }
    @@ -218,7 +216,7 @@ handled once every ~200 milliseconds as desired.

    -
    $ go run rate-limiting.go
    +          
    $ 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
     request 3 2012-10-19 00:38:19.087238 +0000 UTC
    @@ -238,7 +236,7 @@ then serve the remaining 2 with ~200ms delays each.

    -
    request 1 2012-10-19 00:38:20.487578 +0000 UTC
    +          
    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
     request 4 2012-10-19 00:38:20.687483 +0000 UTC
    @@ -259,5 +257,10 @@ then serve the remaining 2 with ~200ms delays each.

    by Mark McGranaghan | source | license

    + + diff --git a/public/reading-files b/public/reading-files index af5009b..5f87bee 100644 --- a/public/reading-files +++ b/public/reading-files @@ -34,7 +34,7 @@ reading files.

    - + @@ -43,10 +43,8 @@ reading files.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -58,7 +56,7 @@ reading files.

    -
    import (
    +          
    import (
         "bufio"
         "fmt"
         "io"
    @@ -78,7 +76,7 @@ This helper will streamline our error checks below.

    -
    func check(e error) {
    +          
    func check(e error) {
         if e != nil {
             panic(e)
         }
    @@ -94,7 +92,7 @@ This helper will streamline our error checks below.

    -
    func main() {
    +          
    func main() {
     
    @@ -108,7 +106,7 @@ slurping a file’s entire contents into memory.

    -
        dat, err := ioutil.ReadFile("/tmp/dat")
    +          
        dat, err := ioutil.ReadFile("/tmp/dat")
         check(err)
         fmt.Print(string(dat))
     
    @@ -125,7 +123,7 @@ by Opening a file to obtain an os.File value.

    -
        f, err := os.Open("/tmp/dat")
    +          
        f, err := os.Open("/tmp/dat")
         check(err)
     
    @@ -141,7 +139,7 @@ actually were read.

    -
        b1 := make([]byte, 5)
    +          
        b1 := make([]byte, 5)
         n1, err := f.Read(b1)
         check(err)
         fmt.Printf("%d bytes: %s\n", n1, string(b1[:n1]))
    @@ -158,7 +156,7 @@ and Read from there.

    -
        o2, err := f.Seek(6, 0)
    +          
        o2, err := f.Seek(6, 0)
         check(err)
         b2 := make([]byte, 2)
         n2, err := f.Read(b2)
    @@ -180,7 +178,7 @@ implemented with ReadAtLeast.

    -
        o3, err := f.Seek(6, 0)
    +          
        o3, err := f.Seek(6, 0)
         check(err)
         b3 := make([]byte, 2)
         n3, err := io.ReadAtLeast(f, b3, 2)
    @@ -199,7 +197,7 @@ accomplishes this.

    -
        _, err = f.Seek(0, 0)
    +          
        _, err = f.Seek(0, 0)
         check(err)
     
    @@ -216,7 +214,7 @@ reading methods it provides.

    -
        r4 := bufio.NewReader(f)
    +          
        r4 := bufio.NewReader(f)
         b4, err := r4.Peek(5)
         check(err)
         fmt.Printf("5 bytes: %s\n", string(b4))
    @@ -234,7 +232,7 @@ be scheduled immediately after Opening with
               
               
                 
    -            
        f.Close()
    +          
        f.Close()
     }
     
    @@ -251,7 +249,7 @@ be scheduled immediately after Opening with -
    $ echo "hello" > /tmp/dat
    +          
    $ echo "hello" > /tmp/dat
     $ echo "go" >>   /tmp/dat
     $ go run reading-files.go
     hello
    @@ -272,7 +270,7 @@ be scheduled immediately after Opening with
               
               
                 
    -            
    +          
               
             
             
    @@ -287,5 +285,10 @@ be scheduled immediately after Opening with
             by Mark McGranaghan | source | license
           

    + + diff --git a/public/recursion b/public/recursion index db074e2..215d30d 100644 --- a/public/recursion +++ b/public/recursion @@ -34,7 +34,7 @@ Here’s a classic factorial example.

    - + @@ -43,10 +43,8 @@ Here’s a classic factorial example.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -58,7 +56,7 @@ Here’s a classic factorial example.

    -
    import "fmt"
    +          
    import "fmt"
     
    @@ -72,7 +70,7 @@ base case of fact(0).

    -
    func fact(n int) int {
    +          
    func fact(n int) int {
         if n == 0 {
             return 1
         }
    @@ -89,7 +87,7 @@ base case of fact(0).

    -
    func main() {
    +          
    func main() {
         fmt.Println(fact(7))
     }
     
    @@ -107,7 +105,7 @@ base case of fact(0).

    -
    $ go run recursion.go 
    +          
    $ go run recursion.go 
     5040
     
    @@ -125,5 +123,10 @@ base case of fact(0).

    by Mark McGranaghan | source | license

    + + diff --git a/public/regular-expressions b/public/regular-expressions index 237af8e..d63163e 100644 --- a/public/regular-expressions +++ b/public/regular-expressions @@ -34,7 +34,7 @@ in Go.

    - + @@ -43,10 +43,8 @@ in Go.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -58,7 +56,7 @@ in Go.

    -
    import "bytes"
    +          
    import "bytes"
     import "fmt"
     import "regexp"
     
    @@ -72,7 +70,7 @@ in Go.

    -
    func main() {
    +          
    func main() {
     
    @@ -85,7 +83,7 @@ in Go.

    -
        match, _ := regexp.MatchString("p([a-z]+)ch", "peach")
    +          
        match, _ := regexp.MatchString("p([a-z]+)ch", "peach")
         fmt.Println(match)
     
    @@ -101,7 +99,7 @@ optimized Regexp struct.

    -
        r, _ := regexp.Compile("p([a-z]+)ch")
    +          
        r, _ := regexp.Compile("p([a-z]+)ch")
     
    @@ -115,7 +113,7 @@ a match test like we saw earlier.

    -
        fmt.Println(r.MatchString("peach"))
    +          
        fmt.Println(r.MatchString("peach"))
     
    @@ -128,7 +126,7 @@ a match test like we saw earlier.

    -
        fmt.Println(r.FindString("peach punch"))
    +          
        fmt.Println(r.FindString("peach punch"))
     
    @@ -143,7 +141,7 @@ matching text.

    -
        fmt.Println(r.FindStringIndex("peach punch"))
    +          
        fmt.Println(r.FindStringIndex("peach punch"))
     
    @@ -159,7 +157,7 @@ information for both p([a-z]+)ch and ([a-z]+).

    -
        fmt.Println(r.FindStringSubmatch("peach punch"))
    +          
        fmt.Println(r.FindStringSubmatch("peach punch"))
     
    @@ -173,7 +171,7 @@ indexes of matches and submatches.

    -
        fmt.Println(r.FindStringSubmatchIndex("peach punch"))
    +          
        fmt.Println(r.FindStringSubmatchIndex("peach punch"))
     
    @@ -188,7 +186,7 @@ example to find all matches for a regexp.

    -
        fmt.Println(r.FindAllString("peach punch pinch", -1))
    +          
        fmt.Println(r.FindAllString("peach punch pinch", -1))
     
    @@ -202,7 +200,7 @@ functions we saw above as well.

    -
        fmt.Println(r.FindAllStringSubmatchIndex(
    +          
        fmt.Println(r.FindAllStringSubmatchIndex(
             "peach punch pinch", -1))
     
    @@ -218,7 +216,7 @@ of matches.

    -
        fmt.Println(r.FindAllString("peach punch pinch", 2))
    +          
        fmt.Println(r.FindAllString("peach punch pinch", 2))
     
    @@ -234,7 +232,7 @@ function name.

    -
        fmt.Println(r.Match([]byte("peach")))
    +          
        fmt.Println(r.Match([]byte("peach")))
     
    @@ -250,7 +248,7 @@ constants because it has 2 return values.

    -
        r = regexp.MustCompile("p([a-z]+)ch")
    +          
        r = regexp.MustCompile("p([a-z]+)ch")
         fmt.Println(r)
     
    @@ -265,7 +263,7 @@ subsets of strings with other values.

    -
        fmt.Println(r.ReplaceAllString("a peach", "<fruit>"))
    +          
        fmt.Println(r.ReplaceAllString("a peach", "<fruit>"))
     
    @@ -279,7 +277,7 @@ text with a given function.

    -
        in := []byte("a peach")
    +          
        in := []byte("a peach")
         out := r.ReplaceAllFunc(in, bytes.ToUpper)
         fmt.Println(string(out))
     }
    @@ -298,7 +296,7 @@ text with a given function.

    -
    $ go run regular-expressions.go 
    +          
    $ go run regular-expressions.go 
     true
     true
     peach
    @@ -325,7 +323,7 @@ the regexp package docs
               
               
                 
    -            
    +          
               
             
             
    @@ -340,5 +338,10 @@ the regexp package docs
             by Mark McGranaghan | source | license
           

    + + diff --git a/public/select b/public/select index af53205..8be3cf4 100644 --- a/public/select +++ b/public/select @@ -34,7 +34,7 @@ select is a powerful feature of Go.

    - + @@ -43,10 +43,8 @@ select is a powerful feature of Go.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -58,7 +56,7 @@ select is a powerful feature of Go.

    -
    import "time"
    +          
    import "time"
     import "fmt"
     
    @@ -71,7 +69,7 @@ select is a powerful feature of Go.

    -
    func main() {
    +          
    func main() {
     
    @@ -84,7 +82,7 @@ select is a powerful feature of Go.

    -
        c1 := make(chan string)
    +          
        c1 := make(chan string)
         c2 := make(chan string)
     
    @@ -100,7 +98,7 @@ executing in concurrent goroutines.

    -
        go func() {
    +          
        go func() {
             time.Sleep(1 * time.Second)
             c1 <- "one"
         }()
    @@ -121,7 +119,7 @@ simultaneously, printing each one as it arrives.

    -
        for i := 0; i < 2; i++ {
    +          
        for i := 0; i < 2; i++ {
             select {
             case msg1 := <-c1:
                 fmt.Println("received", msg1)
    @@ -147,7 +145,7 @@ expected.

    -
    $ time go run select.go 
    +          
    $ time go run select.go 
     received one
     received two
     
    @@ -164,7 +162,7 @@ concurrently.

    -
    real    0m2.245s
    +          
    real    0m2.245s
     
    @@ -181,5 +179,10 @@ concurrently.

    by Mark McGranaghan | source | license

    + + diff --git a/public/sha1-hashes b/public/sha1-hashes index f3e4155..b072bf7 100644 --- a/public/sha1-hashes +++ b/public/sha1-hashes @@ -37,7 +37,7 @@ compute SHA1 hashes in Go.

    - + @@ -46,10 +46,8 @@ compute SHA1 hashes in Go.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -63,7 +61,7 @@ compute SHA1 hashes in Go.

    -
    import "crypto/sha1"
    +          
    import "crypto/sha1"
     import "fmt"
     
    @@ -76,7 +74,7 @@ compute SHA1 hashes in Go.

    -
    func main() {
    +          
    func main() {
         s := "sha1 this string"
     
    @@ -92,7 +90,7 @@ Here we start with a new hash.

    -
        h := sha1.New()
    +          
        h := sha1.New()
     
    @@ -106,7 +104,7 @@ use []byte(s) to coerce it to bytes.

    -
        h.Write([]byte(s))
    +          
        h.Write([]byte(s))
     
    @@ -121,7 +119,7 @@ to an existing byte slice: it usually isn’t needed.

    -
        bs := h.Sum(nil)
    +          
        bs := h.Sum(nil)
     
    @@ -136,7 +134,7 @@ a hash results to a hex string.

    -
        fmt.Println(s)
    +          
        fmt.Println(s)
         fmt.Printf("%x\n", bs)
     }
     
    @@ -156,7 +154,7 @@ a human-readable hex format.

    -
    $ go run sha1-hashes.go
    +          
    $ go run sha1-hashes.go
     sha1 this string
     cf23df2207d99a74fbe169e3eba035e633b65d94
     
    @@ -173,7 +171,7 @@ import crypto/md5 and use md5.New().

    - + @@ -186,7 +184,7 @@ you should carefully research - + @@ -201,5 +199,10 @@ you should carefully research by Mark McGranaghan | source | license

    + + diff --git a/public/signals b/public/signals index 9a1d9f5..28c2b5a 100644 --- a/public/signals +++ b/public/signals @@ -37,7 +37,7 @@ Here’s how to handle signals in Go with channels.

    - + @@ -46,10 +46,8 @@ Here’s how to handle signals in Go with channels.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -61,7 +59,7 @@ Here’s how to handle signals in Go with channels.

    -
    import "fmt"
    +          
    import "fmt"
     import "os"
     import "os/signal"
     import "syscall"
    @@ -76,7 +74,7 @@ Here’s how to handle signals in Go with channels.

    -
    func main() {
    +          
    func main() {
     
    @@ -92,7 +90,7 @@ notify us when the program can exit).

    -
        sigs := make(chan os.Signal, 1)
    +          
        sigs := make(chan os.Signal, 1)
         done := make(chan bool, 1)
     
    @@ -107,7 +105,7 @@ receive notifications of the specified signals.

    -
        signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
    +          
        signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
     
    @@ -122,7 +120,7 @@ and then notify the program that it can finish.

    -
        go func() {
    +          
        go func() {
             sig := <-sigs
             fmt.Println()
             fmt.Println(sig)
    @@ -142,7 +140,7 @@ above sending a value on done) and then exit.

    -
        fmt.Println("awaiting signal")
    +          
        fmt.Println("awaiting signal")
         <-done
         fmt.Println("exiting")
     }
    @@ -165,7 +163,7 @@ causing the program to print interrupt and then exit.

    -
    $ go run signals.go
    +          
    $ go run signals.go
     awaiting signal
     ^C
     interrupt
    @@ -186,5 +184,10 @@ causing the program to print interrupt and then exit.

    by Mark McGranaghan | source | license

    + + diff --git a/public/site.css b/public/site.css index 4808e32..7e93afb 100644 --- a/public/site.css +++ b/public/site.css @@ -136,11 +136,17 @@ pre, code { font-size: 14px; line-height: 18px; font-family: 'Menlo', 'Monaco', 'Consolas', 'Lucida Console', monospace; } -img.run { +img.copy, img.run { height: 16px; width: 16px; float: right } +img.copy, img.run { + cursor: pointer; +} +img.copy { + margin-right: 4px; +} /* Syntax highlighting */ body .hll { background-color: #ffffcc } diff --git a/public/site.js b/public/site.js new file mode 100644 index 0000000..752e656 --- /dev/null +++ b/public/site.js @@ -0,0 +1,17 @@ +/*! + * clipboard.js v1.5.13 + * https://zenorocha.github.io/clipboard.js + * + * Licensed MIT © Zeno Rocha + */ +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Clipboard=t()}}(function(){var t,e,n;return function t(e,n,o){function r(c,a){if(!n[c]){if(!e[c]){var l="function"==typeof require&&require;if(!a&&l)return l(c,!0);if(i)return i(c,!0);var s=new Error("Cannot find module '"+c+"'");throw s.code="MODULE_NOT_FOUND",s}var u=n[c]={exports:{}};e[c][0].call(u.exports,function(t){var n=e[c][1][t];return r(n?n:t)},u,u.exports,t,e,n,o)}return n[c].exports}for(var i="function"==typeof require&&require,c=0;c - + @@ -42,10 +42,8 @@ powerful interface to sequences than arrays.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -57,7 +55,7 @@ powerful interface to sequences than arrays.

    -
    import "fmt"
    +          
    import "fmt"
     
    @@ -69,7 +67,7 @@ powerful interface to sequences than arrays.

    -
    func main() {
    +          
    func main() {
     
    @@ -86,7 +84,7 @@ the builtin make. Here we make a slice of -
        s := make([]string, 3)
    +          
        s := make([]string, 3)
         fmt.Println("emp:", s)
     
    @@ -100,7 +98,7 @@ the builtin make. Here we make a slice of -
        s[0] = "a"
    +          
        s[0] = "a"
         s[1] = "b"
         s[2] = "c"
         fmt.Println("set:", s)
    @@ -117,7 +115,7 @@ the builtin make. Here we make a slice of
               
               
                 
    -            
        fmt.Println("len:", len(s))
    +          
        fmt.Println("len:", len(s))
     
    @@ -135,7 +133,7 @@ Note that we need to accept a return value from -
        s = append(s, "d")
    +          
        s = append(s, "d")
         s = append(s, "e", "f")
         fmt.Println("apd:", s)
     
    @@ -152,7 +150,7 @@ into c from s.

    -
        c := make([]string, len(s))
    +          
        c := make([]string, len(s))
         copy(c, s)
         fmt.Println("cpy:", c)
     
    @@ -169,7 +167,7 @@ of the elements s[2], s[3], and s[4].

    -
        l := s[2:5]
    +          
        l := s[2:5]
         fmt.Println("sl1:", l)
     
    @@ -183,7 +181,7 @@ of the elements s[2], s[3], and s[4].

    -
        l = s[:5]
    +          
        l = s[:5]
         fmt.Println("sl2:", l)
     
    @@ -197,7 +195,7 @@ of the elements s[2], s[3], and s[4].

    -
        l = s[2:]
    +          
        l = s[2:]
         fmt.Println("sl3:", l)
     
    @@ -212,7 +210,7 @@ in a single line as well.

    -
        t := []string{"g", "h", "i"}
    +          
        t := []string{"g", "h", "i"}
         fmt.Println("dcl:", t)
     
    @@ -228,7 +226,7 @@ vary, unlike with multi-dimensional arrays.

    -
        twoD := make([][]int, 3)
    +          
        twoD := make([][]int, 3)
         for i := 0; i < 3; i++ {
             innerLen := i + 1
             twoD[i] = make([]int, innerLen)
    @@ -255,7 +253,7 @@ they are rendered similarly by fmt.Println.

    -
    $ go run slices.go
    +          
    $ go run slices.go
     emp: [  ]
     set: [a b c]
     get: c
    @@ -281,7 +279,7 @@ implementation of slices in Go.

    - + @@ -293,7 +291,7 @@ Go’s other key builtin data structure: maps.

    - + @@ -308,5 +306,10 @@ Go’s other key builtin data structure: maps.

    by Mark McGranaghan | source | license

    + + diff --git a/public/sorting b/public/sorting index 219bc63..b52d375 100644 --- a/public/sorting +++ b/public/sorting @@ -34,7 +34,7 @@ builtins first.

    - + @@ -43,10 +43,8 @@ builtins first.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -58,7 +56,7 @@ builtins first.

    -
    import "fmt"
    +          
    import "fmt"
     import "sort"
     
    @@ -71,7 +69,7 @@ builtins first.

    -
    func main() {
    +          
    func main() {
     
    @@ -87,7 +85,7 @@ return a new one.

    -
        strs := []string{"c", "a", "b"}
    +          
        strs := []string{"c", "a", "b"}
         sort.Strings(strs)
         fmt.Println("Strings:", strs)
     
    @@ -102,7 +100,7 @@ return a new one.

    -
        ints := []int{7, 2, 4}
    +          
        ints := []int{7, 2, 4}
         sort.Ints(ints)
         fmt.Println("Ints:   ", ints)
     
    @@ -118,7 +116,7 @@ already in sorted order.

    -
        s := sort.IntsAreSorted(ints)
    +          
        s := sort.IntsAreSorted(ints)
         fmt.Println("Sorted: ", s)
     }
     
    @@ -138,7 +136,7 @@ slices and true as the result of our AreSorted test. -
    $ go run sorting.go
    +          
    $ go run sorting.go
     Strings: [a b c]
     Ints:    [2 4 7]
     Sorted:  true
    @@ -158,5 +156,10 @@ slices and true as the result of our AreSorted test.Mark McGranaghan | source | license
           

    + + diff --git a/public/sorting-by-functions b/public/sorting-by-functions index a2efcc8..904dbf5 100644 --- a/public/sorting-by-functions +++ b/public/sorting-by-functions @@ -36,7 +36,7 @@ in Go.

    - + @@ -45,10 +45,8 @@ in Go.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -60,7 +58,7 @@ in Go.

    -
    import "sort"
    +          
    import "sort"
     import "fmt"
     
    @@ -77,7 +75,7 @@ type.

    -
    type byLength []string
    +          
    type byLength []string
     
    @@ -96,7 +94,7 @@ we use len(s[i]) and len(s[j]) here.

    -
    func (s byLength) Len() int {
    +          
    func (s byLength) Len() int {
         return len(s)
     }
     func (s byLength) Swap(i, j int) {
    @@ -120,7 +118,7 @@ slice.

    -
    func main() {
    +          
    func main() {
         fruits := []string{"peach", "banana", "kiwi"}
         sort.Sort(byLength(fruits))
         fmt.Println(fruits)
    @@ -142,7 +140,7 @@ length, as desired.

    -
    $ go run sorting-by-functions.go 
    +          
    $ go run sorting-by-functions.go 
     [kiwi peach banana]
     
    @@ -160,7 +158,7 @@ functions.

    - + @@ -175,5 +173,10 @@ functions.

    by Mark McGranaghan | source | license

    + + diff --git a/public/spawning-processes b/public/spawning-processes index d8396b9..634bd69 100644 --- a/public/spawning-processes +++ b/public/spawning-processes @@ -37,7 +37,7 @@ of spawning processes from Go.

    - + @@ -46,10 +46,8 @@ of spawning processes from Go.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -61,7 +59,7 @@ of spawning processes from Go.

    -
    import "fmt"
    +          
    import "fmt"
     import "io/ioutil"
     import "os/exec"
     
    @@ -75,7 +73,7 @@ of spawning processes from Go.

    -
    func main() {
    +          
    func main() {
     
    @@ -91,7 +89,7 @@ to represent this external process.

    -
        dateCmd := exec.Command("date")
    +          
        dateCmd := exec.Command("date")
     
    @@ -107,7 +105,7 @@ and collecting its output. If there were no errors, -
        dateOut, err := dateCmd.Output()
    +          
        dateOut, err := dateCmd.Output()
         if err != nil {
             panic(err)
         }
    @@ -127,7 +125,7 @@ where we pipe data to the external process on its
               
               
                 
    -            
        grepCmd := exec.Command("grep", "hello")
    +          
        grepCmd := exec.Command("grep", "hello")
     
    @@ -143,7 +141,7 @@ to exit.

    -
        grepIn, _ := grepCmd.StdinPipe()
    +          
        grepIn, _ := grepCmd.StdinPipe()
         grepOut, _ := grepCmd.StdoutPipe()
         grepCmd.Start()
         grepIn.Write([]byte("hello grep\ngoodbye grep"))
    @@ -166,7 +164,7 @@ exactly the same way.

    -
        fmt.Println("> grep hello")
    +          
        fmt.Println("> grep hello")
         fmt.Println(string(grepBytes))
     
    @@ -185,7 +183,7 @@ option:

    -
        lsCmd := exec.Command("bash", "-c", "ls -a -l -h")
    +          
        lsCmd := exec.Command("bash", "-c", "ls -a -l -h")
         lsOut, err := lsCmd.Output()
         if err != nil {
             panic(err)
    @@ -210,7 +208,7 @@ as if we had run them directly from the command-line.

    -
    $ go run spawning-processes.go 
    +          
    $ go run spawning-processes.go 
     > date
     Wed Oct 10 09:53:11 PDT 2012
     
    @@ -224,7 +222,7 @@ as if we had run them directly from the command-line.

    -
    > grep hello
    +          
    > grep hello
     hello grep
     
    @@ -237,7 +235,7 @@ as if we had run them directly from the command-line.

    -
    > ls -a -l -h
    +          
    > 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 ..
     -rw-r--r--  1 mark 1.3K Oct 3 16:28 spawning-processes.go
    @@ -257,5 +255,10 @@ as if we had run them directly from the command-line.

    by Mark McGranaghan | source | license

    + + diff --git a/public/stateful-goroutines b/public/stateful-goroutines index da6329c..80ad0ba 100644 --- a/public/stateful-goroutines +++ b/public/stateful-goroutines @@ -39,7 +39,7 @@ by exactly 1 goroutine.

    - + @@ -48,10 +48,8 @@ by exactly 1 goroutine.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -63,7 +61,7 @@ by exactly 1 goroutine.

    -
    import (
    +          
    import (
         "fmt"
         "math/rand"
         "sync/atomic"
    @@ -88,7 +86,7 @@ goroutine to respond.

    -
    type readOp struct {
    +          
    type readOp struct {
         key  int
         resp chan int
     }
    @@ -108,7 +106,7 @@ goroutine to respond.

    -
    func main() {
    +          
    func main() {
     
    @@ -121,7 +119,7 @@ goroutine to respond.

    -
        var readOps uint64
    +          
        var readOps uint64
         var writeOps uint64
     
    @@ -137,7 +135,7 @@ respectively.

    -
        reads := make(chan readOp)
    +          
        reads := make(chan readOp)
         writes := make(chan writeOp)
     
    @@ -159,7 +157,7 @@ value in the case of reads).

    -
        go func() {
    +          
        go func() {
             var state = make(map[int]int)
             for {
                 select {
    @@ -187,7 +185,7 @@ result over the provided resp channel.

    -
        for r := 0; r < 100; r++ {
    +          
        for r := 0; r < 100; r++ {
             go func() {
                 for {
                     read := readOp{
    @@ -213,7 +211,7 @@ approach.

    -
        for w := 0; w < 10; w++ {
    +          
        for w := 0; w < 10; w++ {
             go func() {
                 for {
                     write := writeOp{
    @@ -239,7 +237,7 @@ approach.

    -
        time.Sleep(time.Second)
    +          
        time.Sleep(time.Second)
     
    @@ -252,7 +250,7 @@ approach.

    -
        readOpsFinal := atomic.LoadUint64(&readOps)
    +          
        readOpsFinal := atomic.LoadUint64(&readOps)
         fmt.Println("readOps:", readOpsFinal)
         writeOpsFinal := atomic.LoadUint64(&writeOps)
         fmt.Println("writeOps:", writeOpsFinal)
    @@ -275,7 +273,7 @@ total operations.

    -
    $ go run stateful-goroutines.go
    +          
    $ go run stateful-goroutines.go
     readOps: 71708
     writeOps: 7177
     
    @@ -297,7 +295,7 @@ program.

    - + @@ -312,5 +310,10 @@ program.

    by Mark McGranaghan | source | license

    + + diff --git a/public/string-formatting b/public/string-formatting index c0652e6..438e9a5 100644 --- a/public/string-formatting +++ b/public/string-formatting @@ -34,7 +34,7 @@ common string formatting tasks.

    - + @@ -43,10 +43,8 @@ common string formatting tasks.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -58,7 +56,7 @@ common string formatting tasks.

    -
    import "fmt"
    +          
    import "fmt"
     import "os"
     
    @@ -71,7 +69,7 @@ common string formatting tasks.

    -
    type point struct {
    +          
    type point struct {
         x, y int
     }
     
    @@ -85,7 +83,7 @@ common string formatting tasks.

    -
    func main() {
    +          
    func main() {
     
    @@ -100,7 +98,7 @@ an instance of our point struct.

    -
        p := point{1, 2}
    +          
        p := point{1, 2}
         fmt.Printf("%v\n", p)
     
    @@ -115,7 +113,7 @@ include the struct’s field names.

    -
        fmt.Printf("%+v\n", p)
    +          
        fmt.Printf("%+v\n", p)
     
    @@ -130,7 +128,7 @@ would produce that value.

    -
        fmt.Printf("%#v\n", p)
    +          
        fmt.Printf("%#v\n", p)
     
    @@ -143,7 +141,7 @@ would produce that value.

    -
        fmt.Printf("%T\n", p)
    +          
        fmt.Printf("%T\n", p)
     
    @@ -156,7 +154,7 @@ would produce that value.

    -
        fmt.Printf("%t\n", true)
    +          
        fmt.Printf("%t\n", true)
     
    @@ -170,7 +168,7 @@ Use %d for standard, base-10 formatting.

    -
        fmt.Printf("%d\n", 123)
    +          
        fmt.Printf("%d\n", 123)
     
    @@ -183,7 +181,7 @@ Use %d for standard, base-10 formatting.

    -
        fmt.Printf("%b\n", 14)
    +          
        fmt.Printf("%b\n", 14)
     
    @@ -197,7 +195,7 @@ given integer.

    -
        fmt.Printf("%c\n", 33)
    +          
        fmt.Printf("%c\n", 33)
     
    @@ -210,7 +208,7 @@ given integer.

    -
        fmt.Printf("%x\n", 456)
    +          
        fmt.Printf("%x\n", 456)
     
    @@ -224,7 +222,7 @@ floats. For basic decimal formatting use %f.

    -
        fmt.Printf("%f\n", 78.9)
    +          
        fmt.Printf("%f\n", 78.9)
     
    @@ -238,7 +236,7 @@ different versions of) scientific notation.

    -
        fmt.Printf("%e\n", 123400000.0)
    +          
        fmt.Printf("%e\n", 123400000.0)
         fmt.Printf("%E\n", 123400000.0)
     
    @@ -252,7 +250,7 @@ different versions of) scientific notation.

    -
        fmt.Printf("%s\n", "\"string\"")
    +          
        fmt.Printf("%s\n", "\"string\"")
     
    @@ -265,7 +263,7 @@ different versions of) scientific notation.

    -
        fmt.Printf("%q\n", "\"string\"")
    +          
        fmt.Printf("%q\n", "\"string\"")
     
    @@ -280,7 +278,7 @@ per byte of input.

    -
        fmt.Printf("%x\n", "hex this")
    +          
        fmt.Printf("%x\n", "hex this")
     
    @@ -293,7 +291,7 @@ per byte of input.

    -
        fmt.Printf("%p\n", &p)
    +          
        fmt.Printf("%p\n", &p)
     
    @@ -311,7 +309,7 @@ spaces.

    -
        fmt.Printf("|%6d|%6d|\n", 12, 345)
    +          
        fmt.Printf("|%6d|%6d|\n", 12, 345)
     
    @@ -327,7 +325,7 @@ width.precision syntax.

    -
        fmt.Printf("|%6.2f|%6.2f|\n", 1.2, 3.45)
    +          
        fmt.Printf("|%6.2f|%6.2f|\n", 1.2, 3.45)
     
    @@ -340,7 +338,7 @@ width.precision syntax.

    -
        fmt.Printf("|%-6.2f|%-6.2f|\n", 1.2, 3.45)
    +          
        fmt.Printf("|%-6.2f|%-6.2f|\n", 1.2, 3.45)
     
    @@ -355,7 +353,7 @@ table-like output. For basic right-justified width.

    -
        fmt.Printf("|%6s|%6s|\n", "foo", "b")
    +          
        fmt.Printf("|%6s|%6s|\n", "foo", "b")
     
    @@ -368,7 +366,7 @@ table-like output. For basic right-justified width.

    -
        fmt.Printf("|%-6s|%-6s|\n", "foo", "b")
    +          
        fmt.Printf("|%-6s|%-6s|\n", "foo", "b")
     
    @@ -383,7 +381,7 @@ and returns a string without printing it anywhere.

    -
        s := fmt.Sprintf("a %s", "string")
    +          
        s := fmt.Sprintf("a %s", "string")
         fmt.Println(s)
     
    @@ -398,7 +396,7 @@ and returns a string without printing it anywhere.

    -
        fmt.Fprintf(os.Stderr, "an %s\n", "error")
    +          
        fmt.Fprintf(os.Stderr, "an %s\n", "error")
     }
     
    @@ -415,7 +413,7 @@ and returns a string without printing it anywhere.

    -
    $ go run string-formatting.go
    +          
    $ go run string-formatting.go
     {1 2}
     {x:1 y:2}
     main.point{x:1, y:2}
    @@ -455,5 +453,10 @@ and returns a string without printing it anywhere.

    by Mark McGranaghan | source | license

    + + diff --git a/public/string-functions b/public/string-functions index 4882c60..05a6e1c 100644 --- a/public/string-functions +++ b/public/string-functions @@ -34,7 +34,7 @@ to give you a sense of the package.

    - + @@ -43,10 +43,8 @@ to give you a sense of the package.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -58,7 +56,7 @@ to give you a sense of the package.

    -
    import s "strings"
    +          
    import s "strings"
     import "fmt"
     
    @@ -73,7 +71,7 @@ it a lot below.

    -
    var p = fmt.Println
    +          
    var p = fmt.Println
     
    @@ -85,7 +83,7 @@ it a lot below.

    -
    func main() {
    +          
    func main() {
     
    @@ -104,7 +102,7 @@ package docs.

    -
        p("Contains:  ", s.Contains("test", "es"))
    +          
        p("Contains:  ", s.Contains("test", "es"))
         p("Count:     ", s.Count("test", "t"))
         p("HasPrefix: ", s.HasPrefix("test", "te"))
         p("HasSuffix: ", s.HasSuffix("test", "st"))
    @@ -131,7 +129,7 @@ bytes and getting a byte by index.

    -
        p("Len: ", len("hello"))
    +          
        p("Len: ", len("hello"))
         p("Char:", "hello"[1])
     }
     
    @@ -151,7 +149,7 @@ for more information.

    - + @@ -165,7 +163,7 @@ for more information.

    -
    $ go run string-functions.go
    +          
    $ go run string-functions.go
     Contains:   true
     Count:      2
     HasPrefix:  true
    @@ -189,7 +187,7 @@ for more information.

    -
    Len:  5
    +          
    Len:  5
     Char: 101
     
    @@ -207,5 +205,10 @@ for more information.

    by Mark McGranaghan | source | license

    + + diff --git a/public/structs b/public/structs index b550a3c..672b214 100644 --- a/public/structs +++ b/public/structs @@ -34,7 +34,7 @@ records.

    - + @@ -43,10 +43,8 @@ records.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -58,7 +56,7 @@ records.

    -
    import "fmt"
    +          
    import "fmt"
     
    @@ -71,7 +69,7 @@ records.

    -
    type person struct {
    +          
    type person struct {
         name string
         age  int
     }
    @@ -87,7 +85,7 @@ records.

    -
    func NewPerson(name string) *person {
    +          
    func NewPerson(name string) *person {
     
    @@ -101,7 +99,7 @@ as a local variable will survive the scope of the function.

    -
        p := person{name: name}
    +          
        p := person{name: name}
         p.age = 42
         return &p
     }
    @@ -116,7 +114,7 @@ as a local variable will survive the scope of the function.

    -
    func main() {
    +          
    func main() {
     
    @@ -129,7 +127,7 @@ as a local variable will survive the scope of the function.

    -
        fmt.Println(person{"Bob", 20})
    +          
        fmt.Println(person{"Bob", 20})
     
    @@ -142,7 +140,7 @@ as a local variable will survive the scope of the function.

    -
        fmt.Println(person{name: "Alice", age: 30})
    +          
        fmt.Println(person{name: "Alice", age: 30})
     
    @@ -155,7 +153,7 @@ as a local variable will survive the scope of the function.

    -
        fmt.Println(person{name: "Fred"})
    +          
        fmt.Println(person{name: "Fred"})
     
    @@ -168,7 +166,7 @@ as a local variable will survive the scope of the function.

    -
        fmt.Println(&person{name: "Ann", age: 40})
    +          
        fmt.Println(&person{name: "Ann", age: 40})
     
    @@ -181,7 +179,7 @@ as a local variable will survive the scope of the function.

    -
        fmt.Println(NewPerson("Jon"))
    +          
        fmt.Println(NewPerson("Jon"))
     
    @@ -194,7 +192,7 @@ as a local variable will survive the scope of the function.

    -
        s := person{name: "Sean", age: 50}
    +          
        s := person{name: "Sean", age: 50}
         fmt.Println(s.name)
     
    @@ -209,7 +207,7 @@ pointers are automatically dereferenced.

    -
        sp := &s
    +          
        sp := &s
         fmt.Println(sp.age)
     
    @@ -223,7 +221,7 @@ pointers are automatically dereferenced.

    -
        sp.age = 51
    +          
        sp.age = 51
         fmt.Println(sp.age)
     }
     
    @@ -241,7 +239,7 @@ pointers are automatically dereferenced.

    -
    $ go run structs.go
    +          
    $ go run structs.go
     {Bob 20}
     {Alice 30}
     {Fred 0}
    @@ -266,5 +264,10 @@ pointers are automatically dereferenced.

    by Mark McGranaghan | source | license

    + + diff --git a/public/switch b/public/switch index fae75e8..a93cff8 100644 --- a/public/switch +++ b/public/switch @@ -33,7 +33,7 @@ branches.

    - + @@ -42,10 +42,8 @@ branches.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -57,7 +55,7 @@ branches.

    -
    import "fmt"
    +          
    import "fmt"
     import "time"
     
    @@ -70,7 +68,7 @@ branches.

    -
    func main() {
    +          
    func main() {
     
    @@ -83,7 +81,7 @@ branches.

    -
        i := 2
    +          
        i := 2
         fmt.Print("Write ", i, " as ")
         switch i {
         case 1:
    @@ -107,7 +105,7 @@ in the same case statement. We use the optional
               
               
                 
    -            
        switch time.Now().Weekday() {
    +          
        switch time.Now().Weekday() {
         case time.Saturday, time.Sunday:
             fmt.Println("It's the weekend")
         default:
    @@ -127,7 +125,7 @@ to express if/else logic. Here we also show how the
               
               
                 
    -            
        t := time.Now()
    +          
        t := time.Now()
         switch {
         case t.Hour() < 12:
             fmt.Println("It's before noon")
    @@ -149,7 +147,7 @@ type corresponding to its clause.

    -
        whatAmI := func(i interface{}) {
    +          
        whatAmI := func(i interface{}) {
             switch t := i.(type) {
             case bool:
                 fmt.Println("I'm a bool")
    @@ -178,7 +176,7 @@ type corresponding to its clause.

    -
    $ go run switch.go 
    +          
    $ go run switch.go 
     Write 2 as two
     It's a weekday
     It's after noon
    @@ -201,5 +199,10 @@ type corresponding to its clause.

    by Mark McGranaghan | source | license

    + + diff --git a/public/temporary-files-and-directories b/public/temporary-files-and-directories index ce479ca..37d7831 100644 --- a/public/temporary-files-and-directories +++ b/public/temporary-files-and-directories @@ -36,7 +36,7 @@ time.

    - + @@ -45,10 +45,8 @@ time.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -60,7 +58,7 @@ time.

    -
    import (
    +          
    import (
         "fmt"
         "io/ioutil"
         "os"
    @@ -77,7 +75,7 @@ time.

    -
    func check(e error) {
    +          
    func check(e error) {
         if e != nil {
             panic(e)
         }
    @@ -93,7 +91,7 @@ time.

    -
    func main() {
    +          
    func main() {
     
    @@ -110,7 +108,7 @@ create the file in the default location for our OS.

    -
        f, err := ioutil.TempFile("", "sample")
    +          
        f, err := ioutil.TempFile("", "sample")
         check(err)
     
    @@ -129,7 +127,7 @@ calls will always create different file names.

    -
        fmt.Println("Temp file name:", f.Name())
    +          
        fmt.Println("Temp file name:", f.Name())
     
    @@ -145,7 +143,7 @@ explicitly.

    -
        defer os.Remove(f.Name())
    +          
        defer os.Remove(f.Name())
     
    @@ -158,7 +156,7 @@ explicitly.

    -
        _, err = f.Write([]byte{1, 2, 3, 4})
    +          
        _, err = f.Write([]byte{1, 2, 3, 4})
         check(err)
     
    @@ -176,7 +174,7 @@ rather than an open file.

    -
        dname, err := ioutil.TempDir("", "sampledir")
    +          
        dname, err := ioutil.TempDir("", "sampledir")
         fmt.Println("Temp dir name:", dname)
     
    @@ -189,7 +187,7 @@ rather than an open file.

    -
        defer os.RemoveAll(dname)
    +          
        defer os.RemoveAll(dname)
     
    @@ -203,7 +201,7 @@ prefixing them with our temporary directory.

    -
        fname := filepath.Join(dname, "file1")
    +          
        fname := filepath.Join(dname, "file1")
         err = ioutil.WriteFile(fname, []byte{1, 2}, 0666)
         check(err)
     }
    @@ -222,7 +220,7 @@ prefixing them with our temporary directory.

    -
    $ go run temporary-files-and-directories.go
    +          
    $ go run temporary-files-and-directories.go
     Temp file name: /tmp/sample610887201
     Temp dir name: /tmp/sampledir898854668
     
    @@ -241,5 +239,10 @@ prefixing them with our temporary directory.

    by Mark McGranaghan | source | license

    + + diff --git a/public/tickers b/public/tickers index 286dfff..2210a6a 100644 --- a/public/tickers +++ b/public/tickers @@ -36,7 +36,7 @@ periodically until we stop it.

    - + @@ -45,10 +45,8 @@ periodically until we stop it.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -60,7 +58,7 @@ periodically until we stop it.

    -
    import "time"
    +          
    import "time"
     import "fmt"
     
    @@ -73,7 +71,7 @@ periodically until we stop it.

    -
    func main() {
    +          
    func main() {
     
    @@ -89,7 +87,7 @@ the values as they arrive every 500ms.

    -
        ticker := time.NewTicker(500 * time.Millisecond)
    +          
        ticker := time.NewTicker(500 * time.Millisecond)
         go func() {
             for t := range ticker.C {
                 fmt.Println("Tick at", t)
    @@ -109,7 +107,7 @@ channel. We’ll stop ours after 1600ms.

    -
        time.Sleep(1600 * time.Millisecond)
    +          
        time.Sleep(1600 * time.Millisecond)
         ticker.Stop()
         fmt.Println("Ticker stopped")
     }
    @@ -130,7 +128,7 @@ before we stop it.

    -
    $ go run tickers.go
    +          
    $ 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
     Tick at 2012-09-23 11:29:57.488076 -0700 PDT
    @@ -151,5 +149,10 @@ before we stop it.

    by Mark McGranaghan | source | license

    + + diff --git a/public/time b/public/time index 90fbf1f..3c6f1b2 100644 --- a/public/time +++ b/public/time @@ -33,7 +33,7 @@ here are some examples.

    - + @@ -42,10 +42,8 @@ here are some examples.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -57,7 +55,7 @@ here are some examples.

    -
    import "fmt"
    +          
    import "fmt"
     import "time"
     
    @@ -70,7 +68,7 @@ here are some examples.

    -
    func main() {
    +          
    func main() {
         p := fmt.Println
     
    @@ -84,7 +82,7 @@ here are some examples.

    -
        now := time.Now()
    +          
        now := time.Now()
         p(now)
     
    @@ -100,7 +98,7 @@ with a Location, i.e. time zone.

    -
        then := time.Date(
    +          
        then := time.Date(
             2009, 11, 17, 20, 34, 58, 651387237, time.UTC)
         p(then)
     
    @@ -116,7 +114,7 @@ value as expected.

    -
        p(then.Year())
    +          
        p(then.Year())
         p(then.Month())
         p(then.Day())
         p(then.Hour())
    @@ -136,7 +134,7 @@ value as expected.

    -
        p(then.Weekday())
    +          
        p(then.Weekday())
     
    @@ -151,7 +149,7 @@ as the second, respectively.

    -
        p(then.Before(now))
    +          
        p(then.Before(now))
         p(then.After(now))
         p(then.Equal(now))
     
    @@ -167,7 +165,7 @@ the interval between two times.

    -
        diff := now.Sub(then)
    +          
        diff := now.Sub(then)
         p(diff)
     
    @@ -182,7 +180,7 @@ various units.

    -
        p(diff.Hours())
    +          
        p(diff.Hours())
         p(diff.Minutes())
         p(diff.Seconds())
         p(diff.Nanoseconds())
    @@ -200,7 +198,7 @@ duration.

    -
        p(then.Add(diff))
    +          
        p(then.Add(diff))
         p(then.Add(-diff))
     }
     
    @@ -218,7 +216,7 @@ duration.

    -
    $ go run time.go
    +          
    $ go run time.go
     2012-10-31 15:50:13.793654 +0000 UTC
     2009-11-17 20:34:58.651387237 +0000 UTC
     2009
    @@ -253,7 +251,7 @@ the Unix epoch.

    - + @@ -268,5 +266,10 @@ the Unix epoch.

    by Mark McGranaghan | source | license

    + + diff --git a/public/time-formatting-parsing b/public/time-formatting-parsing index 602c729..cd8a62a 100644 --- a/public/time-formatting-parsing +++ b/public/time-formatting-parsing @@ -33,7 +33,7 @@ pattern-based layouts.

    - + @@ -42,10 +42,8 @@ pattern-based layouts.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -57,7 +55,7 @@ pattern-based layouts.

    -
    import "fmt"
    +          
    import "fmt"
     import "time"
     
    @@ -70,7 +68,7 @@ pattern-based layouts.

    -
    func main() {
    +          
    func main() {
         p := fmt.Println
     
    @@ -86,7 +84,7 @@ constant.

    -
        t := time.Now()
    +          
        t := time.Now()
         p(t.Format(time.RFC3339))
     
    @@ -100,7 +98,7 @@ constant.

    -
        t1, e := time.Parse(
    +          
        t1, e := time.Parse(
             time.RFC3339,
             "2012-11-01T22:08:41+00:00")
         p(t1)
    @@ -122,7 +120,7 @@ The example time must be exactly as shown: the year 2006,
               
               
                 
    -            
        p(t.Format("3:04PM"))
    +          
        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"))
         form := "3 04 PM"
    @@ -142,7 +140,7 @@ components of the time value.

    -
        fmt.Printf("%d-%02d-%02dT%02d:%02d:%02d-00:00\n",
    +          
        fmt.Printf("%d-%02d-%02dT%02d:%02d:%02d-00:00\n",
             t.Year(), t.Month(), t.Day(),
             t.Hour(), t.Minute(), t.Second())
     
    @@ -158,7 +156,7 @@ explaining the parsing problem.

    -
        ansic := "Mon Jan _2 15:04:05 2006"
    +          
        ansic := "Mon Jan _2 15:04:05 2006"
         _, e = time.Parse(ansic, "8:41PM")
         p(e)
     }
    @@ -177,7 +175,7 @@ explaining the parsing problem.

    -
    $ go run time-formatting-parsing.go 
    +          
    $ go run time-formatting-parsing.go 
     2014-04-15T18:00:15-07:00
     2012-11-01 22:08:41 +0000 +0000
     6:00PM
    @@ -202,5 +200,10 @@ explaining the parsing problem.

    by Mark McGranaghan | source | license

    + + diff --git a/public/timeouts b/public/timeouts index 35315f4..c00732d 100644 --- a/public/timeouts +++ b/public/timeouts @@ -35,7 +35,7 @@ elegant thanks to channels and select.

    - + @@ -44,10 +44,8 @@ elegant thanks to channels and select.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -59,7 +57,7 @@ elegant thanks to channels and select.

    -
    import "time"
    +          
    import "time"
     import "fmt"
     
    @@ -72,7 +70,7 @@ elegant thanks to channels and select.

    -
    func main() {
    +          
    func main() {
     
    @@ -87,7 +85,7 @@ after 2s.

    -
        c1 := make(chan string, 1)
    +          
        c1 := make(chan string, 1)
         go func() {
             time.Sleep(2 * time.Second)
             c1 <- "result 1"
    @@ -109,7 +107,7 @@ if the operation takes more than the allowed 1s.

    -
        select {
    +          
        select {
         case res := <-c1:
             fmt.Println(res)
         case <-time.After(1 * time.Second):
    @@ -128,7 +126,7 @@ from c2 will succeed and we’ll print the result.

    -
        c2 := make(chan string, 1)
    +          
        c2 := make(chan string, 1)
         go func() {
             time.Sleep(2 * time.Second)
             c2 <- "result 2"
    @@ -157,7 +155,7 @@ out and the second succeeding.

    -
    $ go run timeouts.go 
    +          
    $ go run timeouts.go 
     timeout 1
     result 2
     
    @@ -176,7 +174,7 @@ examples of this next: timers and tickers.

    - + @@ -191,5 +189,10 @@ examples of this next: timers and tickers.

    by Mark McGranaghan | source | license

    + + diff --git a/public/timers b/public/timers index 3ba794e..1cff001 100644 --- a/public/timers +++ b/public/timers @@ -36,7 +36,7 @@ at tickers.

    - + @@ -45,10 +45,8 @@ at tickers.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -60,7 +58,7 @@ at tickers.

    -
    import "time"
    +          
    import "time"
     import "fmt"
     
    @@ -73,7 +71,7 @@ at tickers.

    -
    func main() {
    +          
    func main() {
     
    @@ -89,7 +87,7 @@ time. This timer will wait 2 seconds.

    -
        timer1 := time.NewTimer(2 * time.Second)
    +          
        timer1 := time.NewTimer(2 * time.Second)
     
    @@ -104,7 +102,7 @@ expired.

    -
        <-timer1.C
    +          
        <-timer1.C
         fmt.Println("Timer 1 expired")
     
    @@ -121,7 +119,7 @@ Here’s an example of that.

    -
        timer2 := time.NewTimer(time.Second)
    +          
        timer2 := time.NewTimer(time.Second)
         go func() {
             <-timer2.C
             fmt.Println("Timer 2 expired")
    @@ -149,7 +147,7 @@ a chance to expire.

    -
    $ go run timers.go
    +          
    $ go run timers.go
     Timer 1 expired
     Timer 2 stopped
     
    @@ -168,5 +166,10 @@ a chance to expire.

    by Mark McGranaghan | source | license

    + + diff --git a/public/url-parsing b/public/url-parsing index 71874e9..668af2f 100644 --- a/public/url-parsing +++ b/public/url-parsing @@ -33,7 +33,7 @@ Here’s how to parse URLs in Go.

    - + @@ -42,10 +42,8 @@ Here’s how to parse URLs in Go.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -57,7 +55,7 @@ Here’s how to parse URLs in Go.

    -
    import "fmt"
    +          
    import "fmt"
     import "net"
     import "net/url"
     
    @@ -71,7 +69,7 @@ Here’s how to parse URLs in Go.

    -
    func main() {
    +          
    func main() {
     
    @@ -86,7 +84,7 @@ query params, and query fragment.

    -
        s := "postgres://user:pass@host.com:5432/path?k=v#f"
    +          
        s := "postgres://user:pass@host.com:5432/path?k=v#f"
     
    @@ -99,7 +97,7 @@ query params, and query fragment.

    -
        u, err := url.Parse(s)
    +          
        u, err := url.Parse(s)
         if err != nil {
             panic(err)
         }
    @@ -115,7 +113,7 @@ query params, and query fragment.

    -
        fmt.Println(u.Scheme)
    +          
        fmt.Println(u.Scheme)
     
    @@ -130,7 +128,7 @@ values.

    -
        fmt.Println(u.User)
    +          
        fmt.Println(u.User)
         fmt.Println(u.User.Username())
         p, _ := u.User.Password()
         fmt.Println(p)
    @@ -147,7 +145,7 @@ if present. Use SplitHostPort to extract them.

    -
        fmt.Println(u.Host)
    +          
        fmt.Println(u.Host)
         host, port, _ := net.SplitHostPort(u.Host)
         fmt.Println(host)
         fmt.Println(port)
    @@ -164,7 +162,7 @@ the #.

    -
        fmt.Println(u.Path)
    +          
        fmt.Println(u.Path)
         fmt.Println(u.Fragment)
     
    @@ -182,7 +180,7 @@ if you only want the first value.

    -
        fmt.Println(u.RawQuery)
    +          
        fmt.Println(u.RawQuery)
         m, _ := url.ParseQuery(u.RawQuery)
         fmt.Println(m)
         fmt.Println(m["k"][0])
    @@ -204,7 +202,7 @@ pieces that we extracted.

    -
    $ go run url-parsing.go 
    +          
    $ go run url-parsing.go 
     postgres
     user:pass
     user
    @@ -233,5 +231,10 @@ pieces that we extracted.

    by Mark McGranaghan | source | license

    + + diff --git a/public/values b/public/values index 648aed8..eef6bfb 100644 --- a/public/values +++ b/public/values @@ -34,7 +34,7 @@ basic examples.

    - + @@ -43,10 +43,8 @@ basic examples.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -58,7 +56,7 @@ basic examples.

    -
    import "fmt"
    +          
    import "fmt"
     
    @@ -70,7 +68,7 @@ basic examples.

    -
    func main() {
    +          
    func main() {
     
    @@ -83,7 +81,7 @@ basic examples.

    -
        fmt.Println("go" + "lang")
    +          
        fmt.Println("go" + "lang")
     
    @@ -96,7 +94,7 @@ basic examples.

    -
        fmt.Println("1+1 =", 1+1)
    +          
        fmt.Println("1+1 =", 1+1)
         fmt.Println("7.0/3.0 =", 7.0/3.0)
     
    @@ -110,7 +108,7 @@ basic examples.

    -
        fmt.Println(true && false)
    +          
        fmt.Println(true && false)
         fmt.Println(true || false)
         fmt.Println(!true)
     }
    @@ -129,7 +127,7 @@ basic examples.

    -
    $ go run values.go
    +          
    $ go run values.go
     golang
     1+1 = 2
     7.0/3.0 = 2.3333333333333335
    @@ -152,5 +150,10 @@ basic examples.

    by Mark McGranaghan | source | license

    + + diff --git a/public/variables b/public/variables index 0779d1c..8ce28a3 100644 --- a/public/variables +++ b/public/variables @@ -34,7 +34,7 @@ calls.

    - + @@ -43,10 +43,8 @@ calls.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -58,7 +56,7 @@ calls.

    -
    import "fmt"
    +          
    import "fmt"
     
    @@ -70,7 +68,7 @@ calls.

    -
    func main() {
    +          
    func main() {
     
    @@ -83,7 +81,7 @@ calls.

    -
        var a = "initial"
    +          
        var a = "initial"
         fmt.Println(a)
     
    @@ -97,7 +95,7 @@ calls.

    -
        var b, c int = 1, 2
    +          
        var b, c int = 1, 2
         fmt.Println(b, c)
     
    @@ -111,7 +109,7 @@ calls.

    -
        var d = true
    +          
        var d = true
         fmt.Println(d)
     
    @@ -127,7 +125,7 @@ zero value for an int is 0.

    -
        var e int
    +          
        var e int
         fmt.Println(e)
     
    @@ -143,7 +141,7 @@ initializing a variable, e.g. for -
        f := "apple"
    +          
        f := "apple"
         fmt.Println(f)
     }
     
    @@ -161,7 +159,7 @@ initializing a variable, e.g. for -
    $ go run variables.go
    +          
    $ go run variables.go
     initial
     1 2
     true
    @@ -183,5 +181,10 @@ initializing a variable, e.g. for
             by Mark McGranaghan | source | license
           

    + + diff --git a/public/variadic-functions b/public/variadic-functions index f0355c4..536970b 100644 --- a/public/variadic-functions +++ b/public/variadic-functions @@ -35,7 +35,7 @@ function.

    - + @@ -44,10 +44,8 @@ function.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -59,7 +57,7 @@ function.

    -
    import "fmt"
    +          
    import "fmt"
     
    @@ -73,7 +71,7 @@ of ints as arguments.

    -
    func sum(nums ...int) {
    +          
    func sum(nums ...int) {
         fmt.Print(nums, " ")
         total := 0
         for _, num := range nums {
    @@ -92,7 +90,7 @@ of ints as arguments.

    -
    func main() {
    +          
    func main() {
     
    @@ -106,7 +104,7 @@ with individual arguments.

    -
        sum(1, 2)
    +          
        sum(1, 2)
         sum(1, 2, 3)
     
    @@ -122,7 +120,7 @@ apply them to a variadic function using -
        nums := []int{1, 2, 3, 4}
    +          
        nums := []int{1, 2, 3, 4}
         sum(nums...)
     }
     
    @@ -140,7 +138,7 @@ apply them to a variadic function using -
    $ go run variadic-functions.go 
    +          
    $ go run variadic-functions.go 
     [1 2] 3
     [1 2 3] 6
     [1 2 3 4] 10
    @@ -157,7 +155,7 @@ to form closures, which we’ll look at next.

    - + @@ -172,5 +170,10 @@ to form closures, which we’ll look at next.

    by Mark McGranaghan | source | license

    + + diff --git a/public/waitgroups b/public/waitgroups index 5962f99..d8c3f13 100644 --- a/public/waitgroups +++ b/public/waitgroups @@ -33,7 +33,7 @@ use a wait group.

    - + @@ -42,10 +42,8 @@ use a wait group.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -57,7 +55,7 @@ use a wait group.

    -
    import (
    +          
    import (
         "fmt"
         "sync"
         "time"
    @@ -76,7 +74,7 @@ pointer.

    -
    func worker(id int, wg *sync.WaitGroup) {
    +          
    func worker(id int, wg *sync.WaitGroup) {
         fmt.Printf("Worker %d starting\n", id)
     
    @@ -90,7 +88,7 @@ pointer.

    -
        time.Sleep(time.Second)
    +          
        time.Sleep(time.Second)
         fmt.Printf("Worker %d done\n", id)
     
    @@ -104,7 +102,7 @@ pointer.

    -
        wg.Done()
    +          
        wg.Done()
     }
     
    @@ -117,7 +115,7 @@ pointer.

    -
    func main() {
    +          
    func main() {
     
    @@ -131,7 +129,7 @@ goroutines launched here to finish.

    -
        var wg sync.WaitGroup
    +          
        var wg sync.WaitGroup
     
    @@ -145,7 +143,7 @@ counter for each.

    -
        for i := 1; i <= 5; i++ {
    +          
        for i := 1; i <= 5; i++ {
             wg.Add(1)
             go worker(i, &wg)
         }
    @@ -162,7 +160,7 @@ all the workers notified they’re done.

    -
        wg.Wait()
    +          
        wg.Wait()
     }
     
    @@ -179,7 +177,7 @@ all the workers notified they’re done.

    -
    $ go run waitgroups.go
    +          
    $ go run waitgroups.go
     Worker 5 starting
     Worker 3 starting
     Worker 4 starting
    @@ -203,7 +201,7 @@ is likely to be different for each invocation.

    - + @@ -218,5 +216,10 @@ is likely to be different for each invocation.

    by Mark McGranaghan | source | license

    + + diff --git a/public/worker-pools b/public/worker-pools index ddabd53..0ddf1b3 100644 --- a/public/worker-pools +++ b/public/worker-pools @@ -33,7 +33,7 @@ a worker pool using goroutines and channels.

    - + @@ -42,10 +42,8 @@ a worker pool using goroutines and channels.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -57,7 +55,7 @@ a worker pool using goroutines and channels.

    -
    import "fmt"
    +          
    import "fmt"
     import "time"
     
    @@ -75,7 +73,7 @@ simulate an expensive task.

    -
    func worker(id int, jobs <-chan int, results chan<- int) {
    +          
    func worker(id int, jobs <-chan int, results chan<- int) {
         for j := range jobs {
             fmt.Println("worker", id, "started  job", j)
             time.Sleep(time.Second)
    @@ -94,7 +92,7 @@ simulate an expensive task.

    -
    func main() {
    +          
    func main() {
     
    @@ -109,7 +107,7 @@ channels for this.

    -
        jobs := make(chan int, 100)
    +          
        jobs := make(chan int, 100)
         results := make(chan int, 100)
     
    @@ -124,7 +122,7 @@ because there are no jobs yet.

    -
        for w := 1; w <= 3; w++ {
    +          
        for w := 1; w <= 3; w++ {
             go worker(w, jobs, results)
         }
     
    @@ -140,7 +138,7 @@ channel to indicate that’s all the work we have.

    -
        for j := 1; j <= 5; j++ {
    +          
        for j := 1; j <= 5; j++ {
             jobs <- j
         }
         close(jobs)
    @@ -159,7 +157,7 @@ goroutines is to use a WaitGroup.

    -
        for a := 1; a <= 5; a++ {
    +          
        for a := 1; a <= 5; a++ {
             <-results
         }
     }
    @@ -182,7 +180,7 @@ there are 3 workers operating concurrently.

    -
    $ time go run worker-pools.go 
    +          
    $ time go run worker-pools.go 
     worker 1 started  job 1
     worker 2 started  job 2
     worker 3 started  job 3
    @@ -204,7 +202,7 @@ there are 3 workers operating concurrently.

    -
    real    0m2.358s
    +          
    real    0m2.358s
     
    @@ -221,5 +219,10 @@ there are 3 workers operating concurrently.

    by Mark McGranaghan | source | license

    + + diff --git a/public/writing-files b/public/writing-files index f4dd30d..2969c77 100644 --- a/public/writing-files +++ b/public/writing-files @@ -33,7 +33,7 @@ ones we saw earlier for reading.

    - + @@ -42,10 +42,8 @@ ones we saw earlier for reading.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -57,7 +55,7 @@ ones we saw earlier for reading.

    -
    import (
    +          
    import (
         "bufio"
         "fmt"
         "io/ioutil"
    @@ -74,7 +72,7 @@ ones we saw earlier for reading.

    -
    func check(e error) {
    +          
    func check(e error) {
         if e != nil {
             panic(e)
         }
    @@ -90,7 +88,7 @@ ones we saw earlier for reading.

    -
    func main() {
    +          
    func main() {
     
    @@ -104,7 +102,7 @@ bytes) into a file.

    -
        d1 := []byte("hello\ngo\n")
    +          
        d1 := []byte("hello\ngo\n")
         err := ioutil.WriteFile("/tmp/dat1", d1, 0644)
         check(err)
     
    @@ -119,7 +117,7 @@ bytes) into a file.

    -
        f, err := os.Create("/tmp/dat2")
    +          
        f, err := os.Create("/tmp/dat2")
         check(err)
     
    @@ -134,7 +132,7 @@ after opening a file.

    -
        defer f.Close()
    +          
        defer f.Close()
     
    @@ -147,7 +145,7 @@ after opening a file.

    -
        d2 := []byte{115, 111, 109, 101, 10}
    +          
        d2 := []byte{115, 111, 109, 101, 10}
         n2, err := f.Write(d2)
         check(err)
         fmt.Printf("wrote %d bytes\n", n2)
    @@ -163,7 +161,7 @@ after opening a file.

    -
        n3, err := f.WriteString("writes\n")
    +          
        n3, err := f.WriteString("writes\n")
         fmt.Printf("wrote %d bytes\n", n3)
     
    @@ -177,7 +175,7 @@ after opening a file.

    -
        f.Sync()
    +          
        f.Sync()
     
    @@ -191,7 +189,7 @@ to the buffered readers we saw earlier.

    -
        w := bufio.NewWriter(f)
    +          
        w := bufio.NewWriter(f)
         n4, err := w.WriteString("buffered\n")
         fmt.Printf("wrote %d bytes\n", n4)
     
    @@ -207,7 +205,7 @@ been applied to the underlying writer.

    -
        w.Flush()
    +          
        w.Flush()
     
    @@ -219,7 +217,7 @@ been applied to the underlying writer.

    -
    }
    +          
    }
     
    @@ -236,7 +234,7 @@ been applied to the underlying writer.

    -
    $ go run writing-files.go 
    +          
    $ go run writing-files.go 
     wrote 5 bytes
     wrote 7 bytes
     wrote 9 bytes
    @@ -252,7 +250,7 @@ been applied to the underlying writer.

    -
    $ cat /tmp/dat1
    +          
    $ cat /tmp/dat1
     hello
     go
     $ cat /tmp/dat2
    @@ -272,7 +270,7 @@ we’ve just seen to the stdin and stdout streams.
               
               
                 
    -            
    +          
               
             
             
    @@ -287,5 +285,10 @@ we’ve just seen to the stdin and stdout streams.
             by Mark McGranaghan | source | license
           

    + + diff --git a/templates/example.tmpl b/templates/example.tmpl index 088ea7f..74bdc12 100644 --- a/templates/example.tmpl +++ b/templates/example.tmpl @@ -30,8 +30,8 @@ {{.DocsRendered}} - {{if .CodeRun}}{{end}} - {{.CodeRendered}} + {{if .CodeRun}}{{end}} + {{.CodeRendered}} {{end}} @@ -48,7 +48,7 @@
    diff --git a/templates/site.css b/templates/site.css index 06d0111..7e93afb 100644 --- a/templates/site.css +++ b/templates/site.css @@ -141,9 +141,12 @@ img.copy, img.run { width: 16px; float: right } -img.copy { +img.copy, img.run { cursor: pointer; } +img.copy { + margin-right: 4px; +} /* Syntax highlighting */ body .hll { background-color: #ffffcc } diff --git a/tools/generate.go b/tools/generate.go index 91164cc..7776380 100644 --- a/tools/generate.go +++ b/tools/generate.go @@ -129,8 +129,8 @@ var dashPat = regexp.MustCompile("\\-+") // Seg is a segment of an example type Seg struct { Docs, DocsRendered string - Code, CodeRendered, CodeForJs string - CodeEmpty, CodeLeading, CodeRun bool + Code, CodeRendered, CodeForJs string + CodeEmpty, CodeLeading, CodeRun bool } // Example is info extracted from an example file @@ -224,9 +224,9 @@ func parseAndRenderSegs(sourcePath string) ([]*Seg, string) { if seg.Code != "" { seg.CodeRendered = cachedPygmentize(lexer, seg.Code) // adding the content to the js code for copying to the clipboard - if strings.HasSuffix(sourcePath, ".go") { - seg.CodeForJs = strings.Trim(seg.Code, "\n") + "\n" - } + if strings.HasSuffix(sourcePath, ".go") { + seg.CodeForJs = strings.Trim(seg.Code, "\n") + "\n" + } } } // we are only interested in the 'go' code to pass to play.golang.org From 62bfb159ac5a20c0596ab379d22514ab445f0ffe Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Thu, 11 Jul 2019 07:11:19 -0700 Subject: [PATCH 46/54] Initial code for XML sample Covers marshal/unmarshal of a simple un-nested type. No .sh file yet --- examples/xml/xml.go | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 examples/xml/xml.go diff --git a/examples/xml/xml.go b/examples/xml/xml.go new file mode 100644 index 0000000..f172bc6 --- /dev/null +++ b/examples/xml/xml.go @@ -0,0 +1,32 @@ +package main + +import ( + "encoding/xml" + "fmt" +) + +type Plant struct { + XMLName xml.Name `xml:"fruit"` + Id int `xml:"id,attr"` + Name string `xml:"name"` + Origin []string `xml:"origin"` +} + +func (p Plant) String() string { + return fmt.Sprintf("Fruit id=%v, name=%v, origin=%v", + p.Id, p.Name, p.Origin) +} + +func main() { + coffee := &Plant{Id: 27, Name: "Coffee"} + coffee.Origin = []string{"Ethiopia", "Brazil"} + + out, _ := xml.MarshalIndent(coffee, " ", " ") + fmt.Println(string(out)) + + var p Plant + if err := xml.Unmarshal(out, &p); err != nil { + panic(err) + } + fmt.Println(p) +} From c715a7efc08170ddf00dfb22532dc192a6a15623 Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Fri, 12 Jul 2019 06:43:08 -0700 Subject: [PATCH 47/54] Complete the example text, add .sh and generate page --- examples.txt | 1 + examples/xml/xml.go | 41 +++++- examples/xml/xml.hash | 2 + examples/xml/xml.sh | 29 +++++ public/index.html | 2 + public/json | 4 +- public/time | 2 +- public/xml | 285 ++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 361 insertions(+), 5 deletions(-) create mode 100644 examples/xml/xml.hash create mode 100644 examples/xml/xml.sh create mode 100644 public/xml diff --git a/examples.txt b/examples.txt index 22a2c3b..880802f 100644 --- a/examples.txt +++ b/examples.txt @@ -46,6 +46,7 @@ String Functions String Formatting Regular Expressions JSON +XML Time Epoch Time Formatting / Parsing diff --git a/examples/xml/xml.go b/examples/xml/xml.go index f172bc6..e545106 100644 --- a/examples/xml/xml.go +++ b/examples/xml/xml.go @@ -1,3 +1,6 @@ +// Go offers built-in support for XML and XML-like +// formats with the `encoding.xml` package. + package main import ( @@ -5,15 +8,22 @@ import ( "fmt" ) +// This type will be mapped to XML. Similarly to the +// JSON examples, field tags contain directives for the +// encoder and decoder. Here we use some special features +// of the XML package: the `XMLName` field name dictates +// the name of the XML element representing this struct; +// `id,attr` means that the `Id` field is an XML +// _attribute_ rather than a nested element. type Plant struct { - XMLName xml.Name `xml:"fruit"` + XMLName xml.Name `xml:"plant"` Id int `xml:"id,attr"` Name string `xml:"name"` Origin []string `xml:"origin"` } func (p Plant) String() string { - return fmt.Sprintf("Fruit id=%v, name=%v, origin=%v", + return fmt.Sprintf("Plant id=%v, name=%v, origin=%v", p.Id, p.Name, p.Origin) } @@ -21,12 +31,39 @@ func main() { coffee := &Plant{Id: 27, Name: "Coffee"} coffee.Origin = []string{"Ethiopia", "Brazil"} + // Emit XML representing our plant; using + // `MarshalIndent` to produce a more + // human-readable output. out, _ := xml.MarshalIndent(coffee, " ", " ") fmt.Println(string(out)) + // To add a generic XML header to the output, append + // it explicitly. + fmt.Println(xml.Header + string(out)) + + // Use `Unmarhshal` to parse a stream of bytes with XML + // into a data structure. If the XML is malformed or + // cannot be mapped onto Plant, a descriptive error + // will be returned. var p Plant if err := xml.Unmarshal(out, &p); err != nil { panic(err) } fmt.Println(p) + + tomato := &Plant{Id: 81, Name: "Tomato"} + tomato.Origin = []string{"Mexico", "California"} + + // The `parent>child>plant` field tag tells the encoder + // to nest all `plant`s under `...` + type Nesting struct { + XMLName xml.Name `xml:"nesting"` + Plants []*Plant `xml:"parent>child>plant"` + } + + nesting := &Nesting{} + nesting.Plants = []*Plant{coffee, tomato} + + out, _ = xml.MarshalIndent(nesting, " ", " ") + fmt.Println(string(out)) } diff --git a/examples/xml/xml.hash b/examples/xml/xml.hash new file mode 100644 index 0000000..104125d --- /dev/null +++ b/examples/xml/xml.hash @@ -0,0 +1,2 @@ +18ada773098bca38778a58b438d6af70529f18b0 +qd9Ii_3AW0s diff --git a/examples/xml/xml.sh b/examples/xml/xml.sh new file mode 100644 index 0000000..0e8d2cd --- /dev/null +++ b/examples/xml/xml.sh @@ -0,0 +1,29 @@ +$ go run xml.go + + Coffee + Ethiopia + Brazil + + + + Coffee + Ethiopia + Brazil + +Plant id=27, name=Coffee, origin=[Ethiopia Brazil] + + + + + Coffee + Ethiopia + Brazil + + + Tomato + Mexico + California + + + + diff --git a/public/index.html b/public/index.html index 8c83d38..74ff261 100644 --- a/public/index.html +++ b/public/index.html @@ -119,6 +119,8 @@
  • JSON
  • +
  • XML
  • +
  • Time
  • Epoch
  • diff --git a/public/json b/public/json index fb7b9c8..1cc92b7 100644 --- a/public/json +++ b/public/json @@ -14,7 +14,7 @@ if (e.key == "ArrowRight") { - window.location.href = 'time'; + window.location.href = 'xml'; } } @@ -392,7 +392,7 @@ for more.

    - Next example: Time. + Next example: XML.

    +

    Go by Example: XML

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    Go offers built-in support for XML and XML-like +formats with the encoding.xml package.

    + +
    + + +
    + + + + + +
    package main
    +
    + +
    + + + +
    import (
    +    "encoding/xml"
    +    "fmt"
    +)
    +
    + +
    +

    This type will be mapped to XML. Similarly to the +JSON examples, field tags contain directives for the +encoder and decoder. Here we use some special features +of the XML package: the XMLName field name dictates +the name of the XML element representing this struct; +id,attr means that the Id field is an XML +attribute rather than a nested element.

    + +
    + +
    type Plant struct {
    +    XMLName xml.Name `xml:"plant"`
    +    Id      int      `xml:"id,attr"`
    +    Name    string   `xml:"name"`
    +    Origin  []string `xml:"origin"`
    +}
    +
    + +
    + + + +
    func (p Plant) String() string {
    +    return fmt.Sprintf("Plant id=%v, name=%v, origin=%v",
    +        p.Id, p.Name, p.Origin)
    +}
    +
    + +
    + + + +
    func main() {
    +    coffee := &Plant{Id: 27, Name: "Coffee"}
    +    coffee.Origin = []string{"Ethiopia", "Brazil"}
    +
    + +
    +

    Emit XML representing our plant; using +MarshalIndent to produce a more +human-readable output.

    + +
    + +
        out, _ := xml.MarshalIndent(coffee, " ", "  ")
    +    fmt.Println(string(out))
    +
    + +
    +

    To add a generic XML header to the output, append +it explicitly.

    + +
    + +
        fmt.Println(xml.Header + string(out))
    +
    + +
    +

    Use Unmarhshal to parse a stream of bytes with XML +into a data structure. If the XML is malformed or +cannot be mapped onto Plant, a descriptive error +will be returned.

    + +
    + +
        var p Plant
    +    if err := xml.Unmarshal(out, &p); err != nil {
    +        panic(err)
    +    }
    +    fmt.Println(p)
    +
    + +
    + + + +
        tomato := &Plant{Id: 81, Name: "Tomato"}
    +    tomato.Origin = []string{"Mexico", "California"}
    +
    + +
    +

    The parent>child>plant field tag tells the encoder +to nest all plants under <parent><child>...

    + +
    + +
        type Nesting struct {
    +        XMLName xml.Name `xml:"nesting"`
    +        Plants  []*Plant `xml:"parent>child>plant"`
    +    }
    +
    + +
    + + + +
        nesting := &Nesting{}
    +    nesting.Plants = []*Plant{coffee, tomato}
    +
    + +
    + + + +
        out, _ = xml.MarshalIndent(nesting, " ", "  ")
    +    fmt.Println(string(out))
    +}
    +
    + +
    + + + + + + + + +
    + + + +
    $ go run xml.go
    + <plant id="27">
    +   <name>Coffee</name>
    +   <origin>Ethiopia</origin>
    +   <origin>Brazil</origin>
    + </plant>
    +<?xml version="1.0" encoding="UTF-8"?>
    + <plant id="27">
    +   <name>Coffee</name>
    +   <origin>Ethiopia</origin>
    +   <origin>Brazil</origin>
    + </plant>
    +Plant id=27, name=Coffee, origin=[Ethiopia Brazil]
    + <nesting>
    +   <parent>
    +     <child>
    +       <plant id="27">
    +         <name>Coffee</name>
    +         <origin>Ethiopia</origin>
    +         <origin>Brazil</origin>
    +       </plant>
    +       <plant id="81">
    +         <name>Tomato</name>
    +         <origin>Mexico</origin>
    +         <origin>California</origin>
    +       </plant>
    +     </child>
    +   </parent>
    + </nesting>
    +
    + +
    + + +

    + Next example: Time. +

    + + +
    + + From fab0a1888b481e9b722e23bbc32955d33a8ac924 Mon Sep 17 00:00:00 2001 From: Mark McGranaghan Date: Sun, 1 Sep 2019 16:13:55 -0700 Subject: [PATCH 48/54] Rengerate --- public/xml | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/public/xml b/public/xml index 0d8ce2d..e463b37 100644 --- a/public/xml +++ b/public/xml @@ -33,7 +33,7 @@ formats with the encoding.xml package.

    - + @@ -42,10 +42,8 @@ formats with the encoding.xml package.

    - - - -
    package main
    +            
    +          
    package main
     
    @@ -57,7 +55,7 @@ formats with the encoding.xml package.

    -
    import (
    +          
    import (
         "encoding/xml"
         "fmt"
     )
    @@ -79,7 +77,7 @@ the name of the XML element representing this struct;
               
               
                 
    -            
    type Plant struct {
    +          
    type Plant struct {
         XMLName xml.Name `xml:"plant"`
         Id      int      `xml:"id,attr"`
         Name    string   `xml:"name"`
    @@ -96,7 +94,7 @@ the name of the XML element representing this struct;
               
               
                 
    -            
    func (p Plant) String() string {
    +          
    func (p Plant) String() string {
         return fmt.Sprintf("Plant id=%v, name=%v, origin=%v",
             p.Id, p.Name, p.Origin)
     }
    @@ -111,7 +109,7 @@ the name of the XML element representing this struct;
               
               
                 
    -            
    func main() {
    +          
    func main() {
         coffee := &Plant{Id: 27, Name: "Coffee"}
         coffee.Origin = []string{"Ethiopia", "Brazil"}
     
    @@ -128,7 +126,7 @@ human-readable output.

    -
        out, _ := xml.MarshalIndent(coffee, " ", "  ")
    +          
        out, _ := xml.MarshalIndent(coffee, " ", "  ")
         fmt.Println(string(out))
     
    @@ -143,7 +141,7 @@ it explicitly.

    -
        fmt.Println(xml.Header + string(out))
    +          
        fmt.Println(xml.Header + string(out))
     
    @@ -159,7 +157,7 @@ will be returned.

    -
        var p Plant
    +          
        var p Plant
         if err := xml.Unmarshal(out, &p); err != nil {
             panic(err)
         }
    @@ -175,7 +173,7 @@ will be returned.

    -
        tomato := &Plant{Id: 81, Name: "Tomato"}
    +          
        tomato := &Plant{Id: 81, Name: "Tomato"}
         tomato.Origin = []string{"Mexico", "California"}
     
    @@ -190,7 +188,7 @@ to nest all plants under <parent><child>... -
        type Nesting struct {
    +          
        type Nesting struct {
             XMLName xml.Name `xml:"nesting"`
             Plants  []*Plant `xml:"parent>child>plant"`
         }
    @@ -205,7 +203,7 @@ to nest all plants under <parent><child>...
               
                 
    -            
        nesting := &Nesting{}
    +          
        nesting := &Nesting{}
         nesting.Plants = []*Plant{coffee, tomato}
     
    @@ -218,7 +216,7 @@ to nest all plants under <parent><child>... -
        out, _ = xml.MarshalIndent(nesting, " ", "  ")
    +          
        out, _ = xml.MarshalIndent(nesting, " ", "  ")
         fmt.Println(string(out))
     }
     
    @@ -236,7 +234,7 @@ to nest all plants under <parent><child>... -
    $ go run xml.go
    +          
    $ go run xml.go
      <plant id="27">
        <name>Coffee</name>
        <origin>Ethiopia</origin>
    @@ -281,5 +279,10 @@ to nest all plants under <parent><child>...Mark McGranaghan | source | license
           

    + + From a0ac6165ddcb9d1d44131451961d5a74346bc20c Mon Sep 17 00:00:00 2001 From: Mark McGranaghan Date: Sun, 1 Sep 2019 16:20:57 -0700 Subject: [PATCH 49/54] Regnerate --- examples/json/json.go | 3 ++- examples/json/json.hash | 4 ++-- public/json | 19 ++++++++++++++++--- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/examples/json/json.go b/examples/json/json.go index aaf4bac..8d443bd 100644 --- a/examples/json/json.go +++ b/examples/json/json.go @@ -14,7 +14,8 @@ type response1 struct { Page int Fruits []string } -// Only exported fields will be encoded/decoded in JSON. + +// Only exported fields will be encoded/decoded in JSON. // Fields must start with capital letters to be exported. type response2 struct { Page int `json:"page"` diff --git a/examples/json/json.hash b/examples/json/json.hash index 3acb1f6..0c3c3a1 100644 --- a/examples/json/json.hash +++ b/examples/json/json.hash @@ -1,2 +1,2 @@ -d4dc2281f64061f077d8f1e9687538f41a339b25 -xC6SHbzGBZC +6b92694b7be60cdec3e7a04e9fdbf49d5c84adb1 +63PdbTHxKJA diff --git a/public/json b/public/json index 1cc92b7..a0d6395 100644 --- a/public/json +++ b/public/json @@ -43,7 +43,7 @@ data types.

    - +
    package main
     
    @@ -76,7 +76,20 @@ decoding of custom types below.

    Page int Fruits []string } -type response2 struct { +
    + + + + + + +

    Only exported fields will be encoded/decoded in JSON. +Fields must start with capital letters to be exported.

    + + + + +
    type response2 struct {
         Page   int      `json:"page"`
         Fruits []string `json:"fruits"`
     }
    @@ -401,7 +414,7 @@ for more.

    From ef8f0e3831c3b888c390e0734fde4c31ee8e386d Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Thu, 5 Sep 2019 10:50:09 -0700 Subject: [PATCH 50/54] Deterministic example for atomics. Fixes #265 --- examples/atomic-counters/atomic-counters.go | 39 +++++----- examples/atomic-counters/atomic-counters.hash | 4 +- examples/atomic-counters/atomic-counters.sh | 10 ++- public/atomic-counters | 77 ++++++++++--------- 4 files changed, 66 insertions(+), 64 deletions(-) diff --git a/examples/atomic-counters/atomic-counters.go b/examples/atomic-counters/atomic-counters.go index 9df3276..2a0901b 100644 --- a/examples/atomic-counters/atomic-counters.go +++ b/examples/atomic-counters/atomic-counters.go @@ -7,9 +7,11 @@ package main -import "fmt" -import "time" -import "sync/atomic" +import ( + "fmt" + "sync" + "sync/atomic" +) func main() { @@ -17,33 +19,28 @@ func main() { // (always-positive) counter. var ops uint64 - // To simulate concurrent updates, we'll start 50 - // goroutines that each increment the counter about - // once a millisecond. + // A WaitGroup will help us wait for all goroutines + // to finish their work. + var wg sync.WaitGroup + + // We'll start 50 goroutines that each increment the + // counter exactly 1000 times. for i := 0; i < 50; i++ { + wg.Add(1) + go func() { - for { + for c := 0; c < 1000; c++ { // To atomically increment the counter we // use `AddUint64`, giving it the memory // address of our `ops` counter with the // `&` syntax. atomic.AddUint64(&ops, 1) - - // Wait a bit between increments. - time.Sleep(time.Millisecond) } + wg.Done() }() } - // Wait a second to allow some ops to accumulate. - time.Sleep(time.Second) - - // In order to safely use the counter while it's still - // being updated by other goroutines, we extract a - // copy of the current value into `opsFinal` via - // `LoadUint64`. As above we need to give this - // function the memory address `&ops` from which to - // fetch the value. - opsFinal := atomic.LoadUint64(&ops) - fmt.Println("ops:", opsFinal) + // Wait until all the goroutines are done. + wg.Wait() + fmt.Println("ops:", ops) } diff --git a/examples/atomic-counters/atomic-counters.hash b/examples/atomic-counters/atomic-counters.hash index c1b531a..e35f8f2 100644 --- a/examples/atomic-counters/atomic-counters.hash +++ b/examples/atomic-counters/atomic-counters.hash @@ -1,2 +1,2 @@ -a4190094ea0405b5f2733101beb97939a1d43aee -KDr9EMMPMgi +103c9b7d036e3a5c14dc481755b78b10dc9f894e +GRkVf6J1--B diff --git a/examples/atomic-counters/atomic-counters.sh b/examples/atomic-counters/atomic-counters.sh index e4523f9..1680a10 100644 --- a/examples/atomic-counters/atomic-counters.sh +++ b/examples/atomic-counters/atomic-counters.sh @@ -1,7 +1,11 @@ -# Running the program shows that we executed about -# 40,000 operations. +# We expect to get exactly 50,000 operations. Had we +# used the non-atomic `ops++` to increment the counter, +# we'd likely get a different number, changing between +# runs, because the goroutines would interfere with +# each other. Moreover, we'd get data race failures +# when running with the `-race` flag. $ go run atomic-counters.go -ops: 41419 +ops: 50000 # Next we'll look at mutexes, another tool for managing # state. diff --git a/public/atomic-counters b/public/atomic-counters index b2e006e..6c9d94c 100644 --- a/public/atomic-counters +++ b/public/atomic-counters @@ -46,7 +46,7 @@ counters accessed by multiple goroutines.

    - +
    package main
     
    @@ -59,9 +59,11 @@ counters accessed by multiple goroutines.

    -
    import "fmt"
    -import "time"
    -import "sync/atomic"
    +          
    import (
    +    "fmt"
    +    "sync"
    +    "sync/atomic"
    +)
     
    @@ -95,16 +97,28 @@ counters accessed by multiple goroutines.

    -

    To simulate concurrent updates, we’ll start 50 -goroutines that each increment the counter about -once a millisecond.

    +

    A WaitGroup will help us wait for all goroutines +to finish their work.

    + + + + +
        var wg sync.WaitGroup
    +
    + + + + + + +

    We’ll start 50 goroutines that each increment the +counter exactly 1000 times.

        for i := 0; i < 50; i++ {
    -        go func() {
    -            for {
    +        wg.Add(1)
     
    @@ -120,7 +134,8 @@ address of our ops counter with the -
                    atomic.AddUint64(&ops, 1)
    +          
            go func() {
    +            for c := 0; c < 1000; c++ {
     
    @@ -128,13 +143,13 @@ address of our ops counter with the -

    Wait a bit between increments.

    - + -
                    time.Sleep(time.Millisecond)
    +          
                    atomic.AddUint64(&ops, 1)
                 }
    +            wg.Done()
             }()
         }
     
    @@ -144,31 +159,13 @@ address of our ops counter with the -

    Wait a second to allow some ops to accumulate.

    - - - - -
        time.Sleep(time.Second)
    -
    - - - - - - -

    In order to safely use the counter while it’s still -being updated by other goroutines, we extract a -copy of the current value into opsFinal via -LoadUint64. As above we need to give this -function the memory address &ops from which to -fetch the value.

    +

    Wait until all the goroutines are done.

    -
        opsFinal := atomic.LoadUint64(&ops)
    -    fmt.Println("ops:", opsFinal)
    +          
        wg.Wait()
    +    fmt.Println("ops:", ops)
     }
     
    @@ -181,14 +178,18 @@ fetch the value.

    -

    Running the program shows that we executed about -40,000 operations.

    +

    We expect to get exactly 50,000 operations. Had we +used the non-atomic ops++ to increment the counter, +we’d likely get a different number, changing between +runs, because the goroutines would interfere with +each other. Moreover, we’d get data race failures +when running with the -race flag.

    $ go run atomic-counters.go
    -ops: 41419
    +ops: 50000
     
    @@ -219,7 +220,7 @@ state.

    From b70c15adaa0983b3d07312f425b8c6d4df71457f Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Thu, 5 Sep 2019 13:26:08 -0700 Subject: [PATCH 51/54] Clarify reading op non-atomically --- examples/atomic-counters/atomic-counters.go | 6 +++++ examples/atomic-counters/atomic-counters.hash | 4 ++-- public/atomic-counters | 24 +++++++++++++++---- 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/examples/atomic-counters/atomic-counters.go b/examples/atomic-counters/atomic-counters.go index 2a0901b..046a347 100644 --- a/examples/atomic-counters/atomic-counters.go +++ b/examples/atomic-counters/atomic-counters.go @@ -42,5 +42,11 @@ func main() { // Wait until all the goroutines are done. wg.Wait() + + // It's safe to access `ops` now because we know + // no other goroutine is writing to it. Reading + // atomics safely while they are being updated is + // also possible, using functions like + // `atomic.LoadUint64`. fmt.Println("ops:", ops) } diff --git a/examples/atomic-counters/atomic-counters.hash b/examples/atomic-counters/atomic-counters.hash index e35f8f2..989ed19 100644 --- a/examples/atomic-counters/atomic-counters.hash +++ b/examples/atomic-counters/atomic-counters.hash @@ -1,2 +1,2 @@ -103c9b7d036e3a5c14dc481755b78b10dc9f894e -GRkVf6J1--B +8ebec0be3b167021c96b8b497d0e8c0a2ea99385 +F2pJfduyQiA diff --git a/public/atomic-counters b/public/atomic-counters index 6c9d94c..9627c97 100644 --- a/public/atomic-counters +++ b/public/atomic-counters @@ -46,7 +46,7 @@ counters accessed by multiple goroutines.

    - +
    package main
     
    @@ -162,10 +162,26 @@ address of our ops counter with the

    Wait until all the goroutines are done.

    - +
        wg.Wait()
    -    fmt.Println("ops:", ops)
    +
    + + + + + + +

    It’s safe to access ops now because we know +no other goroutine is writing to it. Reading +atomics safely while they are being updated is +also possible, using functions like +atomic.LoadUint64.

    + + + + +
        fmt.Println("ops:", ops)
     }
     
    @@ -220,7 +236,7 @@ state.

    From a34c967eaf2e1bda05eadc5c1af59fe8060ca0dc Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Thu, 5 Sep 2019 13:30:16 -0700 Subject: [PATCH 52/54] Clarify use of buffered channel in the timeouts example. The buffered channel prevents goroutine leaks in case the channel doesn't end up being read (as indeed happens to c1). Updates #207 --- examples/timeouts/timeouts.go | 5 ++++- examples/timeouts/timeouts.hash | 4 ++-- public/timeouts | 7 +++++-- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/examples/timeouts/timeouts.go b/examples/timeouts/timeouts.go index ccc9ecb..ce1d1cd 100644 --- a/examples/timeouts/timeouts.go +++ b/examples/timeouts/timeouts.go @@ -12,7 +12,10 @@ func main() { // For our example, suppose we're executing an external // call that returns its result on a channel `c1` - // after 2s. + // after 2s. Note that the channel is buffered, so the + // send in the goroutine is nonblocking. This is a + // common pattern to prevent goroutine leaks in case the + // channel is never read. c1 := make(chan string, 1) go func() { time.Sleep(2 * time.Second) diff --git a/examples/timeouts/timeouts.hash b/examples/timeouts/timeouts.hash index 64d1c5a..f510bfa 100644 --- a/examples/timeouts/timeouts.hash +++ b/examples/timeouts/timeouts.hash @@ -1,2 +1,2 @@ -93343e1aacb14f818c87732914c29ba57afab245 -MgcfA-xpJO9 +b1e8d0efbabd0c52271a85fad5ad58dcd1c7c476 +gyY_qDsRVUe diff --git a/public/timeouts b/public/timeouts index c00732d..532dbc0 100644 --- a/public/timeouts +++ b/public/timeouts @@ -44,7 +44,7 @@ elegant thanks to channels and select.

    - +
    package main
     
    @@ -80,7 +80,10 @@ elegant thanks to channels and select.

    For our example, suppose we’re executing an external call that returns its result on a channel c1 -after 2s.

    +after 2s. Note that the channel is buffered, so the +send in the goroutine is nonblocking. This is a +common pattern to prevent goroutine leaks in case the +channel is never read.

    From 9889d7f702a06b0d0b58d37279aa2976c0ca3993 Mon Sep 17 00:00:00 2001 From: Mark McGranaghan Date: Fri, 6 Sep 2019 07:37:49 -0700 Subject: [PATCH 53/54] This transition paragraph no longer makes sense --- examples/timeouts/timeouts.sh | 6 ------ public/timeouts | 19 ++----------------- 2 files changed, 2 insertions(+), 23 deletions(-) diff --git a/examples/timeouts/timeouts.sh b/examples/timeouts/timeouts.sh index 8a9dfb4..3c4344f 100644 --- a/examples/timeouts/timeouts.sh +++ b/examples/timeouts/timeouts.sh @@ -3,9 +3,3 @@ $ go run timeouts.go timeout 1 result 2 - -# Using this `select` timeout pattern requires -# communicating results over channels. This is a good -# idea in general because other important Go features are -# based on channels and `select`. We'll look at two -# examples of this next: timers and tickers. diff --git a/public/timeouts b/public/timeouts index 532dbc0..8142985 100644 --- a/public/timeouts +++ b/public/timeouts @@ -156,7 +156,7 @@ from c2 will succeed and we’ll print the result.

    out and the second succeeding.

    - +
    $ go run timeouts.go 
     timeout 1
    @@ -166,21 +166,6 @@ out and the second succeeding.

    - - -

    Using this select timeout pattern requires -communicating results over channels. This is a good -idea in general because other important Go features are -based on channels and select. We’ll look at two -examples of this next: timers and tickers.

    - - - - - - - - @@ -194,7 +179,7 @@ examples of this next: timers and tickers.

    From c2735885215bf405b22c1ae606b6c58de6b746c5 Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Fri, 6 Sep 2019 15:20:22 -0700 Subject: [PATCH 54/54] Make multiple imports consistent with import ( ... ) style Fixes #272 --- examples/base64-encoding/base64-encoding.go | 6 ++++-- examples/base64-encoding/base64-encoding.hash | 4 ++-- .../channel-synchronization.go | 6 ++++-- .../channel-synchronization.hash | 4 ++-- .../collection-functions/collection-functions.go | 6 ++++-- .../collection-functions/collection-functions.hash | 4 ++-- .../command-line-arguments.go | 6 ++++-- .../command-line-arguments.hash | 4 ++-- examples/command-line-flags/command-line-flags.go | 6 ++++-- .../command-line-flags/command-line-flags.hash | 4 ++-- examples/constants/constants.go | 6 ++++-- examples/constants/constants.hash | 4 ++-- examples/defer/defer.go | 6 ++++-- examples/defer/defer.hash | 4 ++-- .../environment-variables/environment-variables.go | 8 +++++--- .../environment-variables.hash | 4 ++-- examples/epoch/epoch.go | 6 ++++-- examples/epoch/epoch.hash | 4 ++-- examples/errors/errors.go | 6 ++++-- examples/errors/errors.hash | 4 ++-- examples/execing-processes/execing-processes.go | 8 +++++--- examples/execing-processes/execing-processes.hash | 4 ++-- examples/exit/exit.go | 6 ++++-- examples/exit/exit.hash | 4 ++-- examples/interfaces/interfaces.go | 6 ++++-- examples/interfaces/interfaces.hash | 4 ++-- examples/json/json.go | 8 +++++--- examples/json/json.hash | 4 ++-- examples/number-parsing/number-parsing.go | 6 ++++-- examples/number-parsing/number-parsing.hash | 4 ++-- examples/random-numbers/random-numbers.go | 8 +++++--- examples/random-numbers/random-numbers.hash | 4 ++-- examples/rate-limiting/rate-limiting.go | 6 ++++-- examples/rate-limiting/rate-limiting.hash | 4 ++-- .../regular-expressions/regular-expressions.go | 8 +++++--- .../regular-expressions/regular-expressions.hash | 4 ++-- examples/select/select.go | 6 ++++-- examples/select/select.hash | 4 ++-- examples/sha1-hashes/sha1-hashes.go | 6 ++++-- examples/sha1-hashes/sha1-hashes.hash | 4 ++-- examples/signals/signals.go | 10 ++++++---- examples/signals/signals.hash | 4 ++-- .../sorting-by-functions/sorting-by-functions.go | 6 ++++-- .../sorting-by-functions/sorting-by-functions.hash | 4 ++-- examples/sorting/sorting.go | 6 ++++-- examples/sorting/sorting.hash | 4 ++-- examples/spawning-processes/spawning-processes.go | 8 +++++--- .../spawning-processes/spawning-processes.hash | 4 ++-- examples/string-formatting/string-formatting.go | 6 ++++-- examples/string-formatting/string-formatting.hash | 4 ++-- examples/string-functions/string-functions.go | 6 ++++-- examples/string-functions/string-functions.hash | 4 ++-- examples/switch/switch.go | 6 ++++-- examples/switch/switch.hash | 4 ++-- examples/tickers/tickers.go | 6 ++++-- examples/tickers/tickers.hash | 4 ++-- .../time-formatting-parsing.go | 6 ++++-- .../time-formatting-parsing.hash | 4 ++-- examples/time/time.go | 6 ++++-- examples/time/time.hash | 4 ++-- examples/timeouts/timeouts.go | 6 ++++-- examples/timeouts/timeouts.hash | 4 ++-- examples/timers/timers.go | 6 ++++-- examples/timers/timers.hash | 4 ++-- examples/url-parsing/url-parsing.go | 8 +++++--- examples/url-parsing/url-parsing.hash | 4 ++-- examples/worker-pools/worker-pools.go | 6 ++++-- examples/worker-pools/worker-pools.hash | 4 ++-- public/base64-encoding | 10 ++++++---- public/channel-synchronization | 10 ++++++---- public/collection-functions | 10 ++++++---- public/command-line-arguments | 10 ++++++---- public/command-line-flags | 10 ++++++---- public/constants | 10 ++++++---- public/defer | 10 ++++++---- public/environment-variables | 12 +++++++----- public/epoch | 10 ++++++---- public/errors | 10 ++++++---- public/execing-processes | 12 +++++++----- public/exit | 10 ++++++---- public/interfaces | 10 ++++++---- public/json | 12 +++++++----- public/number-parsing | 10 ++++++---- public/random-numbers | 12 +++++++----- public/rate-limiting | 10 ++++++---- public/regular-expressions | 12 +++++++----- public/select | 10 ++++++---- public/sha1-hashes | 10 ++++++---- public/signals | 14 ++++++++------ public/sorting | 10 ++++++---- public/sorting-by-functions | 10 ++++++---- public/spawning-processes | 12 +++++++----- public/string-formatting | 10 ++++++---- public/string-functions | 10 ++++++---- public/switch | 10 ++++++---- public/tickers | 10 ++++++---- public/time | 10 ++++++---- public/time-formatting-parsing | 10 ++++++---- public/timeouts | 10 ++++++---- public/timers | 10 ++++++---- public/url-parsing | 12 +++++++----- public/worker-pools | 10 ++++++---- 102 files changed, 426 insertions(+), 290 deletions(-) diff --git a/examples/base64-encoding/base64-encoding.go b/examples/base64-encoding/base64-encoding.go index 4bdeaf1..09e94fd 100644 --- a/examples/base64-encoding/base64-encoding.go +++ b/examples/base64-encoding/base64-encoding.go @@ -6,8 +6,10 @@ package main // This syntax imports the `encoding/base64` package with // the `b64` name instead of the default `base64`. It'll // save us some space below. -import b64 "encoding/base64" -import "fmt" +import ( + b64 "encoding/base64" + "fmt" +) func main() { diff --git a/examples/base64-encoding/base64-encoding.hash b/examples/base64-encoding/base64-encoding.hash index 1cb409a..717ff3f 100644 --- a/examples/base64-encoding/base64-encoding.hash +++ b/examples/base64-encoding/base64-encoding.hash @@ -1,2 +1,2 @@ -c20da14820b656c867790f2e99bc37140babca8c -y_QTcqdkvZh +e0148b9b4acb01e849b8f678cba03f549d250c44 +V3oV1bvh94k diff --git a/examples/channel-synchronization/channel-synchronization.go b/examples/channel-synchronization/channel-synchronization.go index 79ceafe..889b97b 100644 --- a/examples/channel-synchronization/channel-synchronization.go +++ b/examples/channel-synchronization/channel-synchronization.go @@ -6,8 +6,10 @@ package main -import "fmt" -import "time" +import ( + "fmt" + "time" +) // This is the function we'll run in a goroutine. The // `done` channel will be used to notify another diff --git a/examples/channel-synchronization/channel-synchronization.hash b/examples/channel-synchronization/channel-synchronization.hash index e906123..9dea9a0 100644 --- a/examples/channel-synchronization/channel-synchronization.hash +++ b/examples/channel-synchronization/channel-synchronization.hash @@ -1,2 +1,2 @@ -eb022977181884c2ab0f2b69e50311769e67a509 -8lmP8beav0p +0d5a9de912e2a4a18943e082e2f8107cb75d0ce4 +fe9If6OhYMk diff --git a/examples/collection-functions/collection-functions.go b/examples/collection-functions/collection-functions.go index b6ff547..730644c 100644 --- a/examples/collection-functions/collection-functions.go +++ b/examples/collection-functions/collection-functions.go @@ -18,8 +18,10 @@ package main -import "strings" -import "fmt" +import ( + "fmt" + "strings" +) // Index returns the first index of the target string `t`, or // -1 if no match is found. diff --git a/examples/collection-functions/collection-functions.hash b/examples/collection-functions/collection-functions.hash index 4c45952..abbd3d5 100644 --- a/examples/collection-functions/collection-functions.hash +++ b/examples/collection-functions/collection-functions.hash @@ -1,2 +1,2 @@ -d961fc0e0074aed46cfd1516efdadea78781af56 -BJB_npWH516 +28456737ea996664bdaeb8e1e821d95697d00646 +8hI6oPNEfyh diff --git a/examples/command-line-arguments/command-line-arguments.go b/examples/command-line-arguments/command-line-arguments.go index e000e13..1104113 100644 --- a/examples/command-line-arguments/command-line-arguments.go +++ b/examples/command-line-arguments/command-line-arguments.go @@ -5,8 +5,10 @@ package main -import "os" -import "fmt" +import ( + "fmt" + "os" +) func main() { diff --git a/examples/command-line-arguments/command-line-arguments.hash b/examples/command-line-arguments/command-line-arguments.hash index 5bf53c7..ad22b59 100644 --- a/examples/command-line-arguments/command-line-arguments.hash +++ b/examples/command-line-arguments/command-line-arguments.hash @@ -1,2 +1,2 @@ -41c970a1ef29ad2a05307e6c783ff52ab80eaccd -6pFdjf800jj +9c80d495201148bbeb0fd0a5a2ce1735aeb34b60 +myJy_-H8Fo_Q diff --git a/examples/command-line-flags/command-line-flags.go b/examples/command-line-flags/command-line-flags.go index ab9c1b7..96647f5 100644 --- a/examples/command-line-flags/command-line-flags.go +++ b/examples/command-line-flags/command-line-flags.go @@ -8,8 +8,10 @@ package main // Go provides a `flag` package supporting basic // command-line flag parsing. We'll use this package to // implement our example command-line program. -import "flag" -import "fmt" +import ( + "flag" + "fmt" +) func main() { diff --git a/examples/command-line-flags/command-line-flags.hash b/examples/command-line-flags/command-line-flags.hash index 1b8f3ac..abee236 100644 --- a/examples/command-line-flags/command-line-flags.hash +++ b/examples/command-line-flags/command-line-flags.hash @@ -1,2 +1,2 @@ -e2ba0461c090789168c712cc7ed0f66aab09a8c8 -klFR5DitrCy +ab08bf890dcd87b807956b5bee441d59efe458e3 +lPaZodnG9TF diff --git a/examples/constants/constants.go b/examples/constants/constants.go index 50ce8f2..e7af860 100644 --- a/examples/constants/constants.go +++ b/examples/constants/constants.go @@ -3,8 +3,10 @@ package main -import "fmt" -import "math" +import ( + "fmt" + "math" +) // `const` declares a constant value. const s string = "constant" diff --git a/examples/constants/constants.hash b/examples/constants/constants.hash index 1e282aa..93d42ca 100644 --- a/examples/constants/constants.hash +++ b/examples/constants/constants.hash @@ -1,2 +1,2 @@ -2f2ec3a5ff4eef280199da1908eed261346fb40e -VhP0f8moZd3 +7cc09460e8dc6fffd0ba811679f92a85eb51e927 +gmjHSglwLic diff --git a/examples/defer/defer.go b/examples/defer/defer.go index 724e698..b4077c7 100644 --- a/examples/defer/defer.go +++ b/examples/defer/defer.go @@ -5,8 +5,10 @@ package main -import "fmt" -import "os" +import ( + "fmt" + "os" +) // Suppose we wanted to create a file, write to it, // and then close when we're done. Here's how we could diff --git a/examples/defer/defer.hash b/examples/defer/defer.hash index 78d3e35..d45bfd7 100644 --- a/examples/defer/defer.hash +++ b/examples/defer/defer.hash @@ -1,2 +1,2 @@ -fadbe9c05bb42db672316ba19adf3c2189c7b3f5 -OrCaBiCrTKq +4fc23579a9bd5d8512884902394f4dce51eb7d60 +QJJ2R6kv6K5 diff --git a/examples/environment-variables/environment-variables.go b/examples/environment-variables/environment-variables.go index beca4e7..b316b8a 100644 --- a/examples/environment-variables/environment-variables.go +++ b/examples/environment-variables/environment-variables.go @@ -5,9 +5,11 @@ package main -import "os" -import "strings" -import "fmt" +import ( + "fmt" + "os" + "strings" +) func main() { diff --git a/examples/environment-variables/environment-variables.hash b/examples/environment-variables/environment-variables.hash index 81632ac..b245851 100644 --- a/examples/environment-variables/environment-variables.hash +++ b/examples/environment-variables/environment-variables.hash @@ -1,2 +1,2 @@ -4d0832c5a1ddd4e95474791e8802c15452358214 -CZJ4R_uu6Uu +db2e203da519a22943753295e9cc27d89e4347b0 +bKuCOOD16KH diff --git a/examples/epoch/epoch.go b/examples/epoch/epoch.go index 63cffbb..ed7f442 100644 --- a/examples/epoch/epoch.go +++ b/examples/epoch/epoch.go @@ -5,8 +5,10 @@ package main -import "fmt" -import "time" +import ( + "fmt" + "time" +) func main() { diff --git a/examples/epoch/epoch.hash b/examples/epoch/epoch.hash index 3899c7f..d37c230 100644 --- a/examples/epoch/epoch.hash +++ b/examples/epoch/epoch.hash @@ -1,2 +1,2 @@ -61a498229c8878a97d729cfdd215e5f3960f87ac -eN1Qv2ATB-C +184c8f3e94dd28176be81956115ac417e33513a6 +3uYNHHRplmQ diff --git a/examples/errors/errors.go b/examples/errors/errors.go index 0b69bad..b850139 100644 --- a/examples/errors/errors.go +++ b/examples/errors/errors.go @@ -9,8 +9,10 @@ package main -import "errors" -import "fmt" +import ( + "errors" + "fmt" +) // By convention, errors are the last return value and // have type `error`, a built-in interface. diff --git a/examples/errors/errors.hash b/examples/errors/errors.hash index d0b2112..b650d25 100644 --- a/examples/errors/errors.hash +++ b/examples/errors/errors.hash @@ -1,2 +1,2 @@ -210ba0f8196006c0380acaec01655816848ef168 -mP_ZR1qjUvA +ed58ad3162d93c723d3efe72529a61ce7041fe13 +vrwN32gxaYx diff --git a/examples/execing-processes/execing-processes.go b/examples/execing-processes/execing-processes.go index b9caed1..18eb283 100644 --- a/examples/execing-processes/execing-processes.go +++ b/examples/execing-processes/execing-processes.go @@ -10,9 +10,11 @@ package main -import "syscall" -import "os" -import "os/exec" +import ( + "os" + "os/exec" + "syscall" +) func main() { diff --git a/examples/execing-processes/execing-processes.hash b/examples/execing-processes/execing-processes.hash index 4701404..020f78e 100644 --- a/examples/execing-processes/execing-processes.hash +++ b/examples/execing-processes/execing-processes.hash @@ -1,2 +1,2 @@ -b527bbb76a42dd4bae541b73a7377b7e83e79905 -bf11ADw-2Ho +e6b4830d4264f307506b54726ec79b25a0363874 +ahZjpJaZz44 diff --git a/examples/exit/exit.go b/examples/exit/exit.go index d1e3646..578e553 100644 --- a/examples/exit/exit.go +++ b/examples/exit/exit.go @@ -3,8 +3,10 @@ package main -import "fmt" -import "os" +import ( + "fmt" + "os" +) func main() { diff --git a/examples/exit/exit.hash b/examples/exit/exit.hash index 988b8f3..234717b 100644 --- a/examples/exit/exit.hash +++ b/examples/exit/exit.hash @@ -1,2 +1,2 @@ -dc0bb3eaafa045d6aa05e88aff39322a1ccf822e -vDaM0-MGJ_k +2316e6c8e364e2066c6bd350dc9b0b2af85b63fe +OX997ykuOGx diff --git a/examples/interfaces/interfaces.go b/examples/interfaces/interfaces.go index 2ac30bd..806ffa7 100644 --- a/examples/interfaces/interfaces.go +++ b/examples/interfaces/interfaces.go @@ -3,8 +3,10 @@ package main -import "fmt" -import "math" +import ( + "fmt" + "math" +) // Here's a basic interface for geometric shapes. type geometry interface { diff --git a/examples/interfaces/interfaces.hash b/examples/interfaces/interfaces.hash index d9daece..b6fa983 100644 --- a/examples/interfaces/interfaces.hash +++ b/examples/interfaces/interfaces.hash @@ -1,2 +1,2 @@ -3547b935d1e0322c0fb696726c27cae53a275e0a -0EwsqIn3TTi +aac1328f5a04568272b82753ff0762b9eacff4fc +hXTlbUAGcvn diff --git a/examples/json/json.go b/examples/json/json.go index 8d443bd..2594786 100644 --- a/examples/json/json.go +++ b/examples/json/json.go @@ -4,9 +4,11 @@ package main -import "encoding/json" -import "fmt" -import "os" +import ( + "encoding/json" + "fmt" + "os" +) // We'll use these two structs to demonstrate encoding and // decoding of custom types below. diff --git a/examples/json/json.hash b/examples/json/json.hash index 0c3c3a1..8c217d6 100644 --- a/examples/json/json.hash +++ b/examples/json/json.hash @@ -1,2 +1,2 @@ -6b92694b7be60cdec3e7a04e9fdbf49d5c84adb1 -63PdbTHxKJA +c751bc7223b8bc615f82fe7643ab98ce2b80240f +ROikmz5tRhZ diff --git a/examples/number-parsing/number-parsing.go b/examples/number-parsing/number-parsing.go index 15a03bf..6371637 100644 --- a/examples/number-parsing/number-parsing.go +++ b/examples/number-parsing/number-parsing.go @@ -5,8 +5,10 @@ package main // The built-in package `strconv` provides the number // parsing. -import "strconv" -import "fmt" +import ( + "fmt" + "strconv" +) func main() { diff --git a/examples/number-parsing/number-parsing.hash b/examples/number-parsing/number-parsing.hash index 3249903..eeaf3cd 100644 --- a/examples/number-parsing/number-parsing.hash +++ b/examples/number-parsing/number-parsing.hash @@ -1,2 +1,2 @@ -0d2155e9863a73c098d44637e92403d7f5e8e965 -NZh4LjhguvN +0191c7e43706640207c403ba92dd2272d66fc868 +t2q4KnWWTAw diff --git a/examples/random-numbers/random-numbers.go b/examples/random-numbers/random-numbers.go index b27c200..ebb6a8c 100644 --- a/examples/random-numbers/random-numbers.go +++ b/examples/random-numbers/random-numbers.go @@ -4,9 +4,11 @@ package main -import "time" -import "fmt" -import "math/rand" +import ( + "fmt" + "math/rand" + "time" +) func main() { diff --git a/examples/random-numbers/random-numbers.hash b/examples/random-numbers/random-numbers.hash index 87959ee..3ebbc4a 100644 --- a/examples/random-numbers/random-numbers.hash +++ b/examples/random-numbers/random-numbers.hash @@ -1,2 +1,2 @@ -8e97de760147b061dd09939db294c892211b6b80 -jiJaIjxL2sP +9374869a809d28ea784a9e1181b4aa1988018776 +DVHO7SjJZnp diff --git a/examples/rate-limiting/rate-limiting.go b/examples/rate-limiting/rate-limiting.go index 175bbcc..c32483d 100644 --- a/examples/rate-limiting/rate-limiting.go +++ b/examples/rate-limiting/rate-limiting.go @@ -6,8 +6,10 @@ package main -import "time" -import "fmt" +import ( + "fmt" + "time" +) func main() { diff --git a/examples/rate-limiting/rate-limiting.hash b/examples/rate-limiting/rate-limiting.hash index ccbbc49..be48802 100644 --- a/examples/rate-limiting/rate-limiting.hash +++ b/examples/rate-limiting/rate-limiting.hash @@ -1,2 +1,2 @@ -edad78bf3b36ddc9bec30b344b8a72be4de90f3b -l4uDE-RCDpa +357d83df3e48675eb1e135188cb9f07448c1f146 +AJ-MJephNib diff --git a/examples/regular-expressions/regular-expressions.go b/examples/regular-expressions/regular-expressions.go index 5d5ee8c..52ec06d 100644 --- a/examples/regular-expressions/regular-expressions.go +++ b/examples/regular-expressions/regular-expressions.go @@ -4,9 +4,11 @@ package main -import "bytes" -import "fmt" -import "regexp" +import ( + "bytes" + "fmt" + "regexp" +) func main() { diff --git a/examples/regular-expressions/regular-expressions.hash b/examples/regular-expressions/regular-expressions.hash index abc14cd..236706c 100644 --- a/examples/regular-expressions/regular-expressions.hash +++ b/examples/regular-expressions/regular-expressions.hash @@ -1,2 +1,2 @@ -7cde6b9af5cf6c47606001dd54eee468a6c61dbb -qR5gn2l0AGa +de24265897edf1d3913e3b87f70757284a66ecea +urHlUNDVenk diff --git a/examples/select/select.go b/examples/select/select.go index c05aacb..d2ce16e 100644 --- a/examples/select/select.go +++ b/examples/select/select.go @@ -4,8 +4,10 @@ package main -import "time" -import "fmt" +import ( + "fmt" + "time" +) func main() { diff --git a/examples/select/select.hash b/examples/select/select.hash index 5037668..ea97b26 100644 --- a/examples/select/select.hash +++ b/examples/select/select.hash @@ -1,2 +1,2 @@ -8d743edffd7de6bf7bccdf4437f45672b6adc75e -ZdSOPe1Gj13 +6e1125087bc036ebd905452300575f160d683918 +yF-xgN7Xf9P diff --git a/examples/sha1-hashes/sha1-hashes.go b/examples/sha1-hashes/sha1-hashes.go index db8bb39..24e5921 100644 --- a/examples/sha1-hashes/sha1-hashes.go +++ b/examples/sha1-hashes/sha1-hashes.go @@ -9,8 +9,10 @@ package main // Go implements several hash functions in various // `crypto/*` packages. -import "crypto/sha1" -import "fmt" +import ( + "crypto/sha1" + "fmt" +) func main() { s := "sha1 this string" diff --git a/examples/sha1-hashes/sha1-hashes.hash b/examples/sha1-hashes/sha1-hashes.hash index e56a014..5af2939 100644 --- a/examples/sha1-hashes/sha1-hashes.hash +++ b/examples/sha1-hashes/sha1-hashes.hash @@ -1,2 +1,2 @@ -6a896270e34f2696b881a8fa7e68bfff57dee51f -1oT-5GBUkLr +4cda643ba233014fe6b30966c37d4d0fcd4edbe8 +oqcrTfY4Ykd diff --git a/examples/signals/signals.go b/examples/signals/signals.go index 38e17ad..4cd373b 100644 --- a/examples/signals/signals.go +++ b/examples/signals/signals.go @@ -7,10 +7,12 @@ package main -import "fmt" -import "os" -import "os/signal" -import "syscall" +import ( + "fmt" + "os" + "os/signal" + "syscall" +) func main() { diff --git a/examples/signals/signals.hash b/examples/signals/signals.hash index 94e8edb..82345ca 100644 --- a/examples/signals/signals.hash +++ b/examples/signals/signals.hash @@ -1,2 +1,2 @@ -9720d747e3ab2893df508a70cbb341c90fdd7ca1 -9koJAW1raI5 +1e43c6f63f1d57e1a52c89f52d35b68757e9676b +_6oj-T3Gko2 diff --git a/examples/sorting-by-functions/sorting-by-functions.go b/examples/sorting-by-functions/sorting-by-functions.go index b880564..8524f66 100644 --- a/examples/sorting-by-functions/sorting-by-functions.go +++ b/examples/sorting-by-functions/sorting-by-functions.go @@ -6,8 +6,10 @@ package main -import "sort" -import "fmt" +import ( + "fmt" + "sort" +) // In order to sort by a custom function in Go, we need a // corresponding type. Here we've created a `byLength` diff --git a/examples/sorting-by-functions/sorting-by-functions.hash b/examples/sorting-by-functions/sorting-by-functions.hash index 776dde8..d62f035 100644 --- a/examples/sorting-by-functions/sorting-by-functions.hash +++ b/examples/sorting-by-functions/sorting-by-functions.hash @@ -1,2 +1,2 @@ -6a04058b564d5741815e523f97f240ee6563cb15 -y3kuCwIFRYK +f7d0b7840dd12601fb86946f9dc4c38fb1c0501f +Jtxf94x94Hx diff --git a/examples/sorting/sorting.go b/examples/sorting/sorting.go index b6317ed..acc67d8 100644 --- a/examples/sorting/sorting.go +++ b/examples/sorting/sorting.go @@ -4,8 +4,10 @@ package main -import "fmt" -import "sort" +import ( + "fmt" + "sort" +) func main() { diff --git a/examples/sorting/sorting.hash b/examples/sorting/sorting.hash index ae5e449..d72396f 100644 --- a/examples/sorting/sorting.hash +++ b/examples/sorting/sorting.hash @@ -1,2 +1,2 @@ -4e576421f2bdbd11847c367d223bd30d0e301990 -e6hp3Rn-oH6 +e11e944d34b21e75ce4f7c91026d4200ce592dc5 +tAWAkRlBJNX diff --git a/examples/spawning-processes/spawning-processes.go b/examples/spawning-processes/spawning-processes.go index 98e0f65..58fdae8 100644 --- a/examples/spawning-processes/spawning-processes.go +++ b/examples/spawning-processes/spawning-processes.go @@ -7,9 +7,11 @@ package main -import "fmt" -import "io/ioutil" -import "os/exec" +import ( + "fmt" + "io/ioutil" + "os/exec" +) func main() { diff --git a/examples/spawning-processes/spawning-processes.hash b/examples/spawning-processes/spawning-processes.hash index dd1b749..bcde707 100644 --- a/examples/spawning-processes/spawning-processes.hash +++ b/examples/spawning-processes/spawning-processes.hash @@ -1,2 +1,2 @@ -0b676b93e41ac5434003c194bc038d5f3ce76bc8 -6HRWVK5gPYU +cc68e4290f10209ad2fa8db74fdfaea7fdb44d5c +QS_Nkoe8VLG diff --git a/examples/string-formatting/string-formatting.go b/examples/string-formatting/string-formatting.go index de7c285..958cb64 100644 --- a/examples/string-formatting/string-formatting.go +++ b/examples/string-formatting/string-formatting.go @@ -4,8 +4,10 @@ package main -import "fmt" -import "os" +import ( + "fmt" + "os" +) type point struct { x, y int diff --git a/examples/string-formatting/string-formatting.hash b/examples/string-formatting/string-formatting.hash index ba1b396..c339d9b 100644 --- a/examples/string-formatting/string-formatting.hash +++ b/examples/string-formatting/string-formatting.hash @@ -1,2 +1,2 @@ -5f39ae6d8f26d59a688a9a9d7d13a5c1d0f7a08b -CkBQ3CFpHQ9 +12b245c576b43537c092a5b84995ebca8ce78a57 +vmYSdxfUcRh diff --git a/examples/string-functions/string-functions.go b/examples/string-functions/string-functions.go index c8f2b54..676e904 100644 --- a/examples/string-functions/string-functions.go +++ b/examples/string-functions/string-functions.go @@ -4,8 +4,10 @@ package main -import s "strings" -import "fmt" +import ( + "fmt" + s "strings" +) // We alias `fmt.Println` to a shorter name as we'll use // it a lot below. diff --git a/examples/string-functions/string-functions.hash b/examples/string-functions/string-functions.hash index 068746c..568c7c6 100644 --- a/examples/string-functions/string-functions.hash +++ b/examples/string-functions/string-functions.hash @@ -1,2 +1,2 @@ -17aa523bbd606fa0b624fae44b89812d46330755 -Vn4D3y4_711 +bf39c7540bd78eba38eb5a9047a9d0ffc7235f85 +xoRUhG86wsF diff --git a/examples/switch/switch.go b/examples/switch/switch.go index 8d72bee..2d2ec2e 100644 --- a/examples/switch/switch.go +++ b/examples/switch/switch.go @@ -3,8 +3,10 @@ package main -import "fmt" -import "time" +import ( + "fmt" + "time" +) func main() { diff --git a/examples/switch/switch.hash b/examples/switch/switch.hash index 5559e1a..54d2e9f 100644 --- a/examples/switch/switch.hash +++ b/examples/switch/switch.hash @@ -1,2 +1,2 @@ -b47004b3e3b6d787ea98642dc5b955df57cd2bcd -TJ4Az0KuLfL +2486fc553301cdeac9a26f3d0b3aed4143d9f4f0 +ZcDzdx3nYQn diff --git a/examples/tickers/tickers.go b/examples/tickers/tickers.go index 1d2a8e5..c23dd5c 100644 --- a/examples/tickers/tickers.go +++ b/examples/tickers/tickers.go @@ -6,8 +6,10 @@ package main -import "time" -import "fmt" +import ( + "fmt" + "time" +) func main() { diff --git a/examples/tickers/tickers.hash b/examples/tickers/tickers.hash index 28a173e..e724ec1 100644 --- a/examples/tickers/tickers.hash +++ b/examples/tickers/tickers.hash @@ -1,2 +1,2 @@ -c83f34821c69d156713919a42c73ec9f58560f72 -IUmkvvXL5Ok +4a42333d14f902e890902343c7bd9b9c735fd8ad +n1q1sSGEvmv diff --git a/examples/time-formatting-parsing/time-formatting-parsing.go b/examples/time-formatting-parsing/time-formatting-parsing.go index a213baf..2968c3c 100644 --- a/examples/time-formatting-parsing/time-formatting-parsing.go +++ b/examples/time-formatting-parsing/time-formatting-parsing.go @@ -3,8 +3,10 @@ package main -import "fmt" -import "time" +import ( + "fmt" + "time" +) func main() { p := fmt.Println diff --git a/examples/time-formatting-parsing/time-formatting-parsing.hash b/examples/time-formatting-parsing/time-formatting-parsing.hash index 0d05bde..eee6d65 100644 --- a/examples/time-formatting-parsing/time-formatting-parsing.hash +++ b/examples/time-formatting-parsing/time-formatting-parsing.hash @@ -1,2 +1,2 @@ -1f9962260f5c92efe57db0b96099b3dd06c90333 -nHAisH6amZG +9e3f17061fef280191e3e8518365e231e17a5d5a +1410R7Fcyx0 diff --git a/examples/time/time.go b/examples/time/time.go index 1d01432..db96527 100644 --- a/examples/time/time.go +++ b/examples/time/time.go @@ -3,8 +3,10 @@ package main -import "fmt" -import "time" +import ( + "fmt" + "time" +) func main() { p := fmt.Println diff --git a/examples/time/time.hash b/examples/time/time.hash index 9542207..2c9d415 100644 --- a/examples/time/time.hash +++ b/examples/time/time.hash @@ -1,2 +1,2 @@ -b6308f1fea7665e89a28f54aac6cb49b95685eb5 -PZMCzzaJURJ +c47d853fa7527a652ce78b0285e452c6cd740050 +u-7i_p8BHVt diff --git a/examples/timeouts/timeouts.go b/examples/timeouts/timeouts.go index ce1d1cd..3f25aec 100644 --- a/examples/timeouts/timeouts.go +++ b/examples/timeouts/timeouts.go @@ -5,8 +5,10 @@ package main -import "time" -import "fmt" +import ( + "fmt" + "time" +) func main() { diff --git a/examples/timeouts/timeouts.hash b/examples/timeouts/timeouts.hash index f510bfa..f622aeb 100644 --- a/examples/timeouts/timeouts.hash +++ b/examples/timeouts/timeouts.hash @@ -1,2 +1,2 @@ -b1e8d0efbabd0c52271a85fad5ad58dcd1c7c476 -gyY_qDsRVUe +b8d3e745539b24d3530ca21efcdc924f08769edb +TYJgoFjlTd6 diff --git a/examples/timers/timers.go b/examples/timers/timers.go index 939cf11..d0256e6 100644 --- a/examples/timers/timers.go +++ b/examples/timers/timers.go @@ -6,8 +6,10 @@ package main -import "time" -import "fmt" +import ( + "fmt" + "time" +) func main() { diff --git a/examples/timers/timers.hash b/examples/timers/timers.hash index f51b1f0..8c0f2c4 100644 --- a/examples/timers/timers.hash +++ b/examples/timers/timers.hash @@ -1,2 +1,2 @@ -e10c601ab3b702dfcea728c1edb31673561484b5 -pybl9hRvJq2 +e8e501d6083bea786629ca5e485e8b18caab4815 +pLnKEIesooU diff --git a/examples/url-parsing/url-parsing.go b/examples/url-parsing/url-parsing.go index b4e0050..f7590f1 100644 --- a/examples/url-parsing/url-parsing.go +++ b/examples/url-parsing/url-parsing.go @@ -3,9 +3,11 @@ package main -import "fmt" -import "net" -import "net/url" +import ( + "fmt" + "net" + "net/url" +) func main() { diff --git a/examples/url-parsing/url-parsing.hash b/examples/url-parsing/url-parsing.hash index 019a1a6..77021f1 100644 --- a/examples/url-parsing/url-parsing.hash +++ b/examples/url-parsing/url-parsing.hash @@ -1,2 +1,2 @@ -b7a0813e9413bfcc956cc58b850f655dd129ebb7 -AL79Lv-9CWo +babc12f5066652f4cb0151231c06f1037298ff28 +M218D9Tldlr diff --git a/examples/worker-pools/worker-pools.go b/examples/worker-pools/worker-pools.go index 84c8bf1..1584d59 100644 --- a/examples/worker-pools/worker-pools.go +++ b/examples/worker-pools/worker-pools.go @@ -3,8 +3,10 @@ package main -import "fmt" -import "time" +import ( + "fmt" + "time" +) // Here's the worker, of which we'll run several // concurrent instances. These workers will receive diff --git a/examples/worker-pools/worker-pools.hash b/examples/worker-pools/worker-pools.hash index 9f101b7..dbfeb88 100644 --- a/examples/worker-pools/worker-pools.hash +++ b/examples/worker-pools/worker-pools.hash @@ -1,2 +1,2 @@ -bc69c6602d438413dcb9ceac112299ee253e4575 -yuHsGf712D1 +9b30cdfc3f46d634c3b8671a7ae1551c133fb6e2 +IiKZ-nj-nKY diff --git a/public/base64-encoding b/public/base64-encoding index d60fe9d..7bf8d28 100644 --- a/public/base64-encoding +++ b/public/base64-encoding @@ -42,7 +42,7 @@ encoding/decoding.

    - +
    package main
     
    @@ -58,8 +58,10 @@ save us some space below.

    -
    import b64 "encoding/base64"
    -import "fmt"
    +          
    import (
    +    b64 "encoding/base64"
    +    "fmt"
    +)
     
    @@ -189,7 +191,7 @@ but they both decode to the original string as desired.

    diff --git a/public/channel-synchronization b/public/channel-synchronization index 16de092..7a0d3a3 100644 --- a/public/channel-synchronization +++ b/public/channel-synchronization @@ -45,7 +45,7 @@ you may prefer to use a WaitGroup.

    - +
    package main
     
    @@ -58,8 +58,10 @@ you may prefer to use a WaitGroup.

    -
    import "fmt"
    -import "time"
    +          
    import (
    +    "fmt"
    +    "time"
    +)
     
    @@ -182,7 +184,7 @@ started.

    diff --git a/public/collection-functions b/public/collection-functions index 2acb092..569c4b3 100644 --- a/public/collection-functions +++ b/public/collection-functions @@ -75,7 +75,7 @@ helper function.

    - +
    package main
     
    @@ -88,8 +88,10 @@ helper function.

    -
    import "strings"
    -import "fmt"
    +          
    import (
    +    "fmt"
    +    "strings"
    +)
     
    @@ -369,7 +371,7 @@ type.

    diff --git a/public/command-line-arguments b/public/command-line-arguments index 1cb6ffd..a2aa9ff 100644 --- a/public/command-line-arguments +++ b/public/command-line-arguments @@ -44,7 +44,7 @@ For example, go run hello.go uses run and - +
    package main
     
    @@ -57,8 +57,10 @@ For example, go run hello.go uses run and -
    import "os"
    -import "fmt"
    +          
    import (
    +    "fmt"
    +    "os"
    +)
     
    @@ -168,7 +170,7 @@ with flags.

    diff --git a/public/command-line-flags b/public/command-line-flags index b2230fa..76e2bfc 100644 --- a/public/command-line-flags +++ b/public/command-line-flags @@ -44,7 +44,7 @@ command-line flag.

    - +
    package main
     
    @@ -60,8 +60,10 @@ implement our example command-line program.

    -
    import "flag"
    -import "fmt"
    +          
    import (
    +    "flag"
    +    "fmt"
    +)
     
    @@ -308,7 +310,7 @@ and show the help text again.

    diff --git a/public/constants b/public/constants index 17379bf..31e2c7b 100644 --- a/public/constants +++ b/public/constants @@ -42,7 +42,7 @@ and numeric values.

    - +
    package main
     
    @@ -55,8 +55,10 @@ and numeric values.

    -
    import "fmt"
    -import "math"
    +          
    import (
    +    "fmt"
    +    "math"
    +)
     
    @@ -181,7 +183,7 @@ assignment or function call. For example, here
    diff --git a/public/defer b/public/defer index 6c62c64..f99d59d 100644 --- a/public/defer +++ b/public/defer @@ -44,7 +44,7 @@ purposes of cleanup. defer is often used where e.g. - +
    package main
     
    @@ -57,8 +57,10 @@ purposes of cleanup. defer is often used where e.g. -
    import "fmt"
    -import "os"
    +          
    import (
    +    "fmt"
    +    "os"
    +)
     
    @@ -210,7 +212,7 @@ after being written.

    diff --git a/public/environment-variables b/public/environment-variables index c452feb..25504ae 100644 --- a/public/environment-variables +++ b/public/environment-variables @@ -44,7 +44,7 @@ Let’s look at how to set, get, and list environment variables.

    - +
    package main
     
    @@ -57,9 +57,11 @@ Let’s look at how to set, get, and list environment variables.

    -
    import "os"
    -import "strings"
    -import "fmt"
    +          
    import (
    +    "fmt"
    +    "os"
    +    "strings"
    +)
     
    @@ -184,7 +186,7 @@ program picks that value up.

    diff --git a/public/epoch b/public/epoch index 644ef79..76a9b20 100644 --- a/public/epoch +++ b/public/epoch @@ -44,7 +44,7 @@ Here’s how to do it in Go.

    - +
    package main
     
    @@ -57,8 +57,10 @@ Here’s how to do it in Go.

    -
    import "fmt"
    -import "time"
    +          
    import (
    +    "fmt"
    +    "time"
    +)
     
    @@ -175,7 +177,7 @@ parsing and formatting.

    diff --git a/public/errors b/public/errors index b0ea98e..351cb86 100644 --- a/public/errors +++ b/public/errors @@ -48,7 +48,7 @@ non-error tasks.

    - +
    package main
     
    @@ -61,8 +61,10 @@ non-error tasks.

    -
    import "errors"
    -import "fmt"
    +          
    import (
    +    "errors"
    +    "fmt"
    +)
     
    @@ -297,7 +299,7 @@ on the Go blog for more on error handling.

    diff --git a/public/execing-processes b/public/execing-processes index 500d807..98ce62a 100644 --- a/public/execing-processes +++ b/public/execing-processes @@ -49,7 +49,7 @@ function.

    - +
    package main
     
    @@ -62,9 +62,11 @@ function.

    -
    import "syscall"
    -import "os"
    -import "os/exec"
    +          
    import (
    +    "os"
    +    "os/exec"
    +    "syscall"
    +)
     
    @@ -201,7 +203,7 @@ processes covers most use cases for fork.

    diff --git a/public/exit b/public/exit index b8c38a6..5929eb6 100644 --- a/public/exit +++ b/public/exit @@ -38,7 +38,7 @@ status.

    - +
    package main
     
    @@ -51,8 +51,10 @@ status.

    -
    import "fmt"
    -import "os"
    +          
    import (
    +    "fmt"
    +    "os"
    +)
     
    @@ -168,7 +170,7 @@ the status in the terminal.

    diff --git a/public/interfaces b/public/interfaces index eddb066..fad0ed0 100644 --- a/public/interfaces +++ b/public/interfaces @@ -42,7 +42,7 @@ signatures.

    - +
    package main
     
    @@ -55,8 +55,10 @@ signatures.

    -
    import "fmt"
    -import "math"
    +          
    import (
    +    "fmt"
    +    "math"
    +)
     
    @@ -234,7 +236,7 @@ these structs as arguments to measure.

    diff --git a/public/json b/public/json index a0d6395..e2327ec 100644 --- a/public/json +++ b/public/json @@ -43,7 +43,7 @@ data types.

    - +
    package main
     
    @@ -56,9 +56,11 @@ data types.

    -
    import "encoding/json"
    -import "fmt"
    -import "os"
    +          
    import (
    +    "encoding/json"
    +    "fmt"
    +    "os"
    +)
     
    @@ -414,7 +416,7 @@ for more.

    diff --git a/public/number-parsing b/public/number-parsing index db31e0d..269da85 100644 --- a/public/number-parsing +++ b/public/number-parsing @@ -42,7 +42,7 @@ in many programs; here’s how to do it in Go.

    - +
    package main
     
    @@ -57,8 +57,10 @@ parsing.

    -
    import "strconv"
    -import "fmt"
    +          
    import (
    +    "fmt"
    +    "strconv"
    +)
     
    @@ -211,7 +213,7 @@ bits.

    diff --git a/public/random-numbers b/public/random-numbers index ffafb29..d3685c5 100644 --- a/public/random-numbers +++ b/public/random-numbers @@ -43,7 +43,7 @@ generation.

    - +
    package main
     
    @@ -56,9 +56,11 @@ generation.

    -
    import "time"
    -import "fmt"
    -import "math/rand"
    +          
    import (
    +    "fmt"
    +    "math/rand"
    +    "time"
    +)
     
    @@ -227,7 +229,7 @@ that Go can provide.

    diff --git a/public/rate-limiting b/public/rate-limiting index 897642b..33dd251 100644 --- a/public/rate-limiting +++ b/public/rate-limiting @@ -45,7 +45,7 @@ channels, and tickers.

    - +
    package main
     
    @@ -58,8 +58,10 @@ channels, and tickers.

    -
    import "time"
    -import "fmt"
    +          
    import (
    +    "fmt"
    +    "time"
    +)
     
    @@ -259,7 +261,7 @@ then serve the remaining 2 with ~200ms delays each.

    diff --git a/public/regular-expressions b/public/regular-expressions index d63163e..76529e3 100644 --- a/public/regular-expressions +++ b/public/regular-expressions @@ -43,7 +43,7 @@ in Go.

    - +
    package main
     
    @@ -56,9 +56,11 @@ in Go.

    -
    import "bytes"
    -import "fmt"
    -import "regexp"
    +          
    import (
    +    "bytes"
    +    "fmt"
    +    "regexp"
    +)
     
    @@ -340,7 +342,7 @@ the regexp package docs
    diff --git a/public/select b/public/select index 8be3cf4..116ac3b 100644 --- a/public/select +++ b/public/select @@ -43,7 +43,7 @@ select is a powerful feature of Go.

    - +
    package main
     
    @@ -56,8 +56,10 @@ select is a powerful feature of Go.

    -
    import "time"
    -import "fmt"
    +          
    import (
    +    "fmt"
    +    "time"
    +)
     
    @@ -181,7 +183,7 @@ concurrently.

    diff --git a/public/sha1-hashes b/public/sha1-hashes index b072bf7..4db0375 100644 --- a/public/sha1-hashes +++ b/public/sha1-hashes @@ -46,7 +46,7 @@ compute SHA1 hashes in Go.

    - +
    package main
     
    @@ -61,8 +61,10 @@ compute SHA1 hashes in Go.

    -
    import "crypto/sha1"
    -import "fmt"
    +          
    import (
    +    "crypto/sha1"
    +    "fmt"
    +)
     
    @@ -201,7 +203,7 @@ you should carefully research
    diff --git a/public/signals b/public/signals index 28c2b5a..b0109b5 100644 --- a/public/signals +++ b/public/signals @@ -46,7 +46,7 @@ Here’s how to handle signals in Go with channels.

    - +
    package main
     
    @@ -59,10 +59,12 @@ Here’s how to handle signals in Go with channels.

    -
    import "fmt"
    -import "os"
    -import "os/signal"
    -import "syscall"
    +          
    import (
    +    "fmt"
    +    "os"
    +    "os/signal"
    +    "syscall"
    +)
     
    @@ -186,7 +188,7 @@ causing the program to print interrupt and then exit.

    diff --git a/public/sorting b/public/sorting index b52d375..ded8f48 100644 --- a/public/sorting +++ b/public/sorting @@ -43,7 +43,7 @@ builtins first.

    - +
    package main
     
    @@ -56,8 +56,10 @@ builtins first.

    -
    import "fmt"
    -import "sort"
    +          
    import (
    +    "fmt"
    +    "sort"
    +)
     
    @@ -158,7 +160,7 @@ slices and true as the result of our AreSorted test. diff --git a/public/sorting-by-functions b/public/sorting-by-functions index 904dbf5..f86a188 100644 --- a/public/sorting-by-functions +++ b/public/sorting-by-functions @@ -45,7 +45,7 @@ in Go.

    - +
    package main
     
    @@ -58,8 +58,10 @@ in Go.

    -
    import "sort"
    -import "fmt"
    +          
    import (
    +    "fmt"
    +    "sort"
    +)
     
    @@ -175,7 +177,7 @@ functions.

    diff --git a/public/spawning-processes b/public/spawning-processes index 634bd69..da8dfc5 100644 --- a/public/spawning-processes +++ b/public/spawning-processes @@ -46,7 +46,7 @@ of spawning processes from Go.

    - +
    package main
     
    @@ -59,9 +59,11 @@ of spawning processes from Go.

    -
    import "fmt"
    -import "io/ioutil"
    -import "os/exec"
    +          
    import (
    +    "fmt"
    +    "io/ioutil"
    +    "os/exec"
    +)
     
    @@ -257,7 +259,7 @@ as if we had run them directly from the command-line.

    diff --git a/public/string-formatting b/public/string-formatting index 438e9a5..6616ed0 100644 --- a/public/string-formatting +++ b/public/string-formatting @@ -43,7 +43,7 @@ common string formatting tasks.

    - +
    package main
     
    @@ -56,8 +56,10 @@ common string formatting tasks.

    -
    import "fmt"
    -import "os"
    +          
    import (
    +    "fmt"
    +    "os"
    +)
     
    @@ -455,7 +457,7 @@ and returns a string without printing it anywhere.

    diff --git a/public/string-functions b/public/string-functions index 05a6e1c..093c467 100644 --- a/public/string-functions +++ b/public/string-functions @@ -43,7 +43,7 @@ to give you a sense of the package.

    - +
    package main
     
    @@ -56,8 +56,10 @@ to give you a sense of the package.

    -
    import s "strings"
    -import "fmt"
    +          
    import (
    +    "fmt"
    +    s "strings"
    +)
     
    @@ -207,7 +209,7 @@ for more information.

    diff --git a/public/switch b/public/switch index a93cff8..f0eff96 100644 --- a/public/switch +++ b/public/switch @@ -42,7 +42,7 @@ branches.

    - +
    package main
     
    @@ -55,8 +55,10 @@ branches.

    -
    import "fmt"
    -import "time"
    +          
    import (
    +    "fmt"
    +    "time"
    +)
     
    @@ -201,7 +203,7 @@ type corresponding to its clause.

    diff --git a/public/tickers b/public/tickers index 8bb9280..dd2bb28 100644 --- a/public/tickers +++ b/public/tickers @@ -45,7 +45,7 @@ periodically until we stop it.

    - +
    package main
     
    @@ -58,8 +58,10 @@ periodically until we stop it.

    -
    import "time"
    -import "fmt"
    +          
    import (
    +    "fmt"
    +    "time"
    +)
     
    @@ -169,7 +171,7 @@ before we stop it.

    diff --git a/public/time b/public/time index 49421de..12137d8 100644 --- a/public/time +++ b/public/time @@ -42,7 +42,7 @@ here are some examples.

    - +
    package main
     
    @@ -55,8 +55,10 @@ here are some examples.

    -
    import "fmt"
    -import "time"
    +          
    import (
    +    "fmt"
    +    "time"
    +)
     
    @@ -268,7 +270,7 @@ the Unix epoch.

    diff --git a/public/time-formatting-parsing b/public/time-formatting-parsing index cd8a62a..5c8f266 100644 --- a/public/time-formatting-parsing +++ b/public/time-formatting-parsing @@ -42,7 +42,7 @@ pattern-based layouts.

    - +
    package main
     
    @@ -55,8 +55,10 @@ pattern-based layouts.

    -
    import "fmt"
    -import "time"
    +          
    import (
    +    "fmt"
    +    "time"
    +)
     
    @@ -202,7 +204,7 @@ explaining the parsing problem.

    diff --git a/public/timeouts b/public/timeouts index 8142985..39238ed 100644 --- a/public/timeouts +++ b/public/timeouts @@ -44,7 +44,7 @@ elegant thanks to channels and select.

    - +
    package main
     
    @@ -57,8 +57,10 @@ elegant thanks to channels and select.

    -
    import "time"
    -import "fmt"
    +          
    import (
    +    "fmt"
    +    "time"
    +)
     
    @@ -179,7 +181,7 @@ out and the second succeeding.

    diff --git a/public/timers b/public/timers index 1cff001..977afef 100644 --- a/public/timers +++ b/public/timers @@ -45,7 +45,7 @@ at tickers.

    - +
    package main
     
    @@ -58,8 +58,10 @@ at tickers.

    -
    import "time"
    -import "fmt"
    +          
    import (
    +    "fmt"
    +    "time"
    +)
     
    @@ -168,7 +170,7 @@ a chance to expire.

    diff --git a/public/url-parsing b/public/url-parsing index 668af2f..0cd07f4 100644 --- a/public/url-parsing +++ b/public/url-parsing @@ -42,7 +42,7 @@ Here’s how to parse URLs in Go.

    - +
    package main
     
    @@ -55,9 +55,11 @@ Here’s how to parse URLs in Go.

    -
    import "fmt"
    -import "net"
    -import "net/url"
    +          
    import (
    +    "fmt"
    +    "net"
    +    "net/url"
    +)
     
    @@ -233,7 +235,7 @@ pieces that we extracted.

    diff --git a/public/worker-pools b/public/worker-pools index 0ddf1b3..70a6a0b 100644 --- a/public/worker-pools +++ b/public/worker-pools @@ -42,7 +42,7 @@ a worker pool using goroutines and channels.

    - +
    package main
     
    @@ -55,8 +55,10 @@ a worker pool using goroutines and channels.

    -
    import "fmt"
    -import "time"
    +          
    import (
    +    "fmt"
    +    "time"
    +)
     
    @@ -221,7 +223,7 @@ there are 3 workers operating concurrently.