diff --git a/README.md b/README.md index 0b35f4c..c8706d9 100644 --- a/README.md +++ b/README.md @@ -81,7 +81,10 @@ $ heroku open -r $DEPLOY ### License -This work is licensed under a +This work is copyright Mark McGranaghan and licensed under a +[Creative Commons Attribution 3.0 Unported License](http://creativecommons.org/licenses/by/3.0/). + +The Go Gopher is copyright the Go Authors and licensed under a [Creative Commons Attribution 3.0 Unported License](http://creativecommons.org/licenses/by/3.0/). diff --git a/examples/arrays/arrays.hash b/examples/arrays/arrays.hash new file mode 100644 index 0000000..516ae70 --- /dev/null +++ b/examples/arrays/arrays.hash @@ -0,0 +1,2 @@ +305975d13d24223181d13f042b290906d86c1a0e +l-A8eBnwio diff --git a/examples/atomic-counters/atomic-counters.hash b/examples/atomic-counters/atomic-counters.hash new file mode 100644 index 0000000..c62b86e --- /dev/null +++ b/examples/atomic-counters/atomic-counters.hash @@ -0,0 +1,2 @@ +97f1f28e352163cb841fb26dc05dced9fa8efde5 +sKIaNsJquU diff --git a/examples/base64-encoding/base64-encoding.hash b/examples/base64-encoding/base64-encoding.hash new file mode 100644 index 0000000..25e1653 --- /dev/null +++ b/examples/base64-encoding/base64-encoding.hash @@ -0,0 +1,2 @@ +e57f5be3a796261fb4a55cdb0580a254e14b4930 +t6rFm2x4Yr diff --git a/examples/channel-buffering/channel-buffering.hash b/examples/channel-buffering/channel-buffering.hash new file mode 100644 index 0000000..c82a990 --- /dev/null +++ b/examples/channel-buffering/channel-buffering.hash @@ -0,0 +1,2 @@ +122140f7ad1bc5cff4fcd7a9e7245b87aaca3ec5 +34PVHwO6Bn diff --git a/examples/channel-directions/channel-directions.hash b/examples/channel-directions/channel-directions.hash new file mode 100644 index 0000000..e881c47 --- /dev/null +++ b/examples/channel-directions/channel-directions.hash @@ -0,0 +1,2 @@ +635cc13dfe33123ac188e01e3002d3aa935d765f +P9Fujfpa1f diff --git a/examples/channel-synchronization/channel-synchronization.hash b/examples/channel-synchronization/channel-synchronization.hash new file mode 100644 index 0000000..8680448 --- /dev/null +++ b/examples/channel-synchronization/channel-synchronization.hash @@ -0,0 +1,2 @@ +fe3e2ea1a67d0f95ce4cb18f3e8aa16d416de0ce +0DfW-1RMqi diff --git a/examples/channels/channels.hash b/examples/channels/channels.hash new file mode 100644 index 0000000..0d8c963 --- /dev/null +++ b/examples/channels/channels.hash @@ -0,0 +1,2 @@ +be6689b44773c1f7a83d409d1e2f5ba7d6c7b006 +aVTMoY5FNt diff --git a/examples/closing-channels/closing-channels.hash b/examples/closing-channels/closing-channels.hash new file mode 100644 index 0000000..b6f3076 --- /dev/null +++ b/examples/closing-channels/closing-channels.hash @@ -0,0 +1,2 @@ +5205898a520533e46ea24c849848d19ebc2d08a9 +eFZ2SeKswH diff --git a/examples/closures/closures.hash b/examples/closures/closures.hash new file mode 100644 index 0000000..a1f8255 --- /dev/null +++ b/examples/closures/closures.hash @@ -0,0 +1,2 @@ +2e062d01989caada16c4b22ff6a35cd58e4eb819 +gQtEWkhWyp diff --git a/examples/collection-functions/collection-functions.hash b/examples/collection-functions/collection-functions.hash new file mode 100644 index 0000000..cab1518 --- /dev/null +++ b/examples/collection-functions/collection-functions.hash @@ -0,0 +1,2 @@ +ed54b3fc0512ccace0f3d0b74975c9bcd2e7a8a2 +3PNdke3Wia diff --git a/examples/command-line-arguments/command-line-arguments.hash b/examples/command-line-arguments/command-line-arguments.hash new file mode 100644 index 0000000..4fd8561 --- /dev/null +++ b/examples/command-line-arguments/command-line-arguments.hash @@ -0,0 +1,2 @@ +41c970a1ef29ad2a05307e6c783ff52ab80eaccd +44uyYt_TRl diff --git a/examples/command-line-flags/command-line-flags.hash b/examples/command-line-flags/command-line-flags.hash new file mode 100644 index 0000000..03cb054 --- /dev/null +++ b/examples/command-line-flags/command-line-flags.hash @@ -0,0 +1,2 @@ +a22c44511e84451cca813659f3803fb7ae48dab0 +9xlvGqQjhl diff --git a/examples/constants/constants.hash b/examples/constants/constants.hash new file mode 100644 index 0000000..b5ab256 --- /dev/null +++ b/examples/constants/constants.hash @@ -0,0 +1,2 @@ +3de4f16f1ed032378268411b2173b95e8000305d +T5sj0eINnp diff --git a/examples/defer/defer.hash b/examples/defer/defer.hash new file mode 100644 index 0000000..726cb8c --- /dev/null +++ b/examples/defer/defer.hash @@ -0,0 +1,2 @@ +570699fc50a1d39e9d0ad6a4461aef3248b080e1 +9aoHwzHcAo diff --git a/examples/environment-variables/environment-variables.hash b/examples/environment-variables/environment-variables.hash new file mode 100644 index 0000000..ef39f96 --- /dev/null +++ b/examples/environment-variables/environment-variables.hash @@ -0,0 +1,2 @@ +4d0832c5a1ddd4e95474791e8802c15452358214 +kfqLhpmEpw diff --git a/examples/epoch/epoch.hash b/examples/epoch/epoch.hash new file mode 100644 index 0000000..95cd863 --- /dev/null +++ b/examples/epoch/epoch.hash @@ -0,0 +1,2 @@ +b56f9122928886ac695c15657c2ff5ec7c5436d9 +3jXHvYbLUz diff --git a/examples/errors/errors.hash b/examples/errors/errors.hash new file mode 100644 index 0000000..aceb00c --- /dev/null +++ b/examples/errors/errors.hash @@ -0,0 +1,2 @@ +07cffb3d4e37162ab7e9e0a192561ddc8042b81a +BmDQXkPPTk diff --git a/examples/execing-processes/execing-processes.hash b/examples/execing-processes/execing-processes.hash new file mode 100644 index 0000000..9267a36 --- /dev/null +++ b/examples/execing-processes/execing-processes.hash @@ -0,0 +1,2 @@ +ae75526fdd970c450fa3ed52c70cf400a45d0770 +iEAD2cYC-h diff --git a/examples/exit/exit.hash b/examples/exit/exit.hash new file mode 100644 index 0000000..cb4c6a9 --- /dev/null +++ b/examples/exit/exit.hash @@ -0,0 +1,2 @@ +dc0bb3eaafa045d6aa05e88aff39322a1ccf822e +CDiAh9SXRM diff --git a/examples/for/for.hash b/examples/for/for.hash new file mode 100644 index 0000000..954a23c --- /dev/null +++ b/examples/for/for.hash @@ -0,0 +1,2 @@ +e7dbd5f44ea79a3eb41e4535575197b9eadc0e03 +mGqqcBZ0jv diff --git a/examples/functions/functions.hash b/examples/functions/functions.hash new file mode 100644 index 0000000..98b77eb --- /dev/null +++ b/examples/functions/functions.hash @@ -0,0 +1,2 @@ +19cac21e4a057e8335ce78a30de9a43c2b18d522 +2EXoOWfGf_ diff --git a/examples/goroutines/goroutines.hash b/examples/goroutines/goroutines.hash new file mode 100644 index 0000000..b2bce9e --- /dev/null +++ b/examples/goroutines/goroutines.hash @@ -0,0 +1,2 @@ +5562eb9bebe9ed442e8fa6801fab86b00fd1d2ba +aIO_Wi3hJj diff --git a/examples/hello-world/hello-world.hash b/examples/hello-world/hello-world.hash new file mode 100644 index 0000000..dd889b9 --- /dev/null +++ b/examples/hello-world/hello-world.hash @@ -0,0 +1,2 @@ +66ef79aa3cbc8789c141ce7031fb3f493e003aad +H8bxSpw9Jq diff --git a/examples/if-else/if-else.hash b/examples/if-else/if-else.hash new file mode 100644 index 0000000..a1981ed --- /dev/null +++ b/examples/if-else/if-else.hash @@ -0,0 +1,2 @@ +4187a4268be1cd85fdd6e9a211d1e4f534666ad6 +p_ykufAYRj diff --git a/examples/interfaces/interfaces.hash b/examples/interfaces/interfaces.hash new file mode 100644 index 0000000..2f3f3db --- /dev/null +++ b/examples/interfaces/interfaces.hash @@ -0,0 +1,2 @@ +853be73c5685a0510da77c22c64727afa7fb0581 +vx8bwC-Bmq diff --git a/examples/json/json.go b/examples/json/json.go index ac9edad..7b10e0b 100644 --- a/examples/json/json.go +++ b/examples/json/json.go @@ -68,7 +68,7 @@ func main() { // Now let's look at decoding JSON data into Go // values. Here's an example for a generic data - // structure. + // structure. byt := []byte(`{"num":6.0,"strs":["a","b"]}`) // We need to provide a variable where the JSON diff --git a/examples/json/json.hash b/examples/json/json.hash new file mode 100644 index 0000000..2b57c3a --- /dev/null +++ b/examples/json/json.hash @@ -0,0 +1,2 @@ +12f985bb444e2bd6d72ea52a24ebc5f4f82c5b9b +4L2wMVv7tW diff --git a/examples/line-filters/line-filters.hash b/examples/line-filters/line-filters.hash new file mode 100644 index 0000000..c5c6dc4 --- /dev/null +++ b/examples/line-filters/line-filters.hash @@ -0,0 +1,2 @@ +fe6d70a3115bd0974aa6f3f8444bb539d17fc027 +OSS71nSpkV diff --git a/examples/maps/maps.hash b/examples/maps/maps.hash new file mode 100644 index 0000000..34d7452 --- /dev/null +++ b/examples/maps/maps.hash @@ -0,0 +1,2 @@ +572365c80895f32241032397bd69094886892d90 +D-F9YN_V8r diff --git a/examples/methods/methods.hash b/examples/methods/methods.hash new file mode 100644 index 0000000..bcb0099 --- /dev/null +++ b/examples/methods/methods.hash @@ -0,0 +1,2 @@ +24cfb9ad45e43c2d49163149bc55925a4e1b3c7a +254m_9Yjwa diff --git a/examples/multiple-return-values/multiple-return-values.hash b/examples/multiple-return-values/multiple-return-values.hash new file mode 100644 index 0000000..f746983 --- /dev/null +++ b/examples/multiple-return-values/multiple-return-values.hash @@ -0,0 +1,2 @@ +9e0a75102d83565fefbf1893728b15633dc44a2c +LrDt1Wah0M diff --git a/examples/mutexes/mutexes.hash b/examples/mutexes/mutexes.hash new file mode 100644 index 0000000..221d44d --- /dev/null +++ b/examples/mutexes/mutexes.hash @@ -0,0 +1,2 @@ +a42e6b574ab2c2bdd38df53d77b9a2f3f3e0b10c +-_LKNceBru diff --git a/examples/non-blocking-channel-operations/non-blocking-channel-operations.hash b/examples/non-blocking-channel-operations/non-blocking-channel-operations.hash new file mode 100644 index 0000000..3bca2a4 --- /dev/null +++ b/examples/non-blocking-channel-operations/non-blocking-channel-operations.hash @@ -0,0 +1,2 @@ +119ced4df4f79795b163483b6abfd855e76ef577 +M972dltae2 diff --git a/examples/number-parsing/number-parsing.hash b/examples/number-parsing/number-parsing.hash new file mode 100644 index 0000000..714860f --- /dev/null +++ b/examples/number-parsing/number-parsing.hash @@ -0,0 +1,2 @@ +0d2155e9863a73c098d44637e92403d7f5e8e965 +N90EppECFk diff --git a/examples/panic/panic.hash b/examples/panic/panic.hash new file mode 100644 index 0000000..5c411f6 --- /dev/null +++ b/examples/panic/panic.hash @@ -0,0 +1,2 @@ +91639bbcfcc6ed088295a9ee6b1c36ab35ae402a +c86oXzfQOt diff --git a/examples/pointers/pointers.hash b/examples/pointers/pointers.hash new file mode 100644 index 0000000..6cb7efd --- /dev/null +++ b/examples/pointers/pointers.hash @@ -0,0 +1,2 @@ +85cff3345d2f22b65a5d54eb8f7aa8f508f27887 +KdE4TBbUL2 diff --git a/examples/random-numbers/random-numbers.hash b/examples/random-numbers/random-numbers.hash new file mode 100644 index 0000000..bedcd90 --- /dev/null +++ b/examples/random-numbers/random-numbers.hash @@ -0,0 +1,2 @@ +62b0562c92dd84ecb9408df4c517031d75b1e337 +C0_kuFx3ET diff --git a/examples/range-over-channels/range-over-channels.hash b/examples/range-over-channels/range-over-channels.hash new file mode 100644 index 0000000..b707556 --- /dev/null +++ b/examples/range-over-channels/range-over-channels.hash @@ -0,0 +1,2 @@ +e415b1f2ae531b319bb9aca69b17e7b916511744 +WN7NNh9tvh diff --git a/examples/range/range.hash b/examples/range/range.hash new file mode 100644 index 0000000..6c3be57 --- /dev/null +++ b/examples/range/range.hash @@ -0,0 +1,2 @@ +e6458150862a6b26e95629ba6a90a6a3036d7d52 +Ys3V-ohVRy diff --git a/examples/rate-limiting/rate-limiting.hash b/examples/rate-limiting/rate-limiting.hash new file mode 100644 index 0000000..3eaf668 --- /dev/null +++ b/examples/rate-limiting/rate-limiting.hash @@ -0,0 +1,2 @@ +d74aebb12f618f22ec776eb5b4de92985104c197 +e7yzIk97-p diff --git a/examples/reading-files/reading-files.go b/examples/reading-files/reading-files.go index c6cbdaf..f07b186 100644 --- a/examples/reading-files/reading-files.go +++ b/examples/reading-files/reading-files.go @@ -69,7 +69,7 @@ func main() { // The `bufio` package implements a buffered // reader that may be useful both for its efficiency // with many small reads and because of the additional - // reading methods it provides. + // reading methods it provides. r4 := bufio.NewReader(f) b4, err := r4.Peek(5) check(err) diff --git a/examples/reading-files/reading-files.hash b/examples/reading-files/reading-files.hash new file mode 100644 index 0000000..d39e052 --- /dev/null +++ b/examples/reading-files/reading-files.hash @@ -0,0 +1,2 @@ +251ab050de24051bb7d9858940421fdec41fa674 +VcLqpSwnkN diff --git a/examples/recursion/recursion.hash b/examples/recursion/recursion.hash new file mode 100644 index 0000000..b867f04 --- /dev/null +++ b/examples/recursion/recursion.hash @@ -0,0 +1,2 @@ +5d1ba6b03a50ccae2a0f46865eb72c587e11857c +RFn-rf42ap diff --git a/examples/regular-expressions/regular-expressions.hash b/examples/regular-expressions/regular-expressions.hash new file mode 100644 index 0000000..98a545e --- /dev/null +++ b/examples/regular-expressions/regular-expressions.hash @@ -0,0 +1,2 @@ +0ebd0a44997fe20d3fa0caa8b5f2cfa96ff1db13 +7bnr2EXlxK diff --git a/examples/select/select.hash b/examples/select/select.hash new file mode 100644 index 0000000..758358e --- /dev/null +++ b/examples/select/select.hash @@ -0,0 +1,2 @@ +572ae309be3d0fd9b029aeb908013b2914a36734 +NGSkDrli6L diff --git a/examples/sha1-hashes/sha1-hashes.hash b/examples/sha1-hashes/sha1-hashes.hash new file mode 100644 index 0000000..081d3d7 --- /dev/null +++ b/examples/sha1-hashes/sha1-hashes.hash @@ -0,0 +1,2 @@ +6a896270e34f2696b881a8fa7e68bfff57dee51f +YUaWWEeB4U diff --git a/examples/signals/signals.hash b/examples/signals/signals.hash new file mode 100644 index 0000000..f5a3787 --- /dev/null +++ b/examples/signals/signals.hash @@ -0,0 +1,2 @@ +42ec8f6064228f89f97e2798150d741317d2bf05 +d42wO1q1oh diff --git a/examples/slices/slices.go b/examples/slices/slices.go index c44cca0..1918f98 100644 --- a/examples/slices/slices.go +++ b/examples/slices/slices.go @@ -27,7 +27,7 @@ func main() { // In addition to these basic operations, slices // support several more that make them richer than - // arrays. One is the builtin `append`, which + // arrays. One is the builtin `append`, which // returns a slice containing one or more new values. // Note that we need to accept a return value from // append as we may get a new slice value. diff --git a/examples/slices/slices.hash b/examples/slices/slices.hash new file mode 100644 index 0000000..68bb6a1 --- /dev/null +++ b/examples/slices/slices.hash @@ -0,0 +1,2 @@ +d900c3b1cf2bd96591f7ad7ce7fd9e592ec31139 +dPQErsP6Yc diff --git a/examples/sorting-by-functions/sorting-by-functions.hash b/examples/sorting-by-functions/sorting-by-functions.hash new file mode 100644 index 0000000..d2b00d7 --- /dev/null +++ b/examples/sorting-by-functions/sorting-by-functions.hash @@ -0,0 +1,2 @@ +9b184444231f799b9388037d8142613a598e9345 +M06NADP985 diff --git a/examples/sorting/sorting.hash b/examples/sorting/sorting.hash new file mode 100644 index 0000000..ffb7712 --- /dev/null +++ b/examples/sorting/sorting.hash @@ -0,0 +1,2 @@ +4e576421f2bdbd11847c367d223bd30d0e301990 +roQOJXtqAb diff --git a/examples/spawning-processes/spawning-processes.hash b/examples/spawning-processes/spawning-processes.hash new file mode 100644 index 0000000..60e08a2 --- /dev/null +++ b/examples/spawning-processes/spawning-processes.hash @@ -0,0 +1,2 @@ +4e31686ab1dac4fa0e3ce753a6af207c51b9b049 +utd_H-XJtC diff --git a/examples/stateful-goroutines/stateful-goroutines.hash b/examples/stateful-goroutines/stateful-goroutines.hash new file mode 100644 index 0000000..a3eefdd --- /dev/null +++ b/examples/stateful-goroutines/stateful-goroutines.hash @@ -0,0 +1,2 @@ +13c5072f2ccb7afb85b8c7ea9a97f94423aef8de +2YrrJo4H6W diff --git a/examples/string-formatting/string-formatting.hash b/examples/string-formatting/string-formatting.hash new file mode 100644 index 0000000..998c0ab --- /dev/null +++ b/examples/string-formatting/string-formatting.hash @@ -0,0 +1,2 @@ +fece72ed980c2ee55b3f1d5d8e8d83aed81dc814 +qayRuqXHym diff --git a/examples/string-functions/string-functions.hash b/examples/string-functions/string-functions.hash new file mode 100644 index 0000000..354a324 --- /dev/null +++ b/examples/string-functions/string-functions.hash @@ -0,0 +1,2 @@ +66fdf78c9be9a41e52bcf2e8b01ab95fa7753401 +COXm374QWe diff --git a/examples/structs/structs.hash b/examples/structs/structs.hash new file mode 100644 index 0000000..9004363 --- /dev/null +++ b/examples/structs/structs.hash @@ -0,0 +1,2 @@ +49cad39331ee5e9fb8d8dad99d3aff7f18a4e6d0 +OMCP5KFC10 diff --git a/examples/switch/switch.hash b/examples/switch/switch.hash new file mode 100644 index 0000000..e6d7380 --- /dev/null +++ b/examples/switch/switch.hash @@ -0,0 +1,2 @@ +1040d0721b871f78f221a0e9e4a61ea3b0e6de70 +8b5CajPcHn diff --git a/examples/tickers/tickers.hash b/examples/tickers/tickers.hash new file mode 100644 index 0000000..d0a1b54 --- /dev/null +++ b/examples/tickers/tickers.hash @@ -0,0 +1,2 @@ +39781500e9ccbd39282e2dce5cb8003715bfe78a +U0PO7ZZU3l diff --git a/examples/time-formatting-parsing/time-formatting-parsing.hash b/examples/time-formatting-parsing/time-formatting-parsing.hash new file mode 100644 index 0000000..81cf2af --- /dev/null +++ b/examples/time-formatting-parsing/time-formatting-parsing.hash @@ -0,0 +1,2 @@ +89dedeb30079f7f5f42202c249609c570563a1ae +JqNGqbuqF1 diff --git a/examples/time/time.hash b/examples/time/time.hash new file mode 100644 index 0000000..4783733 --- /dev/null +++ b/examples/time/time.hash @@ -0,0 +1,2 @@ +a5fb723728be749919194acf860f483a7c2329c7 +NxuQTlVA2l diff --git a/examples/timeouts/timeouts.hash b/examples/timeouts/timeouts.hash new file mode 100644 index 0000000..3981e0e --- /dev/null +++ b/examples/timeouts/timeouts.hash @@ -0,0 +1,2 @@ +48dc2824c813ec9195866592e4bed211fa9a5098 +CoBnJiRyx3 diff --git a/examples/timers/timers.hash b/examples/timers/timers.hash new file mode 100644 index 0000000..911fc88 --- /dev/null +++ b/examples/timers/timers.hash @@ -0,0 +1,2 @@ +a5b44952d93152ba6bfdb100ea30cd8446cad47e +6fSHrYxpMu diff --git a/examples/url-parsing/url-parsing.go b/examples/url-parsing/url-parsing.go index 1229bb8..991c6e9 100644 --- a/examples/url-parsing/url-parsing.go +++ b/examples/url-parsing/url-parsing.go @@ -9,7 +9,7 @@ import "strings" func main() { - // We'll parse this example URL, which includes a + // We'll parse this example URL, which includes a // scheme, authentication info, host, port, path, // query params, and query fragment. s := "postgres://user:pass@host.com:5432/path?k=v#f" diff --git a/examples/url-parsing/url-parsing.hash b/examples/url-parsing/url-parsing.hash new file mode 100644 index 0000000..f90f79f --- /dev/null +++ b/examples/url-parsing/url-parsing.hash @@ -0,0 +1,2 @@ +677974cc6b7ba9a63f6c7f2979fd46ef2a4202d7 +eaMv0skOfY diff --git a/examples/values/values.hash b/examples/values/values.hash new file mode 100644 index 0000000..7343a3c --- /dev/null +++ b/examples/values/values.hash @@ -0,0 +1,2 @@ +c5a53c75cc57dc15ac4458285c9b139bf85c67bf +fgGVOyuZdu diff --git a/examples/variables/variables.hash b/examples/variables/variables.hash new file mode 100644 index 0000000..8e7c623 --- /dev/null +++ b/examples/variables/variables.hash @@ -0,0 +1,2 @@ +8c74aae4850358073926dba5d98aa402f9968251 +Zv45CSMaiD diff --git a/examples/variadic-functions/variadic-functions.hash b/examples/variadic-functions/variadic-functions.hash new file mode 100644 index 0000000..95ad82d --- /dev/null +++ b/examples/variadic-functions/variadic-functions.hash @@ -0,0 +1,2 @@ +25bcf8d28adf0587d1959e88f32786d7f21872b2 +wRPLOM1VIH diff --git a/examples/worker-pools/worker-pools.hash b/examples/worker-pools/worker-pools.hash new file mode 100644 index 0000000..09eb260 --- /dev/null +++ b/examples/worker-pools/worker-pools.hash @@ -0,0 +1,2 @@ +9d5b1d008d278df7db7697d56d491d982da86e7d +y12QxBsKtT diff --git a/examples/writing-files/writing-files.hash b/examples/writing-files/writing-files.hash new file mode 100644 index 0000000..16a7fd6 --- /dev/null +++ b/examples/writing-files/writing-files.hash @@ -0,0 +1,2 @@ +0853ca57176872e9b34b501855ceb8bf5fbdbf46 +5usz1Oc-xY diff --git a/public/arrays b/public/arrays index 2f24682..14b3c44 100644 --- a/public/arrays +++ b/public/arrays @@ -30,6 +30,7 @@ specific length.

+ @@ -39,6 +40,7 @@ specific length.

+
package main
 
@@ -50,6 +52,7 @@ specific length.

+
import "fmt"
 
@@ -61,6 +64,7 @@ specific length.

+
func main() {
 
@@ -76,6 +80,7 @@ zero-valued, which for ints means 0s.

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

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

+
    fmt.Println("len:", len(a))
 
@@ -118,6 +125,7 @@ in one line.

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

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

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

+ diff --git a/public/atomic-counters b/public/atomic-counters index 1102b1e..174cc61 100644 --- a/public/atomic-counters +++ b/public/atomic-counters @@ -34,6 +34,7 @@ counters accessed by multiple goroutines.

+ @@ -43,6 +44,7 @@ counters accessed by multiple goroutines.

+
package main
 
@@ -54,6 +56,7 @@ counters accessed by multiple goroutines.

+
import "fmt"
 import "time"
 import "sync/atomic"
@@ -68,6 +71,7 @@ counters accessed by multiple goroutines.

+
func main() {
 
@@ -81,6 +85,7 @@ counters accessed by multiple goroutines.

+
    var ops uint64 = 0
 
@@ -95,6 +100,7 @@ once a millisecond.

+
    for i := 0; i < 50; i++ {
         go func() {
             for {
@@ -112,6 +118,7 @@ address of our ops counter with the
 
           
           
+	        
             
                atomic.AddUint64(&ops, 1)
 
@@ -124,6 +131,7 @@ address of our ops counter with the +
                runtime.Gosched()
             }
         }()
@@ -139,6 +147,7 @@ address of our ops counter with the
 
           
           
+	        
             
    time.Sleep(time.Second)
 
@@ -156,6 +165,7 @@ fetch the value.

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

+
$ go run atomic-counters.go
 ops: 40200
 
@@ -189,6 +200,7 @@ state.

+ diff --git a/public/base64-encoding b/public/base64-encoding index 84b987a..0d07525 100644 --- a/public/base64-encoding +++ b/public/base64-encoding @@ -30,6 +30,7 @@ encoding/decoding.

+ @@ -39,6 +40,7 @@ encoding/decoding.

+
package main
 
@@ -53,6 +55,7 @@ save us some space below.

+
import b64 "encoding/base64"
 import "fmt"
 
@@ -65,6 +68,7 @@ save us some space below.

+
func main() {
 
@@ -77,6 +81,7 @@ save us some space below.

+
    data := "abc123!?$*&()'-=@~"
 
@@ -92,6 +97,7 @@ cast our string to that type.

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

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

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

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

+
YWJjMTIzIT8kKiYoKSctPUB-
 abc123!?$*&()'-=@~
 
diff --git a/public/channel-buffering b/public/channel-buffering index ee0e9b4..5893c33 100644 --- a/public/channel-buffering +++ b/public/channel-buffering @@ -34,6 +34,7 @@ those values.

+ @@ -43,6 +44,7 @@ those values.

+
package main
 
@@ -54,6 +56,7 @@ those values.

+
import "fmt"
 
@@ -65,6 +68,7 @@ those values.

+
func main() {
 
@@ -78,6 +82,7 @@ those values.

+
    messages := make(chan string, 2)
 
@@ -92,6 +97,7 @@ concurrent receive.

+
    messages <- "buffered"
     messages <- "channel"
 
@@ -105,6 +111,7 @@ concurrent receive.

+
    fmt.Println(<-messages)
     fmt.Println(<-messages)
 }
@@ -122,6 +129,7 @@ concurrent receive.

+
$ go run channel-buffering.go 
 buffered
 channel
diff --git a/public/channel-directions b/public/channel-directions
index 0c9831f..c1171ae 100644
--- a/public/channel-directions
+++ b/public/channel-directions
@@ -32,6 +32,7 @@ the program.

+ @@ -41,6 +42,7 @@ the program.

+
package main
 
@@ -52,6 +54,7 @@ the program.

+
import "fmt"
 
@@ -66,6 +69,7 @@ receive on this channel.

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

+
func pong(pings <-chan string, pongs chan<- string) {
     msg := <-pings
     pongs <- msg
@@ -95,6 +100,7 @@ receive on this channel.

+
func main() {
     pings := make(chan string, 1)
     pongs := make(chan string, 1)
@@ -116,6 +122,7 @@ receive on this channel.

+
$ go run channel-directions.go
 passed message
 
diff --git a/public/channel-synchronization b/public/channel-synchronization index 55f85b8..ed359f3 100644 --- a/public/channel-synchronization +++ b/public/channel-synchronization @@ -31,6 +31,7 @@ blocking receive to wait for a goroutine to finish.

+ @@ -40,6 +41,7 @@ blocking receive to wait for a goroutine to finish.

+
package main
 
@@ -51,6 +53,7 @@ blocking receive to wait for a goroutine to finish.

+
import "fmt"
 import "time"
 
@@ -66,6 +69,7 @@ goroutine that this function’s work is done.

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

+
    done <- true
 }
 
@@ -93,6 +98,7 @@ goroutine that this function’s work is done.

+
func main() {
 
@@ -106,6 +112,7 @@ notify on.

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

+
    <-done
 }
 
@@ -136,6 +144,7 @@ worker on the channel.

+
$ go run channel-synchronization.go      
 working...done                  
 
@@ -151,6 +160,7 @@ started.

+ diff --git a/public/channels b/public/channels index 799189d..fbb9329 100644 --- a/public/channels +++ b/public/channels @@ -33,6 +33,7 @@ underly much of Go’s functionality.

+ @@ -42,6 +43,7 @@ underly much of Go’s functionality.

+
package main
 
@@ -53,6 +55,7 @@ underly much of Go’s functionality.

+
import "fmt"
 
@@ -64,6 +67,7 @@ underly much of Go’s functionality.

+
func main() {
 
@@ -77,6 +81,7 @@ Channels are typed by the values they convey.

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

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

+
    msg := <-messages
     fmt.Println(msg)
 }
@@ -125,6 +132,7 @@ channel.

+
$ go run channels.go 
 ping
 
@@ -141,6 +149,7 @@ message without having to use any other synchronization.

+ diff --git a/public/closing-channels b/public/closing-channels index 46544e6..c614498 100644 --- a/public/closing-channels +++ b/public/closing-channels @@ -31,6 +31,7 @@ completion to the channel’s receivers.

+ @@ -40,6 +41,7 @@ completion to the channel’s receivers.

+
package main
 
@@ -51,6 +53,7 @@ completion to the channel’s receivers.

+
import "fmt"
 
@@ -66,6 +69,7 @@ the worker we’ll close the jobs channel.

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

+
    go func() {
         for {
             j, more := <-jobs
@@ -110,6 +115,7 @@ channel, then closes it.

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

+
    <-done
 }
 
@@ -145,6 +152,7 @@ we saw earlier.

+
$ go run closing-channels.go 
 sent job 1
 received job 1
@@ -166,6 +174,7 @@ example: range over channels.

+ diff --git a/public/closures b/public/closures index e38208a..fcc0b6d 100644 --- a/public/closures +++ b/public/closures @@ -32,6 +32,7 @@ a function inline without having to name it.

+ @@ -41,6 +42,7 @@ a function inline without having to name it.

+
package main
 
@@ -52,6 +54,7 @@ a function inline without having to name it.

+
import "fmt"
 
@@ -67,6 +70,7 @@ form a closure.

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

+
func main() {
 
@@ -99,6 +104,7 @@ we call nextInt.

+
    nextInt := intSeq()
 
@@ -112,6 +118,7 @@ a few times.

+
    fmt.Println(nextInt())
     fmt.Println(nextInt())
     fmt.Println(nextInt())
@@ -127,6 +134,7 @@ particular function, create and test a new one.

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

+
$ go run closures.go
 1
 2
@@ -161,6 +170,7 @@ recursion.

+ diff --git a/public/collection-functions b/public/collection-functions index 0813854..e692eb7 100644 --- a/public/collection-functions +++ b/public/collection-functions @@ -32,6 +32,7 @@ collection with a custom function.

+ @@ -46,6 +47,7 @@ your program and data types.

+ @@ -61,6 +63,7 @@ helper function.

+ @@ -70,6 +73,7 @@ helper function.

+
package main
 
@@ -81,6 +85,7 @@ helper function.

+
import "strings"
 import "fmt"
 
@@ -95,6 +100,7 @@ helper function.

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

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

+
func Any(vs []string, f func(string) bool) bool {
     for _, v := range vs {
         if f(v) {
@@ -150,6 +158,7 @@ satisfy the predicate f.

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

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

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

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

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

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

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

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

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

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

+
    fmt.Println(Map(strs, strings.ToUpper))
 
@@ -306,6 +325,7 @@ type.

+
}
 
@@ -321,6 +341,7 @@ type.

+
$ go run collection-functions.go 
 2
 false
diff --git a/public/command-line-arguments b/public/command-line-arguments
index 327c6d6..8067ee8 100644
--- a/public/command-line-arguments
+++ b/public/command-line-arguments
@@ -32,6 +32,7 @@ For example, go run hello.go uses run and
 
           
           
+	        
             
           
         
@@ -41,6 +42,7 @@ For example, go run hello.go uses run and
             
           
           
+	        
             
package main
 
@@ -52,6 +54,7 @@ For example, go run hello.go uses run and +
import "os"
 import "fmt"
 
@@ -64,6 +67,7 @@ For example, go run hello.go uses run and +
func main() {
 
@@ -79,6 +83,7 @@ holds the arguments to the program.

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

+
    arg := os.Args[3]
 
@@ -103,6 +109,7 @@ holds the arguments to the program.

+
    fmt.Println(argsWithProg)
     fmt.Println(argsWithoutProg)
     fmt.Println(arg)
@@ -123,6 +130,7 @@ build a binary with go build first.

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

+ diff --git a/public/command-line-flags b/public/command-line-flags index 8061b3c..6b0bb4b 100644 --- a/public/command-line-flags +++ b/public/command-line-flags @@ -32,6 +32,7 @@ command-line flag.

+ @@ -41,6 +42,7 @@ command-line flag.

+
package main
 
@@ -55,6 +57,7 @@ implement our example command-line program.

+
import "flag"
 import "fmt"
 
@@ -67,6 +70,7 @@ implement our example command-line program.

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

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

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

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

+
    flag.Parse()
 
@@ -142,6 +150,7 @@ to get the actual option values.

+
    fmt.Println("word:", *wordPtr)
     fmt.Println("numb:", *numbPtr)
     fmt.Println("fork:", *boolPtr)
@@ -165,6 +174,7 @@ binary directly.

+
$ go build command-line-flags.go
 
@@ -178,6 +188,7 @@ all flags.

+
$ ./command-line-flags -word=opt -numb=7 -fork -svar=flag
 word: opt
 numb: 7
@@ -196,6 +207,7 @@ their default values.

+
$ ./command-line-flags -word=opt
 word: opt
 numb: 42
@@ -214,6 +226,7 @@ any flags.

+
$ ./command-line-flags -word=opt a1 a2 a3
 word: opt
 ...
@@ -231,6 +244,7 @@ will be interpreted as positional arguments).

+
$ ./command-line-flags -word=opt a1 a2 a3 -numb=7
 word: opt
 numb: 42
@@ -249,6 +263,7 @@ generated help text for the command-line program.

+
$ ./command-line-flags -h
 Usage of ./command-line-flags:
   -fork=false: a bool
@@ -268,6 +283,7 @@ an show the help text again.

+
$ ./command-line-flags -wat
 flag provided but not defined: -wat
 Usage of ./command-line-flags:
@@ -284,6 +300,7 @@ way to parameterize programs.

+ diff --git a/public/constants b/public/constants index 813eb93..f9c1320 100644 --- a/public/constants +++ b/public/constants @@ -30,6 +30,7 @@ and numeric values.

+ @@ -39,6 +40,7 @@ and numeric values.

+
package main
 
@@ -50,6 +52,7 @@ and numeric values.

+
import "fmt"
 import "math"
 
@@ -63,6 +66,7 @@ and numeric values.

+
const s string = "constant"
 
@@ -74,6 +78,7 @@ and numeric values.

+
func main() {
     fmt.Println(s)
 
@@ -88,6 +93,7 @@ statement can.

+
    const n = 500000000
 
@@ -101,6 +107,7 @@ arbitrary precision.

+
    const d = 3e20 / n
     fmt.Println(d)
 
@@ -115,6 +122,7 @@ one, such as by an explicit cast.

+
    fmt.Println(int64(d))
 
@@ -130,6 +138,7 @@ assignment or function call. For example, here +
    fmt.Println(math.Sin(n))
 }
 
@@ -146,6 +155,7 @@ assignment or function call. For example, here +
$ go run constant.go 
 constant
 6e+11
diff --git a/public/defer b/public/defer
index 4a978c7..130870b 100644
--- a/public/defer
+++ b/public/defer
@@ -32,6 +32,7 @@ purposes of cleanup. defer is often used where e.g.
 
           
           
+	        
             
           
         
@@ -41,6 +42,7 @@ purposes of cleanup. defer is often used where e.g.
             
           
           
+	        
             
package main
 
@@ -52,6 +54,7 @@ purposes of cleanup. defer is often used where e.g. +
import "fmt"
 import "os"
 
@@ -67,6 +70,7 @@ do that with defer.

+
func main() {
 
@@ -83,6 +87,7 @@ of the enclosing function (main), after +
    f := createFile("/tmp/defer.txt")
     defer closeFile(f)
     writeFile(f)
@@ -97,6 +102,7 @@ of the enclosing function (main), after
             
           
           
+	        
             
func createFile(p string) *os.File {
     fmt.Println("creating")
     f, err := os.Create(p)
@@ -115,6 +121,7 @@ of the enclosing function (main), after
             
           
           
+	        
             
func writeFile(f *os.File) {
     fmt.Println("writing")
     fmt.Fprintln(f, "data")
@@ -128,6 +135,7 @@ of the enclosing function (main), after
             
           
           
+	        
             
}
 
@@ -139,6 +147,7 @@ of the enclosing function (main), after +
func closeFile(f *os.File) {
     fmt.Println("closing")
     f.Close()
@@ -159,6 +168,7 @@ after being written.

+
$ go run defer.go
 creating
 writing
diff --git a/public/environment-variables b/public/environment-variables
index 5b86db8..cb61053 100644
--- a/public/environment-variables
+++ b/public/environment-variables
@@ -32,6 +32,7 @@ Let’s look at how to set, get, and list environment variables.

+ @@ -41,6 +42,7 @@ Let’s look at how to set, get, and list environment variables.

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

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

+
func main() {
 
@@ -80,6 +84,7 @@ environment.

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

+
    fmt.Println()
     for _, e := range os.Environ() {
         pair := strings.Split(e, "=")
@@ -120,6 +126,7 @@ value for FOO that we set in the program, but that
 
           
           
+	        
             
$ go run environment-variables.go
 FOO: 1
 BAR: 
@@ -135,6 +142,7 @@ particular machine.

+
TERM_PROGRAM
 PATH
 SHELL
@@ -151,6 +159,7 @@ program picks that value up.

+
$ BAR=2 go run environment-variables.go
 FOO: 1
 BAR: 2
diff --git a/public/epoch b/public/epoch
index 1d372b3..9f2ec37 100644
--- a/public/epoch
+++ b/public/epoch
@@ -32,6 +32,7 @@ Here’s how to do it in Go.

+ @@ -41,6 +42,7 @@ Here’s how to do it in Go.

+
package main
 
@@ -52,6 +54,7 @@ Here’s how to do it in Go.

+
import "fmt"
 import "time"
 
@@ -64,6 +67,7 @@ Here’s how to do it in Go.

+
func main() {
 
@@ -78,6 +82,7 @@ nanoseconds, respectively.

+
    now := time.Now()
     secs := now.Unix()
     nanos := now.UnixNano()
@@ -95,6 +100,7 @@ dive from nanoseconds.

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

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

+
$ go run epoch.go 
 2012-10-31 16:13:58.292387 +0000 UTC
 1351700038
@@ -147,6 +155,7 @@ parsing and formatting.

+ diff --git a/public/errors b/public/errors index 913656c..b07e219 100644 --- a/public/errors +++ b/public/errors @@ -36,6 +36,7 @@ non-error tasks.

+ @@ -45,6 +46,7 @@ non-error tasks.

+
package main
 
@@ -56,6 +58,7 @@ non-error tasks.

+
import "errors"
 import "fmt"
 
@@ -70,6 +73,7 @@ have type error, a built-in interface.

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

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

+
    }
 
@@ -108,6 +114,7 @@ there was no error.

+
    return arg + 3, nil
 }
 
@@ -124,6 +131,7 @@ to explicitly represent an argument error.

+
type argError struct {
     arg  int
     prob string
@@ -138,6 +146,7 @@ to explicitly represent an argument error.

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

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

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

+
func main() {
 
@@ -195,6 +207,7 @@ idiom in Go code.

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

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

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

+ diff --git a/public/execing-processes b/public/execing-processes index 5e9eb34..baa501a 100644 --- a/public/execing-processes +++ b/public/execing-processes @@ -37,6 +37,7 @@ function.

+ @@ -46,6 +47,7 @@ function.

+
package main
 
@@ -57,6 +59,7 @@ function.

+
import "syscall"
 import "os"
 import "os/exec"
@@ -70,6 +73,7 @@ function.

+
func main() {
 
@@ -85,6 +89,7 @@ we’ll use exec.LookPath to find it (probably +
    binary, lookErr := exec.LookPath("ls")
     if lookErr != nil {
         panic(lookErr)
@@ -103,6 +108,7 @@ be the program name.

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

+
    env := os.Environ()
 
@@ -133,6 +140,7 @@ value.

+
    execErr := syscall.Exec(binary, args, env)
     if execErr != nil {
         panic(execErr)
@@ -153,6 +161,7 @@ value.

+
$ go run execing-processes.go
 total 16
 drwxr-xr-x  4 mark 136B Oct 3 16:29 .
@@ -172,6 +181,7 @@ processes covers most use cases for fork.

+ diff --git a/public/exit b/public/exit index a0bc797..3188ddb 100644 --- a/public/exit +++ b/public/exit @@ -30,6 +30,7 @@ status.

+ @@ -39,6 +40,7 @@ status.

+
package main
 
@@ -50,6 +52,7 @@ status.

+
import "fmt"
 import "os"
 
@@ -62,6 +65,7 @@ status.

+
func main() {
 
@@ -75,6 +79,7 @@ this fmt.Println will never be called.

+
    defer fmt.Println("!")
 
@@ -87,6 +92,7 @@ this fmt.Println will never be called.

+
    os.Exit(3)
 }
 
@@ -103,6 +109,7 @@ use os.Exit.

+ @@ -118,6 +125,7 @@ will be picked up by go and printed.

+
$ go run exit.go
 exit status 3
 
@@ -132,6 +140,7 @@ the status in the terminal.

+
$ go build exit.go
 $ ./exit
 $ echo $?
@@ -147,6 +156,7 @@ the status in the terminal.

+ diff --git a/public/for b/public/for index 4d6c435..83e76a3 100644 --- a/public/for +++ b/public/for @@ -30,6 +30,7 @@ three basic types of for loops.

+ @@ -39,6 +40,7 @@ three basic types of for loops.

+
package main
 
@@ -50,6 +52,7 @@ three basic types of for loops.

+
import "fmt"
 
@@ -61,6 +64,7 @@ three basic types of for loops.

+
func main() {
 
@@ -73,6 +77,7 @@ three basic types of for loops.

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

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

+
    for {
         fmt.Println("loop")
         break
@@ -124,6 +131,7 @@ the enclosing function.

+
$ go run for.go
 1
 2
@@ -145,6 +153,7 @@ structures.

+ diff --git a/public/functions b/public/functions index 54c3651..267ae28 100644 --- a/public/functions +++ b/public/functions @@ -30,6 +30,7 @@ functions with a few different examples.

+ @@ -39,6 +40,7 @@ functions with a few different examples.

+
package main
 
@@ -50,6 +52,7 @@ functions with a few different examples.

+
import "fmt"
 
@@ -63,6 +66,7 @@ their sum as an int.

+
func plus(a int, b int) int {
 
@@ -77,6 +81,7 @@ expression.

+
    return a + b
 }
 
@@ -89,6 +94,7 @@ expression.

+
func main() {
 
@@ -102,6 +108,7 @@ expression.

+
    res := plus(1, 2)
     fmt.Println("1+2 =", res)
 }
@@ -119,6 +126,7 @@ expression.

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

+ diff --git a/public/goroutines b/public/goroutines index 4fbedf2..67fe18b 100644 --- a/public/goroutines +++ b/public/goroutines @@ -29,6 +29,7 @@ + @@ -38,6 +39,7 @@ +
package main
 
@@ -49,6 +51,7 @@ +
import "fmt"
 
@@ -60,6 +63,7 @@ +
func f(from string) {
     for i := 0; i < 3; i++ {
         fmt.Println(from, ":", i)
@@ -75,6 +79,7 @@
             
           
           
+	        
             
func main() {
 
@@ -89,6 +94,7 @@ synchronously.

+
    f("direct")
 
@@ -103,6 +109,7 @@ concurrently with the calling one.

+
    go f("goroutine")
 
@@ -116,6 +123,7 @@ function call.

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

+
    var input string
     fmt.Scanln(&input)
     fmt.Println("done")
@@ -155,6 +164,7 @@ goroutines being run concurrently by the Go runtime.

+
$ go run goroutines.go
 direct : 0
 direct : 1
@@ -177,6 +187,7 @@ concurrent Go programs: channels.

+ diff --git a/public/hello-world b/public/hello-world index 88176eb..bfb0c69 100644 --- a/public/hello-world +++ b/public/hello-world @@ -30,6 +30,7 @@ message. Here’s the full source code.

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

+
import "fmt"
 
@@ -52,6 +54,7 @@ message. Here’s the full source code.

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

+
$ go run hello-world.go
 hello world
 
@@ -85,6 +89,7 @@ binaries. We can do this using go build.

+
$ go build hello-world.go
 $ ls
 hello-world	hello-world.go
@@ -99,6 +104,7 @@ binaries. We can do this using go build.

+
$ ./hello-world
 hello world
 
@@ -113,6 +119,7 @@ learn more about the language.

+ diff --git a/public/if-else b/public/if-else index 02c00c3..c54f82e 100644 --- a/public/if-else +++ b/public/if-else @@ -30,6 +30,7 @@ straight-forward.

+ @@ -39,6 +40,7 @@ straight-forward.

+
package main
 
@@ -50,6 +52,7 @@ straight-forward.

+
import "fmt"
 
@@ -61,6 +64,7 @@ straight-forward.

+
func main() {
 
@@ -73,6 +77,7 @@ straight-forward.

+
    if 7%2 == 0 {
         fmt.Println("7 is even")
     } else {
@@ -89,6 +94,7 @@ straight-forward.

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

+
    if num := 9; num < 0 {
         fmt.Println(num, "is negative")
     } else if num < 10 {
@@ -125,6 +132,7 @@ in Go, but that the brackets are required.

+ @@ -138,6 +146,7 @@ in Go, but that the brackets are required.

+
$ go run if-else.go 
 7 is odd
 8 is divisible by 4
@@ -155,6 +164,7 @@ for basic conditions.

+ diff --git a/public/interfaces b/public/interfaces index 24a40a7..3330a70 100644 --- a/public/interfaces +++ b/public/interfaces @@ -30,6 +30,7 @@ signatures.

+ @@ -39,6 +40,7 @@ signatures.

+
package main
 
@@ -50,6 +52,7 @@ signatures.

+
import "fmt"
 import "math"
 
@@ -63,6 +66,7 @@ signatures.

+
type geometry interface {
     area() float64
     perim() float64
@@ -79,6 +83,7 @@ signatures.

+
type square struct {
     width, height float64
 }
@@ -98,6 +103,7 @@ implement geometry on squares.

+
func (s square) area() float64 {
     return s.width * s.height
 }
@@ -115,6 +121,7 @@ implement geometry on squares.

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

+
func measure(g geometry) {
     fmt.Println(g)
     fmt.Println(g.area())
@@ -150,6 +158,7 @@ to work on any geometry.

+
func main() {
     s := square{width: 3, height: 4}
     c := circle{radius: 5}
@@ -167,6 +176,7 @@ these structs as arguments to measure.

+
    measure(s)
     measure(c)
 }
@@ -184,6 +194,7 @@ these structs as arguments to measure.

+
$ go run interfaces.go
 {3 4}
 12
@@ -203,6 +214,7 @@ these structs as arguments to measure.

+ diff --git a/public/json b/public/json index 43bfa4d..ebe459d 100644 --- a/public/json +++ b/public/json @@ -31,6 +31,7 @@ data types.

+ @@ -40,6 +41,7 @@ data types.

+
package main
 
@@ -51,6 +53,7 @@ data types.

+
import "encoding/json"
 import "fmt"
 import "os"
@@ -66,6 +69,7 @@ decoding of custom types below.

+
type Response1 struct {
     Page   int
     Fruits []string
@@ -84,6 +88,7 @@ decoding of custom types below.

+
func main() {
 
@@ -98,6 +103,7 @@ values.

+
    bolB, _ := json.Marshal(true)
     fmt.Println(string(bolB))
 
@@ -110,6 +116,7 @@ values.

+
    intB, _ := json.Marshal(1)
     fmt.Println(string(intB))
 
@@ -122,6 +129,7 @@ values.

+
    fltB, _ := json.Marshal(2.34)
     fmt.Println(string(fltB))
 
@@ -134,6 +142,7 @@ values.

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

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

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

+
    res1D := &Response1{
         Page:   1,
         Fruits: []string{"apple", "peach", "pear"}}
@@ -197,6 +209,7 @@ of such tags.

+
    res2D := &Response2{
         Page:   1,
         Fruits: []string{"apple", "peach", "pear"}}
@@ -215,6 +228,7 @@ structure.

+
    byt := []byte(`{"num":6.0,"strs":["a","b"]}`)
 
@@ -230,6 +244,7 @@ to arbitrary data types.

+
    var dat map[string]interface{}
 
@@ -243,6 +258,7 @@ associated errors.

+
    if err := json.Unmarshal(byt, &dat); err != nil {
         panic(err)
     }
@@ -261,6 +277,7 @@ the expected float64 type.

+
    num := dat["num"].(float64)
     fmt.Println(num)
 
@@ -275,6 +292,7 @@ casts.

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

+
    str := `{"page": 1, "fruits": ["apple", "peach"]}`
     res := &Response2{}
     json.Unmarshal([]byte(str), &res)
@@ -313,6 +332,7 @@ stream JSON encodings directly to os.Writers like
 
           
           
+	        
             
    enc := json.NewEncoder(os.Stdout)
     d := map[string]int{"apple": 5, "lettuce": 7}
     enc.Encode(d)
@@ -331,6 +351,7 @@ stream JSON encodings directly to os.Writers like
             
           
           
+	        
             
$ go run json.go
 true
 1
@@ -360,6 +381,7 @@ for more.

+ diff --git a/public/line-filters b/public/line-filters index a8a00d8..b0dd210 100644 --- a/public/line-filters +++ b/public/line-filters @@ -32,6 +32,7 @@ line filters.

+ @@ -44,6 +45,7 @@ pattern to write your own Go line filters.

+
package main
 
@@ -55,6 +57,7 @@ pattern to write your own Go line filters.

+
import (
     "bufio"
     "fmt"
@@ -72,6 +75,7 @@ pattern to write your own Go line filters.

+
func main() {
 
@@ -86,6 +90,7 @@ that we’ll use to read input line-by-line.

+
    rdr := bufio.NewReader(os.Stdin)
     out := os.Stdout
 
@@ -102,6 +107,7 @@ successive input lines.

+
    for {
         switch line, err := rdr.ReadString('\n'); err {
 
@@ -117,6 +123,7 @@ error on this write as we do on the read.

+
        case nil:
             ucl := strings.ToUpper(line)
             if _, err = out.WriteString(ucl); err != nil {
@@ -135,6 +142,7 @@ end of input, so exit gracefully in that case.

+
        case io.EOF:
             os.Exit(0)
 
@@ -149,6 +157,7 @@ error and exit with non-zero status.

+
        default:
             fmt.Fprintln(os.Stderr, "error:", err)
             os.Exit(1)
@@ -171,6 +180,7 @@ lowercase lines.

+
$ echo 'hello'   > /tmp/lines
 $ echo 'filter' >> /tmp/lines
 
@@ -184,6 +194,7 @@ lowercase lines.

+
$ cat /tmp/lines | go run line-filters.go
 HELLO
 FILTER
diff --git a/public/maps b/public/maps
index e8d5d71..f08cdb9 100644
--- a/public/maps
+++ b/public/maps
@@ -30,6 +30,7 @@
 
           
           
+	        
             
           
         
@@ -39,6 +40,7 @@
             
           
           
+	        
             
package main
 
@@ -50,6 +52,7 @@ +
import "fmt"
 
@@ -61,6 +64,7 @@ +
func main() {
 
@@ -74,6 +78,7 @@ +
    m := make(map[string]int)
 
@@ -87,6 +92,7 @@ syntax.

+
    m["k1"] = 7
     m["k2"] = 13
 
@@ -101,6 +107,7 @@ its key/value pairs.

+
    fmt.Println("map:", m)
 
@@ -113,6 +120,7 @@ its key/value pairs.

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

+
    fmt.Println("len:", len(m))
 
@@ -140,6 +149,7 @@ a map.

+
    delete(m, "k2")
     fmt.Println("map:", m)
 
@@ -157,6 +167,7 @@ like 0 or "".

+
    _, prs := m["k2"]
     fmt.Println("prs:", prs)
 
@@ -171,6 +182,7 @@ the same line with this syntax.

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

+
$ go run maps.go 
 map: map[k1:7 k2:13]
 v1:  7
diff --git a/public/methods b/public/methods
index b618bc1..1d2a96c 100644
--- a/public/methods
+++ b/public/methods
@@ -29,6 +29,7 @@
 
           
           
+	        
             
           
         
@@ -38,6 +39,7 @@
             
           
           
+	        
             
package main
 
@@ -49,6 +51,7 @@ +
import "fmt"
 
@@ -60,6 +63,7 @@ +
type rect struct {
     width, height int
 }
@@ -74,6 +78,7 @@
 
           
           
+	        
             
func (r *rect) area() int {
     return r.width * r.height
 }
@@ -89,6 +94,7 @@ receiver types. Here’s an example of a value receiver.

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

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

+
    fmt.Println("area: ", r.area())
     fmt.Println("perim:", r.perim())
 
@@ -132,6 +140,7 @@ receiving struct.

+
    rp := &r
     fmt.Println("area: ", rp.area())
     fmt.Println("perim:", rp.perim())
@@ -150,6 +159,7 @@ receiving struct.

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

+ diff --git a/public/multiple-return-values b/public/multiple-return-values index 5de0a1f..d81ced5 100644 --- a/public/multiple-return-values +++ b/public/multiple-return-values @@ -31,6 +31,7 @@ to return both result and error values from a function.

+ @@ -40,6 +41,7 @@ to return both result and error values from a function.

+
package main
 
@@ -51,6 +53,7 @@ to return both result and error values from a function.

+
import "fmt"
 
@@ -64,6 +67,7 @@ the function returns 2 ints.

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

+
func main() {
 
@@ -90,6 +95,7 @@ call with multiple assignment.

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

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

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

+ diff --git a/public/mutexes b/public/mutexes index 8a076a7..c830315 100644 --- a/public/mutexes +++ b/public/mutexes @@ -32,6 +32,7 @@ to safely access data across multiple goroutines.

+ @@ -41,6 +42,7 @@ to safely access data across multiple goroutines.

+
package main
 
@@ -52,6 +54,7 @@ to safely access data across multiple goroutines.

+
import (
     "fmt"
     "math/rand"
@@ -70,6 +73,7 @@ to safely access data across multiple goroutines.

+
func main() {
 
@@ -82,6 +86,7 @@ to safely access data across multiple goroutines.

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

+
    var mutex = &sync.Mutex{}
 
@@ -108,6 +114,7 @@ operations we perform against the state.

+
    var ops int64 = 0
 
@@ -121,6 +128,7 @@ reads against the state.

+
    for r := 0; r < 100; r++ {
         go func() {
             total := 0
@@ -141,6 +149,7 @@ the ops count.

+
                key := rand.Intn(5)
                 mutex.Lock()
                 total += state[key]
@@ -164,6 +173,7 @@ case we need to do it manually.

+
                runtime.Gosched()
             }
         }()
@@ -180,6 +190,7 @@ using the same pattern we did for reads.

+
    for w := 0; w < 10; w++ {
         go func() {
             for {
@@ -205,6 +216,7 @@ using the same pattern we did for reads.

+
    time.Sleep(time.Second)
 
@@ -217,6 +229,7 @@ using the same pattern we did for reads.

+
    opsFinal := atomic.LoadInt64(&ops)
     fmt.Println("ops:", opsFinal)
 
@@ -230,6 +243,7 @@ using the same pattern we did for reads.

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

+
$ go run mutexes.go
 ops: 3598302
 state: map[1:38 4:98 2:23 3:85 0:44]
@@ -266,6 +281,7 @@ management task using only goroutines and channels.

+ diff --git a/public/non-blocking-channel-operations b/public/non-blocking-channel-operations index 4e5e16c..de4e98c 100644 --- a/public/non-blocking-channel-operations +++ b/public/non-blocking-channel-operations @@ -32,6 +32,7 @@ non-blocking multi-way selects.

+ @@ -41,6 +42,7 @@ non-blocking multi-way selects.

+
package main
 
@@ -52,6 +54,7 @@ non-blocking multi-way selects.

+
import "fmt"
 
@@ -63,6 +66,7 @@ non-blocking multi-way selects.

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

+
    select {
     case msg := <-messages:
         fmt.Println("received message", msg)
@@ -97,6 +102,7 @@ it will immediately take the default case.

+
    msg := "hi"
     select {
     case messages <- msg:
@@ -118,6 +124,7 @@ on both messages and signals.

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

+
$ go run non-blocking-channel-operations.go 
 no message received
 no message sent
diff --git a/public/number-parsing b/public/number-parsing
index 6d92683..910359f 100644
--- a/public/number-parsing
+++ b/public/number-parsing
@@ -30,6 +30,7 @@ in many programs; here’s how to do it in Go.

+ @@ -39,6 +40,7 @@ in many programs; here’s how to do it in Go.

+
package main
 
@@ -52,6 +54,7 @@ parsing.

+
import "strconv"
 import "fmt"
 
@@ -64,6 +67,7 @@ parsing.

+
func main() {
 
@@ -77,6 +81,7 @@ precision to parse.

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

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

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

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

+
    k, _ := strconv.Atoi("135")
     fmt.Println(k)
 
@@ -145,6 +154,7 @@ bits.

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

+
$ go run number-parsing.go 
 1.234
 123
@@ -180,6 +191,7 @@ bits.

+ diff --git a/public/panic b/public/panic index 95620aa..202bf66 100644 --- a/public/panic +++ b/public/panic @@ -32,6 +32,7 @@ aren’t prepared to handle gracefully.

+ @@ -41,6 +42,7 @@ aren’t prepared to handle gracefully.

+
package main
 
@@ -52,6 +54,7 @@ aren’t prepared to handle gracefully.

+
import "os"
 
@@ -63,6 +66,7 @@ aren’t prepared to handle gracefully.

+
func main() {
 
@@ -77,6 +81,7 @@ site designed to panic.

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

+
$ go run panic.go
 panic: a problem
 
@@ -126,6 +133,7 @@ a non-zero status.

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

+ diff --git a/public/play.png b/public/play.png new file mode 100644 index 0000000..ec7028c Binary files /dev/null and b/public/play.png differ diff --git a/public/pointers b/public/pointers index 598dbfd..bc6e8ba 100644 --- a/public/pointers +++ b/public/pointers @@ -31,6 +31,7 @@ within your program.

+ @@ -40,6 +41,7 @@ within your program.

+
package main
 
@@ -51,6 +53,7 @@ within your program.

+
import "fmt"
 
@@ -67,6 +70,7 @@ from the one in the calling function.

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

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

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

+
    zeroval(i)
     fmt.Println("zeroval:", i)
 
@@ -126,6 +133,7 @@ i.e. a pointer to i.

+
    zeroptr(&i)
     fmt.Println("zeroptr:", i)
 
@@ -139,6 +147,7 @@ i.e. a pointer to i.

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

+
$ go run pointers.go
 initial: 1
 zeroval: 1
diff --git a/public/random-numbers b/public/random-numbers
index 384a074..25ba951 100644
--- a/public/random-numbers
+++ b/public/random-numbers
@@ -31,6 +31,7 @@ generation.

+ @@ -40,6 +41,7 @@ generation.

+
package main
 
@@ -51,6 +53,7 @@ generation.

+
import "fmt"
 import "math/rand"
 
@@ -63,6 +66,7 @@ generation.

+
func main() {
 
@@ -76,6 +80,7 @@ generation.

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

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

+
    fmt.Print((rand.Float64()*5)+5, ",")
     fmt.Print((rand.Float64() * 5) + 5)
     fmt.Println()
@@ -119,6 +126,7 @@ give it a well-known seed.

+
    s1 := rand.NewSource(42)
     r1 := rand.New(s1)
 
@@ -133,6 +141,7 @@ functions on the rand package.

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

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

+
$ go run random-numbers.go 
 81,87
 0.6645600532184904
@@ -187,6 +198,7 @@ that Go can provide.

+ diff --git a/public/range b/public/range index 36fb3c1..209c982 100644 --- a/public/range +++ b/public/range @@ -31,6 +31,7 @@ of the data structures we’ve already learned.

+ @@ -40,6 +41,7 @@ of the data structures we’ve already learned.

+
package main
 
@@ -51,6 +53,7 @@ of the data structures we’ve already learned.

+
import "fmt"
 
@@ -62,6 +65,7 @@ of the data structures we’ve already learned.

+
func main() {
 
@@ -75,6 +79,7 @@ Arrays work like this too.

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

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

+
    kvs := map[string]string{"a": "apple", "b": "banana"}
     for k, v := range kvs {
         fmt.Printf("%s -> %s\n", k, v)
@@ -129,6 +136,7 @@ of the rune and the second the rune itself.

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

+
$ go run range.go 
 sum: 9
 index: 1
diff --git a/public/range-over-channels b/public/range-over-channels
index 0690cf4..202fb59 100644
--- a/public/range-over-channels
+++ b/public/range-over-channels
@@ -32,6 +32,7 @@ values received from a channel.

+ @@ -41,6 +42,7 @@ values received from a channel.

+
package main
 
@@ -52,6 +54,7 @@ values received from a channel.

+
import "fmt"
 
@@ -63,6 +66,7 @@ values received from a channel.

+
func main() {
 
@@ -75,6 +79,7 @@ values received from a channel.

+
    queue := make(chan string, 2)
     queue <- "one"
     queue <- "two"
@@ -94,6 +99,7 @@ we’d block on a 3rd receive in the loop.

+
    for elem := range queue {
         fmt.Println(elem)
     }
@@ -112,6 +118,7 @@ we’d block on a 3rd receive in the loop.

+
$ go run range-over-channels.go
 one
 two
@@ -128,6 +135,7 @@ values be received.

+ diff --git a/public/rate-limiting b/public/rate-limiting index cf5a9c6..7eae4fc 100644 --- a/public/rate-limiting +++ b/public/rate-limiting @@ -33,6 +33,7 @@ channels, and tickers.

+ @@ -42,6 +43,7 @@ channels, and tickers.

+
package main
 
@@ -53,6 +55,7 @@ channels, and tickers.

+
import "time"
 import "fmt"
 
@@ -65,6 +68,7 @@ channels, and tickers.

+
func main() {
 
@@ -80,6 +84,7 @@ same name.

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

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

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

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

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

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

+
$ go run rate-limiting.go
 request 1 2012-10-19 00:38:18.687438 +0000 UTC
 request 2 2012-10-19 00:38:18.887471 +0000 UTC
@@ -221,6 +233,7 @@ then serve the remaining 2 with ~200ms delays each.

+
request 1 2012-10-19 00:38:20.487578 +0000 UTC
 request 2 2012-10-19 00:38:20.487645 +0000 UTC
 request 3 2012-10-19 00:38:20.487676 +0000 UTC
diff --git a/public/reading-files b/public/reading-files
index 6517921..f491aff 100644
--- a/public/reading-files
+++ b/public/reading-files
@@ -31,6 +31,7 @@ reading files.

+ @@ -40,6 +41,7 @@ reading files.

+
package main
 
@@ -51,6 +53,7 @@ reading files.

+
import (
     "bufio"
     "fmt"
@@ -70,6 +73,7 @@ This helper will streamline our error checks below.

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

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

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

+
    f, err := os.Open("/tmp/dat")
 
@@ -128,6 +135,7 @@ actually were read.

+
    b1 := make([]byte, 5)
     n1, err := f.Read(b1)
     check(err)
@@ -144,6 +152,7 @@ and Read from there.

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

+
    o3, err := f.Seek(6, 0)
     check(err)
     b3 := make([]byte, 2)
@@ -182,6 +192,7 @@ accomplishes this.

+
    _, err = f.Seek(0, 0)
     check(err)
 
@@ -198,6 +209,7 @@ reading methods it provides.

+
    r4 := bufio.NewReader(f)
     b4, err := r4.Peek(5)
     check(err)
@@ -215,6 +227,7 @@ be scheduled immediately after Opening with
 
           
           
+	        
             
    f.Close()
 
@@ -226,6 +239,7 @@ be scheduled immediately after Opening with +
}
 
@@ -241,6 +255,7 @@ be scheduled immediately after Opening with +
$ echo "hello" > /tmp/dat
 $ echo "go" >>   /tmp/dat
 $ go run reading-files.go 
@@ -261,6 +276,7 @@ be scheduled immediately after Opening with
 
           
           
+	        
             
           
         
diff --git a/public/recursion b/public/recursion
index df21191..295fad2 100644
--- a/public/recursion
+++ b/public/recursion
@@ -31,6 +31,7 @@ Here’s a classic factorial example.

+ @@ -40,6 +41,7 @@ Here’s a classic factorial example.

+
package main
 
@@ -51,6 +53,7 @@ Here’s a classic factorial example.

+
import "fmt"
 
@@ -64,6 +67,7 @@ base case of fact(0).

+
func fact(n int) int {
     if n == 0 {
         return 1
@@ -80,6 +84,7 @@ base case of fact(0).

+
func main() {
     fmt.Println(fact(7))
 }
@@ -97,6 +102,7 @@ base case of fact(0).

+
$ go run recursion.go 
 5040
 
diff --git a/public/regular-expressions b/public/regular-expressions index 9d82695..dd9af01 100644 --- a/public/regular-expressions +++ b/public/regular-expressions @@ -31,6 +31,7 @@ in Go.

+ @@ -40,6 +41,7 @@ in Go.

+
package main
 
@@ -51,6 +53,7 @@ in Go.

+
import "bytes"
 import "fmt"
 import "regexp"
@@ -64,6 +67,7 @@ in Go.

+
func main() {
 
@@ -76,6 +80,7 @@ in Go.

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

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

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

+
    fmt.Println(r.FindString("peach punch"))
 
@@ -130,6 +138,7 @@ matching text.

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

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

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

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

+
    fmt.Println(r.FindAllStringSubmatchIndex(
         "peach punch pinch", -1))
 
@@ -200,6 +213,7 @@ of matches.

+
    fmt.Println(r.FindAllString("peach punch pinch", 2))
 
@@ -215,6 +229,7 @@ function name.

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

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

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

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

+
$ go run regular-expressions.go 
 true
 true
@@ -301,6 +320,7 @@ the regexp package docs
 
           
           
+	        
             
           
         
diff --git a/public/select b/public/select
index de44372..33e0bcf 100644
--- a/public/select
+++ b/public/select
@@ -31,6 +31,7 @@ select is powerful feature of Go.

+ @@ -40,6 +41,7 @@ select is powerful feature of Go.

+
package main
 
@@ -51,6 +53,7 @@ select is powerful feature of Go.

+
import "time"
 import "fmt"
 
@@ -63,6 +66,7 @@ select is powerful feature of Go.

+
func main() {
 
@@ -75,6 +79,7 @@ select is powerful feature of Go.

+
    c1 := make(chan string)
     c2 := make(chan string)
 
@@ -90,6 +95,7 @@ executing in concurrent goroutines.

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

+
    for i := 0; i < 2; i++ {
         select {
         case msg1 := <-c1:
@@ -135,6 +142,7 @@ expected.

+
$ time go run select.go 
 received one
 received two
@@ -151,6 +159,7 @@ concurrently.

+
real	0m2.245s
 
diff --git a/public/sha1-hashes b/public/sha1-hashes index 9a7d958..285c703 100644 --- a/public/sha1-hashes +++ b/public/sha1-hashes @@ -34,6 +34,7 @@ compute SHA1 hashes in Go.

+ @@ -43,6 +44,7 @@ compute SHA1 hashes in Go.

+
package main
 
@@ -56,6 +58,7 @@ compute SHA1 hashes in Go.

+
import "crypto/sha1"
 import "fmt"
 
@@ -68,6 +71,7 @@ compute SHA1 hashes in Go.

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

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

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

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

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

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

+ @@ -171,6 +181,7 @@ you should carefully research + diff --git a/public/signals b/public/signals index 6820a9c..a149a0e 100644 --- a/public/signals +++ b/public/signals @@ -34,6 +34,7 @@ Here’s how to handle signals in Go with channels.

+ @@ -43,6 +44,7 @@ Here’s how to handle signals in Go with channels.

+
package main
 
@@ -54,6 +56,7 @@ Here’s how to handle signals in Go with channels.

+
import "fmt"
 import "os"
 import "os/signal"
@@ -68,6 +71,7 @@ Here’s how to handle signals in Go with channels.

+
func main() {
 
@@ -83,6 +87,7 @@ notify us when the program can exit.)

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

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

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

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

+
$ go run signals.go
 awaiting signal
 ^C
diff --git a/public/site.css b/public/site.css
index 1e698f4..4808e32 100644
--- a/public/site.css
+++ b/public/site.css
@@ -136,6 +136,11 @@ pre, code {
     font-size: 14px; line-height: 18px;
     font-family: 'Menlo', 'Monaco', 'Consolas', 'Lucida Console', monospace;
 }
+img.run {
+  height: 16px;
+  width: 16px;
+  float: right
+}
 
 /* Syntax highlighting */
 body .hll { background-color: #ffffcc }
diff --git a/public/slices b/public/slices
index 1f39e96..e69b209 100644
--- a/public/slices
+++ b/public/slices
@@ -30,6 +30,7 @@ powerful interface to sequences than arrays.

+ @@ -39,6 +40,7 @@ powerful interface to sequences than arrays.

+
package main
 
@@ -50,6 +52,7 @@ powerful interface to sequences than arrays.

+
import "fmt"
 
@@ -61,6 +64,7 @@ powerful interface to sequences than arrays.

+
func main() {
 
@@ -77,6 +81,7 @@ the builtin make. Here we make a slice of +
    s := make([]string, 3)
     fmt.Println("emp:", s)
 
@@ -90,6 +95,7 @@ the builtin make. Here we make a slice of +
    s[0] = "a"
     s[1] = "b"
     s[2] = "c"
@@ -106,6 +112,7 @@ the builtin make. Here we make a slice of
 
           
           
+	        
             
    fmt.Println("len:", len(s))
 
@@ -123,6 +130,7 @@ append as we may get a new slice value.

+
    s = append(s, "d")
     s = append(s, "e", "f")
     fmt.Println("apd:", s)
@@ -139,6 +147,7 @@ into c from s.

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

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

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

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

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

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

+
$ go run slices.go
 emp: [  ]
 set: [a b c]
@@ -261,6 +276,7 @@ implementation of slices in Go.

+ @@ -272,6 +288,7 @@ Go’s other key builtin data structure: maps.

+ diff --git a/public/sorting b/public/sorting index a8dc00d..31dd745 100644 --- a/public/sorting +++ b/public/sorting @@ -31,6 +31,7 @@ builtins first.

+ @@ -40,6 +41,7 @@ builtins first.

+
package main
 
@@ -51,6 +53,7 @@ builtins first.

+
import "fmt"
 import "sort"
 
@@ -63,6 +66,7 @@ builtins first.

+
func main() {
 
@@ -78,6 +82,7 @@ return a new one.

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

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

+
    s := sort.IntsAreSorted(ints)
     fmt.Println("Sorted: ", s)
 }
@@ -126,6 +133,7 @@ slices and true as the result of our AreSorted test.
           
+	        
             
$ go run sorting.go
 Strings: [a b c]
 Ints:    [2 4 7]
diff --git a/public/sorting-by-functions b/public/sorting-by-functions
index 901cbce..85af568 100644
--- a/public/sorting-by-functions
+++ b/public/sorting-by-functions
@@ -33,6 +33,7 @@ in Go.

+ @@ -42,6 +43,7 @@ in Go.

+
package main
 
@@ -53,6 +55,7 @@ in Go.

+
import "sort"
 import "fmt"
 
@@ -69,6 +72,7 @@ type.

+
type ByLength []string
 
@@ -87,6 +91,7 @@ we use len(s[i]) and len(s[j]) here.

+
func (s ByLength) Len() int {
     return len(s)
 }
@@ -110,6 +115,7 @@ slice.

+
func main() {
     fruits := []string{"peach", "banana", "kiwi"}
     sort.Sort(ByLength(fruits))
@@ -131,6 +137,7 @@ length, as desired.

+
$ go run sorting-by-functions.go 
 [kiwi peach banana]
 
@@ -148,6 +155,7 @@ functions.

+ diff --git a/public/spawning-processes b/public/spawning-processes index 56e9ae1..a6d4da7 100644 --- a/public/spawning-processes +++ b/public/spawning-processes @@ -34,6 +34,7 @@ of spawning processes from Go.

+ @@ -43,6 +44,7 @@ of spawning processes from Go.

+
package main
 
@@ -54,6 +56,7 @@ of spawning processes from Go.

+
import "fmt"
 import "io/ioutil"
 import "os/exec"
@@ -67,6 +70,7 @@ of spawning processes from Go.

+
func main() {
 
@@ -82,6 +86,7 @@ to represent this external process.

+
    dateCmd := exec.Command("date")
 
@@ -97,6 +102,7 @@ and collecting its output. If there were no errors, +
    dateOut, err := dateCmd.Output()
     if err != nil {
         panic(err)
@@ -116,6 +122,7 @@ where we pipe data to the external process on its
 
           
           
+	        
             
    grepCmd := exec.Command("grep", "hello")
 
@@ -131,6 +138,7 @@ to exit.

+
    grepIn, _ := grepCmd.StdinPipe()
     grepOut, _ := grepCmd.StdoutPipe()
     grepCmd.Start()
@@ -153,6 +161,7 @@ exactly the same way.

+
    fmt.Println("> grep hello")
     fmt.Println(string(grepBytes))
 
@@ -171,6 +180,7 @@ option:

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

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

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

+
> ls -a -l -h
 drwxr-xr-x  4 mark 136B Oct 3 16:29 .
 drwxr-xr-x 91 mark 3.0K Oct 3 12:50 ..
diff --git a/public/stateful-goroutines b/public/stateful-goroutines
index e78f2d8..485ec2f 100644
--- a/public/stateful-goroutines
+++ b/public/stateful-goroutines
@@ -36,6 +36,7 @@ by exactly 1 goroutine.

+ @@ -45,6 +46,7 @@ by exactly 1 goroutine.

+
package main
 
@@ -56,6 +58,7 @@ by exactly 1 goroutine.

+
import (
     "fmt"
     "math/rand"
@@ -80,6 +83,7 @@ goroutine to respond.

+
type readOp struct {
     key  int
     resp chan int
@@ -99,6 +103,7 @@ goroutine to respond.

+
func main() {
 
@@ -112,6 +117,7 @@ example.

+
    var state = make(map[int]int)
 
@@ -125,6 +131,7 @@ perform.

+
    var ops int64 = 0
 
@@ -139,6 +146,7 @@ respectively.

+
    reads := make(chan *readOp)
     writes := make(chan *writeOp)
 
@@ -158,6 +166,7 @@ on the response channel resp to indicate success +
    go func() {
         for {
             select {
@@ -184,6 +193,7 @@ result over the provided resp channel.

+
    for r := 0; r < 100; r++ {
         go func() {
             for {
@@ -208,6 +218,7 @@ approach.

+
    for w := 0; w < 10; w++ {
         go func() {
             for {
@@ -232,6 +243,7 @@ approach.

+
    time.Sleep(time.Second)
 
@@ -244,6 +256,7 @@ approach.

+
    opsFinal := atomic.LoadInt64(&ops)
     fmt.Println("ops:", opsFinal)
 }
@@ -264,6 +277,7 @@ operations per second.

+
$ go run stateful-goroutines.go
 ops: 807434
 
@@ -284,6 +298,7 @@ program.

+ diff --git a/public/string-formatting b/public/string-formatting index be4465d..9e54b0a 100644 --- a/public/string-formatting +++ b/public/string-formatting @@ -31,6 +31,7 @@ common string formatting tasks.

+ @@ -40,6 +41,7 @@ common string formatting tasks.

+
package main
 
@@ -51,6 +53,7 @@ common string formatting tasks.

+
import "fmt"
 import "os"
 
@@ -63,6 +66,7 @@ common string formatting tasks.

+
type point struct {
     x, y int
 }
@@ -76,6 +80,7 @@ common string formatting tasks.

+
func main() {
 
@@ -90,6 +95,7 @@ an instance of our point struct.

+
    p := point{1, 2}
     fmt.Printf("%v\n", p)
 
@@ -104,6 +110,7 @@ include the struct’s field names.

+
    fmt.Printf("%+v\n", p)
 
@@ -118,6 +125,7 @@ would produce that value.

+
    fmt.Printf("%#v\n", p)
 
@@ -130,6 +138,7 @@ would produce that value.

+
    fmt.Printf("%T\n", p)
 
@@ -142,6 +151,7 @@ would produce that value.

+
    fmt.Printf("%t\n", true)
 
@@ -155,6 +165,7 @@ Use %d for standard, base-10 formatting.

+
    fmt.Printf("%d\n", 123)
 
@@ -167,6 +178,7 @@ Use %d for standard, base-10 formatting.

+
    fmt.Printf("%b\n", 14)
 
@@ -180,6 +192,7 @@ given integer.

+
    fmt.Printf("%c\n", 33)
 
@@ -192,6 +205,7 @@ given integer.

+
    fmt.Printf("%x\n", 456)
 
@@ -205,6 +219,7 @@ floats. For basic decimal formatting use %f.

+
    fmt.Printf("%f\n", 78.9)
 
@@ -218,6 +233,7 @@ different versions of) scientific notation.

+
    fmt.Printf("%e\n", 123400000.0)
     fmt.Printf("%E\n", 123400000.0)
 
@@ -231,6 +247,7 @@ different versions of) scientific notation.

+
    fmt.Printf("%s\n", "\"string\"")
 
@@ -243,6 +260,7 @@ different versions of) scientific notation.

+
    fmt.Printf("%q\n", "\"string\"")
 
@@ -257,6 +275,7 @@ per byte of input.

+
    fmt.Printf("%x\n", "hex this")
 
@@ -269,6 +288,7 @@ per byte of input.

+
    fmt.Printf("%p\n", &p)
 
@@ -286,6 +306,7 @@ spaces.

+
    fmt.Printf("|%6d|%6d|\n", 12, 345)
 
@@ -301,6 +322,7 @@ width.precision syntax.

+
    fmt.Printf("|%6.2f|%6.2f|\n", 1.2, 3.45)
 
@@ -313,6 +335,7 @@ width.precision syntax.

+
    fmt.Printf("|%-6.2f|%-6.2f|\n", 1.2, 3.45)
 
@@ -327,6 +350,7 @@ table-like output. For basic right-justified width.

+
    fmt.Printf("|%6s|%6s|\n", "foo", "b")
 
@@ -339,6 +363,7 @@ table-like output. For basic right-justified width.

+
    fmt.Printf("|%-6s|%-6s|\n", "foo", "b")
 
@@ -353,6 +378,7 @@ and returns a string without printing it anywhere.

+
    s := fmt.Sprintf("a %s", "string")
     fmt.Println(s)
 
@@ -367,6 +393,7 @@ and returns a string without printing it anywhere.

+
    fmt.Fprintf(os.Stderr, "an %s\n", "error")
 }
 
@@ -383,6 +410,7 @@ and returns a string without printing it anywhere.

+
$ go run string-formatting.go
 {1 2}
 {x:1 y:2}
diff --git a/public/string-functions b/public/string-functions
index 9fb9bc7..6b83df4 100644
--- a/public/string-functions
+++ b/public/string-functions
@@ -31,6 +31,7 @@ to give you a sense of the package.

+ @@ -40,6 +41,7 @@ to give you a sense of the package.

+
package main
 
@@ -51,6 +53,7 @@ to give you a sense of the package.

+
import s "strings"
 import "fmt"
 
@@ -65,6 +68,7 @@ it a lot below.

+
var p = fmt.Println
 
@@ -76,6 +80,7 @@ it a lot below.

+
func main() {
 
@@ -92,6 +97,7 @@ as the first argument to the function.

+
    p("Contains:  ", s.Contains("test", "es"))
     p("Count:     ", s.Count("test", "t"))
     p("HasPrefix: ", s.HasPrefix("test", "te"))
@@ -117,6 +123,7 @@ package docs.

+ @@ -129,6 +136,7 @@ and getting a character by index.

+
    p("Len: ", len("hello"))
     p("Char:", "hello"[1])
 }
@@ -146,6 +154,7 @@ and getting a character by index.

+
$ go run string-functions.go
 Contains:   true
 Count:      2
@@ -169,6 +178,7 @@ and getting a character by index.

+
Len:  5
 Char: 101
 
diff --git a/public/structs b/public/structs index 031d0ee..7b41cd5 100644 --- a/public/structs +++ b/public/structs @@ -31,6 +31,7 @@ records.

+ @@ -40,6 +41,7 @@ records.

+
package main
 
@@ -51,6 +53,7 @@ records.

+
import "fmt"
 
@@ -63,6 +66,7 @@ records.

+
type person struct {
     name string
     age  int
@@ -77,6 +81,7 @@ records.

+
func main() {
 
@@ -89,6 +94,7 @@ records.

+
    fmt.Println(person{"Bob", 20})
 
@@ -101,6 +107,7 @@ records.

+
    fmt.Println(person{name: "Alice", age: 30})
 
@@ -113,6 +120,7 @@ records.

+
    fmt.Println(person{name: "Fred"})
 
@@ -125,6 +133,7 @@ records.

+
    fmt.Println(&person{name: "Ann", age: 40})
 
@@ -137,6 +146,7 @@ records.

+
    s := person{name: "Sean", age: 50}
     fmt.Println(s.name)
 
@@ -151,6 +161,7 @@ pointers are automatically dereferenced.

+
    sp := &s
     fmt.Println(sp.age)
 
@@ -164,6 +175,7 @@ pointers are automatically dereferenced.

+
    sp.age = 51
     fmt.Println(sp.age)
 }
@@ -181,6 +193,7 @@ pointers are automatically dereferenced.

+
$ go run structs.go
 {Bob 20}
 {Alice 30}
diff --git a/public/switch b/public/switch
index 66cdc89..f999571 100644
--- a/public/switch
+++ b/public/switch
@@ -30,6 +30,7 @@ branches.

+ @@ -39,6 +40,7 @@ branches.

+
package main
 
@@ -50,6 +52,7 @@ branches.

+
import "fmt"
 import "time"
 
@@ -62,6 +65,7 @@ branches.

+
func main() {
 
@@ -74,6 +78,7 @@ branches.

+
    i := 2
     fmt.Print("write ", i, " as ")
     switch i {
@@ -97,6 +102,7 @@ in the same case statement. We use the optional
 
           
           
+	        
             
    switch time.Now().Weekday() {
     case time.Saturday, time.Sunday:
         fmt.Println("it's the weekend")
@@ -116,6 +122,7 @@ to express if/else logic. Here we also show how the
 
           
           
+	        
             
    t := time.Now()
     switch {
     case t.Hour() < 12:
@@ -138,6 +145,7 @@ to express if/else logic. Here we also show how the
             
           
           
+	        
             
$ go run switch.go 
 write 2 as two
 it's the weekend
diff --git a/public/tickers b/public/tickers
index 78abefb..48fd574 100644
--- a/public/tickers
+++ b/public/tickers
@@ -33,6 +33,7 @@ periodically until we stop it.

+ @@ -42,6 +43,7 @@ periodically until we stop it.

+
package main
 
@@ -53,6 +55,7 @@ periodically until we stop it.

+
import "time"
 import "fmt"
 
@@ -65,6 +68,7 @@ periodically until we stop it.

+
func main() {
 
@@ -80,6 +84,7 @@ the values as they arrive every 500ms.

+
    ticker := time.NewTicker(time.Millisecond * 500)
     go func() {
         for t := range ticker.C {
@@ -99,6 +104,7 @@ channel. We’ll stop ours after 1500ms.

+
    time.Sleep(time.Millisecond * 1500)
     ticker.Stop()
     fmt.Println("Ticker stopped")
@@ -119,6 +125,7 @@ before we stop it.

+
$ go run tickers.go
 Tick at 2012-09-23 11:29:56.487625 -0700 PDT
 Tick at 2012-09-23 11:29:56.988063 -0700 PDT
diff --git a/public/time b/public/time
index 9b6c9f6..76eb47c 100644
--- a/public/time
+++ b/public/time
@@ -30,6 +30,7 @@ here are some examples.

+ @@ -39,6 +40,7 @@ here are some examples.

+
package main
 
@@ -50,6 +52,7 @@ here are some examples.

+
import "fmt"
 import "time"
 
@@ -62,6 +65,7 @@ here are some examples.

+
func main() {
     p := fmt.Println
 
@@ -75,6 +79,7 @@ here are some examples.

+
    now := time.Now()
     p(now)
 
@@ -90,6 +95,7 @@ with a Location, i.e. time zone.

+
    then := time.Date(
         2009, 11, 17, 20, 34, 58, 651387237, time.UTC)
     p(then)
@@ -105,6 +111,7 @@ value as expected.

+
    p(then.Year())
     p(then.Month())
     p(then.Day())
@@ -124,6 +131,7 @@ value as expected.

+
    p(then.Weekday())
 
@@ -138,6 +146,7 @@ as the second, respectively.

+
    p(then.Before(now))
     p(then.After(now))
     p(then.Equal(now))
@@ -153,6 +162,7 @@ the interval between two times.

+
    diff := now.Sub(then)
     p(diff)
 
@@ -167,6 +177,7 @@ various units.

+
    p(diff.Hours())
     p(diff.Minutes())
     p(diff.Seconds())
@@ -184,6 +195,7 @@ duration.

+
    p(then.Add(diff))
     p(then.Add(-diff))
 }
@@ -201,6 +213,7 @@ duration.

+
$ go run time.go
 2012-10-31 15:50:13.793654 +0000 UTC
 2009-11-17 20:34:58.651387237 +0000 UTC
@@ -235,6 +248,7 @@ the Unix epoch.

+ diff --git a/public/time-formatting-parsing b/public/time-formatting-parsing index ae325c5..73cc45b 100644 --- a/public/time-formatting-parsing +++ b/public/time-formatting-parsing @@ -30,6 +30,7 @@ pattern-based layouts.

+ @@ -39,6 +40,7 @@ pattern-based layouts.

+
package main
 
@@ -50,6 +52,7 @@ pattern-based layouts.

+
import "fmt"
 import "time"
 
@@ -62,6 +65,7 @@ pattern-based layouts.

+
func main() {
     p := fmt.Println
 
@@ -76,6 +80,7 @@ according to RFC3339.

+
    t := time.Now()
     p(t.Format("2006-01-02T15:04:05Z07:00"))
 
@@ -94,6 +99,7 @@ formatting.

+
    p(t.Format("3:04PM"))
     p(t.Format("Mon Jan _2 15:04:05 2006"))
     p(t.Format("2006-01-02T15:04:05.999999-07:00"))
@@ -110,6 +116,7 @@ components of the time value.

+
    fmt.Printf("%d-%02d-%02dT%02d:%02d:%02d-00:00\n",
         t.Year(), t.Month(), t.Day(),
         t.Hour(), t.Minute(), t.Second())
@@ -126,6 +133,7 @@ with some of the layouts used above.

+
    withNanos := "2006-01-02T15:04:05.999999999-07:00"
     t1, e := time.Parse(
         withNanos,
@@ -146,6 +154,7 @@ explaining the parsing problem.

+
    ansic := "Mon Jan _2 15:04:05 2006"
     _, e = time.Parse(ansic, "8:41PM")
     p(e)
@@ -161,6 +170,7 @@ use for both formatting and parsing.

+
    p(t.Format(time.Kitchen))
 }
 
@@ -177,6 +187,7 @@ use for both formatting and parsing.

+
$ go run time-formatting-parsing.go 
 2012-11-02T09:35:03-07:00
 9:35AM
diff --git a/public/timeouts b/public/timeouts
index 0a79faa..e8b6567 100644
--- a/public/timeouts
+++ b/public/timeouts
@@ -32,6 +32,7 @@ elegant thanks to channels and select.

+ @@ -41,6 +42,7 @@ elegant thanks to channels and select.

+
package main
 
@@ -52,6 +54,7 @@ elegant thanks to channels and select.

+
import "time"
 import "fmt"
 
@@ -64,6 +67,7 @@ elegant thanks to channels and select.

+
func main() {
 
@@ -78,6 +82,7 @@ after 2s.

+
    c1 := make(chan string, 1)
     go func() {
         time.Sleep(time.Second * 2)
@@ -99,6 +104,7 @@ if the operation takes more than the allowed 1s.

+
    select {
     case res := <-c1:
         fmt.Println(res)
@@ -117,6 +123,7 @@ from c2 will succeed and we’ll print the result.

+
    c2 := make(chan string, 1)
     go func() {
         time.Sleep(time.Second * 2)
@@ -145,6 +152,7 @@ out and the second succeeding.

+
$ go run timeouts.go 
 timeout 1
 result 2
@@ -163,6 +171,7 @@ examples of this next: timers and tickers.

+ diff --git a/public/timers b/public/timers index 2c1452a..77aec09 100644 --- a/public/timers +++ b/public/timers @@ -33,6 +33,7 @@ at tickers.

+ @@ -42,6 +43,7 @@ at tickers.

+
package main
 
@@ -53,6 +55,7 @@ at tickers.

+
import "time"
 import "fmt"
 
@@ -65,6 +68,7 @@ at tickers.

+
func main() {
 
@@ -80,6 +84,7 @@ time. This timer will wait 2 seconds.

+
    timer1 := time.NewTimer(time.Second * 2)
 
@@ -94,6 +99,7 @@ expired.

+
    <-timer1.C
     fmt.Println("Timer 1 expired")
 
@@ -110,6 +116,7 @@ Here’s an example of that.

+
    timer2 := time.NewTimer(time.Second)
     go func() {
         <-timer2.C
@@ -137,6 +144,7 @@ a chance to expire.

+
$ go run timers.go
 Timer 1 expired
 Timer 2 stopped
diff --git a/public/url-parsing b/public/url-parsing
index ed41e56..b514a5e 100644
--- a/public/url-parsing
+++ b/public/url-parsing
@@ -30,6 +30,7 @@ Here’s how to parse URLs in Go.

+ @@ -39,6 +40,7 @@ Here’s how to parse URLs in Go.

+
package main
 
@@ -50,6 +52,7 @@ Here’s how to parse URLs in Go.

+
import "fmt"
 import "net/url"
 import "strings"
@@ -63,6 +66,7 @@ Here’s how to parse URLs in Go.

+
func main() {
 
@@ -77,6 +81,7 @@ query params, and query fragment.

+
    s := "postgres://user:pass@host.com:5432/path?k=v#f"
 
@@ -89,6 +94,7 @@ query params, and query fragment.

+
    u, err := url.Parse(s)
     if err != nil {
         panic(err)
@@ -104,6 +110,7 @@ query params, and query fragment.

+
    fmt.Println(u.Scheme)
 
@@ -118,6 +125,7 @@ values.

+
    fmt.Println(u.User)
     fmt.Println(u.User.Username())
     p, _ := u.User.Password()
@@ -135,6 +143,7 @@ the port.

+
    fmt.Println(u.Host)
     h := strings.Split(u.Host, ":")
     fmt.Println(h[0])
@@ -151,6 +160,7 @@ the #.

+
    fmt.Println(u.Path)
     fmt.Println(u.Fragment)
 
@@ -168,6 +178,7 @@ if you only want the first value.

+
    fmt.Println(u.RawQuery)
     m, _ := url.ParseQuery(u.RawQuery)
     fmt.Println(m)
@@ -189,6 +200,7 @@ pieces that we extracted.

+
$ go run url-parsing.go 
 postgres
 user:pass
diff --git a/public/values b/public/values
index 6f6c644..aeeee0f 100644
--- a/public/values
+++ b/public/values
@@ -31,6 +31,7 @@ basic examples.

+ @@ -40,6 +41,7 @@ basic examples.

+
package main
 
@@ -51,6 +53,7 @@ basic examples.

+
import "fmt"
 
@@ -62,6 +65,7 @@ basic examples.

+
func main() {
 
@@ -74,6 +78,7 @@ basic examples.

+
    fmt.Println("go" + "lang")
 
@@ -86,6 +91,7 @@ basic examples.

+
    fmt.Println("1+1 =", 1+1)
     fmt.Println("7.0/3.0 =", 7.0/3.0)
 
@@ -99,6 +105,7 @@ basic examples.

+
    fmt.Println(true && false)
     fmt.Println(true || false)
     fmt.Println(!true)
@@ -117,6 +124,7 @@ basic examples.

+
$ go run values.go
 golang
 1+1 = 2
diff --git a/public/variables b/public/variables
index 7c079ca..7422d14 100644
--- a/public/variables
+++ b/public/variables
@@ -31,6 +31,7 @@ calls.

+ @@ -40,6 +41,7 @@ calls.

+
package main
 
@@ -51,6 +53,7 @@ calls.

+
import "fmt"
 
@@ -62,6 +65,7 @@ calls.

+
func main() {
 
@@ -74,6 +78,7 @@ calls.

+
    var a string = "initial"
     fmt.Println(a)
 
@@ -87,6 +92,7 @@ calls.

+
    var b, c int = 1, 2
     fmt.Println(b, c)
 
@@ -100,6 +106,7 @@ calls.

+
    var d = true
     fmt.Println(d)
 
@@ -115,6 +122,7 @@ zero value for an int is 0.

+
    var e int
     fmt.Println(e)
 
@@ -130,6 +138,7 @@ initializing a variable, e.g. for +
    f := "short"
     fmt.Println(f)
 }
@@ -147,6 +156,7 @@ initializing a variable, e.g. for
             
           
           
+	        
             
$ go run variables.go
 initial
 1 2
diff --git a/public/variadic-functions b/public/variadic-functions
index c273143..653c773 100644
--- a/public/variadic-functions
+++ b/public/variadic-functions
@@ -32,6 +32,7 @@ function.

+ @@ -41,6 +42,7 @@ function.

+
package main
 
@@ -52,6 +54,7 @@ function.

+
import "fmt"
 
@@ -65,6 +68,7 @@ of ints as arguments.

+
func sum(nums ...int) {
     fmt.Print(nums, " ")
     total := 0
@@ -83,6 +87,7 @@ of ints as arguments.

+
func main() {
 
@@ -96,6 +101,7 @@ with individual arguments.

+
    sum(1, 2)
     sum(1, 2, 3)
 
@@ -111,6 +117,7 @@ apply them to a variadic function using +
    nums := []int{1, 2, 3, 4}
     sum(nums...)
 }
@@ -128,6 +135,7 @@ apply them to a variadic function using
             
           
           
+	        
             
$ go run variadic-functions.go 
 [1 2] 3
 [1 2 3] 6
@@ -144,6 +152,7 @@ to form closures, which we’ll look at next.

+ diff --git a/public/worker-pools b/public/worker-pools index 258a305..1471e84 100644 --- a/public/worker-pools +++ b/public/worker-pools @@ -30,6 +30,7 @@ a worker pool using goroutines and channels.

+ @@ -39,6 +40,7 @@ a worker pool using goroutines and channels.

+
package main
 
@@ -50,6 +52,7 @@ a worker pool using goroutines and channels.

+
import "fmt"
 import "time"
 
@@ -67,6 +70,7 @@ simulate an expensive task.

+
func worker(id int, jobs <-chan int, results chan<- int) {
     for j := range jobs {
         fmt.Println("worker", id, "processing job", j)
@@ -84,6 +88,7 @@ simulate an expensive task.

+
func main() {
 
@@ -98,6 +103,7 @@ channels for this.

+
    jobs := make(chan int, 100)
     results := make(chan int, 100)
 
@@ -112,6 +118,7 @@ because there are no jobs yet.

+
    for w := 1; w <= 3; w++ {
         go worker(w, jobs, results)
     }
@@ -127,6 +134,7 @@ channel to indicate that’s all the work we have.

+
    for j := 1; j <= 9; j++ {
         jobs <- j
     }
@@ -142,6 +150,7 @@ channel to indicate that’s all the work we have.

+
    for a := 1; a <= 9; a++ {
         <-results
     }
@@ -164,6 +173,7 @@ there are 3 workers operating concurrently.

+
$ time go run worker-pools.go 
 worker 1 processing job 1
 worker 2 processing job 2
@@ -184,6 +194,7 @@ there are 3 workers operating concurrently.

+
real	0m3.149s
 
diff --git a/public/writing-files b/public/writing-files index 3753007..dc9f576 100644 --- a/public/writing-files +++ b/public/writing-files @@ -30,6 +30,7 @@ ones we saw earlier for reading.

+ @@ -39,6 +40,7 @@ ones we saw earlier for reading.

+
package main
 
@@ -50,6 +52,7 @@ ones we saw earlier for reading.

+
import (
     "bufio"
     "fmt"
@@ -66,6 +69,7 @@ ones we saw earlier for reading.

+
func check(e error) {
     if e != nil {
         panic(e)
@@ -81,6 +85,7 @@ ones we saw earlier for reading.

+
func main() {
 
@@ -94,6 +99,7 @@ bytes) into a file.

+
    d1 := []byte("hello\ngo\n")
     err := ioutil.WriteFile("/tmp/dat1", d1, 0644)
     check(err)
@@ -108,6 +114,7 @@ bytes) into a file.

+
    f, err := os.Create("/tmp/dat2")
     check(err)
 
@@ -122,6 +129,7 @@ after opening a file.

+
    defer f.Close()
 
@@ -134,6 +142,7 @@ after opening a file.

+
    d2 := []byte{115, 111, 109, 101, 10}
     n2, err := f.Write(d2)
     check(err)
@@ -149,6 +158,7 @@ after opening a file.

+
    n3, err := f.WriteString("writes\n")
     fmt.Printf("wrote %d bytes\n", n3)
 
@@ -162,6 +172,7 @@ after opening a file.

+
    f.Sync()
 
@@ -175,6 +186,7 @@ to the buffered readers we saw earlier.

+
    w := bufio.NewWriter(f)
     n4, err := w.WriteString("buffered\n")
     fmt.Printf("wrote %d bytes\n", n4)
@@ -190,6 +202,7 @@ been applied to the underlying writer.

+
    w.Flush()
 
@@ -201,6 +214,7 @@ been applied to the underlying writer.

+
}
 
@@ -217,6 +231,7 @@ been applied to the underlying writer.

+
$ go run writing-files.go 
 wrote 5 bytes
 wrote 7 bytes
@@ -232,6 +247,7 @@ been applied to the underlying writer.

+
$ cat /tmp/dat1
 hello
 go
@@ -251,6 +267,7 @@ we’ve just seen to the stdin and stdout streams.
 
           
           
+	        
             
           
         
diff --git a/server.go b/server.go
index 4b7164c..fc420c8 100644
--- a/server.go
+++ b/server.go
@@ -142,6 +142,7 @@ func router() *mux.Router {
 	router := mux.NewRouter()
 	router.HandleFunc("/", static).Methods("GET")
 	router.HandleFunc("/favicon.ico", static).Methods("GET")
+	router.HandleFunc("/play.png", static).Methods("GET")
 	router.HandleFunc("/site.css", static).Methods("GET")
 	entries, err := ioutil.ReadDir("public")
 	check(err)
diff --git a/templates/example.tmpl b/templates/example.tmpl
index 3ad84f3..db3dc96 100644
--- a/templates/example.tmpl
+++ b/templates/example.tmpl
@@ -28,6 +28,7 @@
             {{.DocsRendered}}
           
           
+	        {{if .CodeRun}}{{end}}
             {{.CodeRendered}}
           
         
diff --git a/templates/play.png b/templates/play.png
new file mode 100644
index 0000000..ec7028c
Binary files /dev/null and b/templates/play.png differ
diff --git a/templates/site.css b/templates/site.css
index 1e698f4..4808e32 100644
--- a/templates/site.css
+++ b/templates/site.css
@@ -136,6 +136,11 @@ pre, code {
     font-size: 14px; line-height: 18px;
     font-family: 'Menlo', 'Monaco', 'Consolas', 'Lucida Console', monospace;
 }
+img.run {
+  height: 16px;
+  width: 16px;
+  float: right
+}
 
 /* Syntax highlighting */
 body .hll { background-color: #ffffcc }
diff --git a/tools/generate.go b/tools/generate.go
index 3aceaa3..30d7291 100644
--- a/tools/generate.go
+++ b/tools/generate.go
@@ -5,6 +5,7 @@ import (
     "fmt"
     "github.com/russross/blackfriday"
     "io/ioutil"
+    "net/http"
     "os"
     "os/exec"
     "path/filepath"
@@ -117,19 +118,40 @@ var todoPat = regexp.MustCompile("\\/\\/ todo: ")
 var dashPat = regexp.MustCompile("\\-+")
 
 type Seg struct {
-    Docs, DocsRendered     string
-    Code, CodeRendered     string
-    CodeEmpty, CodeLeading bool
+    Docs, DocsRendered              string
+    Code, CodeRendered              string
+    CodeEmpty, CodeLeading, CodeRun bool
 }
 
 type Example struct {
-    Id, Name    string
-    Segs        [][]*Seg
-    NextExample *Example
+    Id, Name                    string
+    GoCode, GoCodeHash, UrlHash string
+    Segs                        [][]*Seg
+    NextExample                 *Example
 }
 
-func parseSegs(sourcePath string) []*Seg {
+func parseHashFile(sourcePath string) (string, string) {
     lines := readLines(sourcePath)
+    return lines[0], lines[1]
+}
+
+func resetUrlHashFile(codehash, code, sourcePath string) string {
+    payload := strings.NewReader(code)
+    resp, err := http.Post("http://play.golang.org/share", "text/plain", payload)
+    if err != nil {
+        panic(err)
+    }
+    defer resp.Body.Close()
+    body, err := ioutil.ReadAll(resp.Body)
+    urlkey := string(body)
+    data := fmt.Sprintf("%s\n%s\n", codehash, urlkey)
+    ioutil.WriteFile(sourcePath, []byte(data), 0644)
+    return urlkey
+}
+
+func parseSegs(sourcePath string) ([]*Seg, string) {
+    lines := readLines(sourcePath)
+    filecontent := strings.Join(lines, "\n")
     segs := []*Seg{}
     lastSeen := ""
     for _, line := range lines {
@@ -171,12 +193,13 @@ func parseSegs(sourcePath string) []*Seg {
     for i, seg := range segs {
         seg.CodeEmpty = (seg.Code == "")
         seg.CodeLeading = (i < (len(segs) - 1))
+        seg.CodeRun = strings.Contains(seg.Code, "package main")
     }
-    return segs
+    return segs, filecontent
 }
 
-func parseAndRenderSegs(sourcePath string) []*Seg {
-    segs := parseSegs(sourcePath)
+func parseAndRenderSegs(sourcePath string) ([]*Seg, string) {
+    segs, filecontent := parseSegs(sourcePath)
     lexer := whichLexer(sourcePath)
     for _, seg := range segs {
         if seg.Docs != "" {
@@ -186,7 +209,11 @@ func parseAndRenderSegs(sourcePath string) []*Seg {
             seg.CodeRendered = cachedPygmentize(lexer, seg.Code)
         }
     }
-    return segs
+    // we are only interested in the 'go' code to pass to play.golang.org
+    if lexer != "go" {
+        filecontent = ""
+    }
+    return segs, filecontent
 }
 
 func parseExamples() []*Example {
@@ -204,8 +231,19 @@ func parseExamples() []*Example {
             example.Segs = make([][]*Seg, 0)
             sourcePaths := mustGlob("examples/" + exampleId + "/*")
             for _, sourcePath := range sourcePaths {
-                sourceSegs := parseAndRenderSegs(sourcePath)
-                example.Segs = append(example.Segs, sourceSegs)
+                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)
         }
@@ -242,6 +280,7 @@ func main() {
     copyFile("templates/site.css", siteDir+"/site.css")
     copyFile("templates/favicon.ico", siteDir+"/favicon.ico")
     copyFile("templates/404.html", siteDir+"/404.html")
+    copyFile("templates/play.png", siteDir+"/play.png")
     examples := parseExamples()
     renderIndex(examples)
     renderExamples(examples)