├── .gitignore ├── LICENSE ├── README.md ├── app ├── css │ ├── book.css │ ├── fonts.css │ ├── layout.css │ ├── main.css │ ├── multi-step.css │ ├── normalize.css │ └── toc.css └── js │ └── main.js ├── build.go ├── build.ninja ├── go.mod ├── go.sum ├── main.go ├── public ├── fonts │ ├── FiraMono-Bold.eot │ ├── FiraMono-Bold.ttf │ ├── FiraMono-Bold.woff │ ├── FiraMono-Regular.eot │ ├── FiraMono-Regular.ttf │ ├── FiraMono-Regular.woff │ ├── FiraSans-Bold.eot │ ├── FiraSans-Bold.ttf │ ├── FiraSans-Bold.woff │ ├── FiraSans-Regular.eot │ ├── FiraSans-Regular.ttf │ └── FiraSans-Regular.woff ├── golang-book.css ├── golang-book.css.map ├── golang-book.js ├── golang-book.js.map ├── health.html ├── img │ ├── favicon.ico │ ├── guides │ │ ├── osx-atom.png │ │ ├── osx-install-atom.png │ │ ├── osx-install-tetris.png │ │ ├── osx-terminal.png │ │ ├── windows-command-prompt.png │ │ └── windows-run.png │ ├── intro │ │ ├── 10000000000001740000006A3733A30E.png │ │ ├── 10000000000001840000005156009DB3.png │ │ ├── 100000000000019000000057111AA314.png │ │ ├── 10000000000001FF000000A90C708B88.png │ │ ├── 100002010000001E0000001EBC3C3681.png │ │ ├── 10000201000004B0000002474EAE2B1A.png │ │ ├── 10000201000004B0000002A351BA6C59.png │ │ ├── 10000201000004B0000002F094337FAB.png │ │ ├── 10000201000004B00000038773C3C446.png │ │ ├── 10000201000004B0000003B4415431D2.png │ │ ├── 10000201000004B000000447FA964939.png │ │ ├── 10000201000004B00000056400FE05B4.png │ │ ├── 100002010000054B000008D40B52A239.png │ │ └── cover.png │ ├── introducing-go │ │ └── cover.jpg │ ├── pattern-1ask.png │ ├── pattern-577q.png │ ├── pattern-5a79.png │ ├── pattern-74mq.png │ ├── pattern-axpr.png │ ├── pattern-c1ry.png │ ├── pattern-e3e6.png │ ├── pattern-il54.png │ ├── python-logo.png │ └── web │ │ ├── hello-name.png │ │ ├── import-tree.png │ │ ├── memory-h.png │ │ ├── memory-hello-world.png │ │ ├── memory-render-text.png │ │ ├── msysgit.png │ │ ├── nitrous-go.png │ │ ├── nitrous-tetris.png │ │ ├── nitrous.png │ │ ├── scopes.png │ │ ├── variable-box.png │ │ ├── windows-atom-go-plus.png │ │ ├── windows-atom-install.png │ │ ├── windows-bash.png │ │ ├── windows-cmd.png │ │ ├── windows-explorer.png │ │ └── windows-tetris.png └── pdf │ └── gobook.pdf ├── scripts └── fileversions │ └── main.go ├── templates.go └── templates ├── books ├── intro │ ├── 1.gohtml │ ├── 10.gohtml │ ├── 11.gohtml │ ├── 12.gohtml │ ├── 13.gohtml │ ├── 14.gohtml │ ├── 2.gohtml │ ├── 3.gohtml │ ├── 4.gohtml │ ├── 5.gohtml │ ├── 6.gohtml │ ├── 7.gohtml │ ├── 8.gohtml │ ├── 9.gohtml │ ├── front.gohtml │ └── layout.gohtml └── web │ ├── 00-01.gohtml │ ├── 01-01.gohtml │ ├── 01-02.gohtml │ ├── 01-03.gohtml │ ├── 01-04.gohtml │ ├── 02-01.gohtml │ ├── 02-02.gohtml │ ├── 02-03.gohtml │ ├── front.gohtml │ ├── layout.gohtml │ └── templates │ └── templates.gohtml ├── guides ├── 01_machine_setup.gohtml ├── 02_bootcamp.gohtml ├── bootcamp │ ├── week-1 │ │ ├── day-1.gohtml │ │ ├── day-2.gohtml │ │ ├── day-3.gohtml │ │ ├── day-4.gohtml │ │ └── day-5.gohtml │ ├── week-2 │ │ ├── day-1.gohtml │ │ ├── day-2.gohtml │ │ ├── day-3.gohtml │ │ ├── day-4.gohtml │ │ └── day-5.gohtml │ ├── week-3 │ │ ├── day-1.gohtml │ │ ├── day-2.gohtml │ │ ├── day-3.gohtml │ │ ├── day-4.gohtml │ │ └── day-5.gohtml │ └── week-4 │ │ ├── day-1.gohtml │ │ └── day-2.gohtml └── layout.gohtml ├── index.gohtml └── layout.gohtml /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Architecture specific extensions/prefixes 11 | *.[568vq] 12 | [568vq].out 13 | 14 | *.cgo1.go 15 | *.cgo2.c 16 | _cgo_defun.c 17 | _cgo_gotypes.go 18 | _cgo_export.* 19 | 20 | _testmain.go 21 | 22 | *.exe 23 | *.test 24 | *.prof 25 | .ninja_deps 26 | .ninja_log 27 | tmp/ 28 | 29 | build 30 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | With regards to the book content (templates/books/**.gohtml, images, etc..): 2 | 3 | Copyright (c) 2015 Caleb Doxsey 4 | All Rights Reserved 5 | 6 | The cover art for "An Introduction to Programming in Go" is: 7 | 8 | Copyright (c) 2012 Abigail Doxsey Anderson 9 | All Rights Reserved 10 | 11 | With regards to the guide content (templates/guides/**.gohtml, images, etc...): 12 | 13 | Copyright (c) 2015 Caleb Doxsey 14 | Licensed under a Creative Commons Attribution 4.0 International License. 15 | 16 | Portions of the text may contain modifications based on work created and shared 17 | by Google and used according to terms described in the Creative Commons 3.0 18 | Attribution License. 19 | 20 | 21 | 22 | With regards to the source code (.go, .css, .js, etc..): 23 | 24 | Copyright (c) 2015 Caleb Doxsey 25 | 26 | Permission is hereby granted, free of charge, to any person obtaining a copy 27 | of this software and associated documentation files (the "Software"), to deal 28 | in the Software without restriction, including without limitation the rights 29 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 30 | copies of the Software, and to permit persons to whom the Software is 31 | furnished to do so, subject to the following conditions: 32 | 33 | The above copyright notice and this permission notice shall be included in all 34 | copies or substantial portions of the Software. 35 | 36 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 37 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 38 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 39 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 40 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 41 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 42 | SOFTWARE. 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # golang-book.com 2 | https://www.golang-book.com 3 | -------------------------------------------------------------------------------- /app/css/book.css: -------------------------------------------------------------------------------- 1 | img.block { 2 | display: block; 3 | margin: 16px auto; 4 | } 5 | .book table { 6 | margin-bottom: 16px; 7 | } 8 | .book td { 9 | border: 1px solid #E3E3E3; 10 | padding: 4px 8px; 11 | background: #FAFAFA; 12 | text-align: center; 13 | } 14 | 15 | 16 | .book .paging { 17 | border-top: 1px solid #ddd; 18 | width: 100%; 19 | margin-top: 16px; 20 | } 21 | .book .paging td { 22 | text-align: center; 23 | padding: 8px 0 0; 24 | border: none; 25 | background: transparent; 26 | } 27 | .book .paging .prev, .book .paging .next { 28 | width: 100px; 29 | } 30 | .book .paging .prev { 31 | text-align: left; 32 | } 33 | .book .paging .next { 34 | text-align: right; 35 | } 36 | 37 | .book .section-link { 38 | margin-left: 4px; 39 | } 40 | -------------------------------------------------------------------------------- /app/css/fonts.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'Fira Mono'; 3 | src: url('/public/fonts/FiraMono-Regular.eot'); 4 | src: url('/public/fonts/FiraMono-Regular.eot') format('embedded-opentype'), 5 | url('/public/fonts/FiraMono-Regular.woff') format('woff'), 6 | url('/public/fonts/FiraMono-Regular.ttf') format('truetype'); 7 | font-weight: 400; 8 | font-style: normal; 9 | } 10 | 11 | @font-face { 12 | font-family: 'Fira Mono'; 13 | src: url('/public/fonts/FiraMono-Bold.eot'); 14 | src: url('/public/fonts/FiraMono-Bold.eot') format('embedded-opentype'), 15 | url('/public/fonts/FiraMono-Bold.woff') format('woff'), 16 | url('/public/fonts/FiraMono-Bold.ttf') format('truetype'); 17 | font-weight: 700; 18 | font-style: normal; 19 | } 20 | 21 | @font-face { 22 | font-family: 'Fira Sans'; 23 | src: url('/public/fonts/FiraSans-Regular.eot'); 24 | src: url('/public/fonts/FiraSans-Regular.eot') format('embedded-opentype'), 25 | url('/public/fonts/FiraSans-Regular.woff') format('woff'), 26 | url('/public/fonts/FiraSans-Regular.ttf') format('truetype'); 27 | font-weight: 400; 28 | font-style: normal; 29 | } 30 | 31 | @font-face { 32 | font-family: 'Fira Sans'; 33 | src: url('/public/fonts/FiraSans-Bold.eot'); 34 | src: url('/public/fonts/FiraSans-Bold.eot') format('embedded-opentype'), 35 | url('/public/fonts/FiraSans-Bold.woff') format('woff'), 36 | url('/public/fonts/FiraSans-Bold.ttf') format('truetype'); 37 | font-weight: 700; 38 | font-style: normal; 39 | } 40 | -------------------------------------------------------------------------------- /app/css/layout.css: -------------------------------------------------------------------------------- 1 | .outer-container { 2 | max-width: 700px; 3 | margin: 0 auto; 4 | background: #FFF; 5 | border: 1px solid #AAA; 6 | border-top: none; 7 | border-bottom: none; 8 | 9 | box-shadow: 0px 0px 20px 0px rgba(0, 0, 0, 0.15); 10 | display: flex; 11 | min-height: 100vh; 12 | flex-direction: column; 13 | } 14 | @media (max-width: 715px) { 15 | .outer-container { 16 | border: none 17 | } 18 | } 19 | .container { 20 | padding: 20px; 21 | } 22 | .body { 23 | flex: 1; 24 | } 25 | .breadcrumbs { 26 | padding: 8px 16px; 27 | border-bottom: 1px solid #DDD; 28 | background: #F3F3F3; 29 | font-size: 13px; 30 | } 31 | .footer { 32 | padding: 4px 16px; 33 | border-top: 1px solid #DDD; 34 | background: #F3F3F3; 35 | font-size: 8px; 36 | } 37 | 38 | .cover-image { 39 | float: left; 40 | margin-right: 16px; 41 | margin-top: 4px; 42 | border: 1px solid #666; 43 | border-radius: 4px; 44 | box-shadow: 0px 0px 6px 0px rgba(0, 0, 0, 0.25); 45 | } 46 | 47 | img.autoscale { 48 | max-width: calc(100% - 32px); 49 | border-radius: 8px; 50 | display: block; 51 | border: 1px solid #333; 52 | box-shadow: 0px 0px 16px 0px rgba(0, 0, 0, 0.25); 53 | margin: 32px auto; 54 | } 55 | -------------------------------------------------------------------------------- /app/css/main.css: -------------------------------------------------------------------------------- 1 | 2 | * { 3 | box-sizing: border-box; 4 | } 5 | html, body { 6 | padding: 0; 7 | margin: 0; 8 | height: 100%; 9 | } 10 | body { 11 | background: #E0EBF5 url("/public/img/pattern-1ask.png") repeat; 12 | font-family: "Fira Sans", serif; 13 | font-size: 15px; 14 | color: #333; 15 | } 16 | a, a:active, a:visited, a:link, a:hover { 17 | color: #375EAB; 18 | text-decoration: none; 19 | } 20 | a:hover { 21 | text-decoration: underline; 22 | } 23 | 24 | h1 { 25 | font-size: 40px; 26 | margin: 0 0 20px; 27 | text-align: center; 28 | } 29 | 30 | p { 31 | line-height: 24px; 32 | } 33 | 34 | pre, code, .code { 35 | font-family: "Fira Mono", monospace; 36 | font-size: 13px; 37 | } 38 | pre, code { 39 | background: #F3F3F3; 40 | border: 1px solid #E3E3E3; 41 | } 42 | pre { 43 | padding: 8px 12px; 44 | border-radius: 8px; 45 | white-space: pre-wrap; 46 | line-height: 18px; 47 | } 48 | code { 49 | border-radius: 3px; 50 | padding: 1px 2px; 51 | white-space: nowrap; 52 | } 53 | 54 | q, blockquote { 55 | color: black; 56 | } 57 | blockquote { 58 | background: #fff8dc; 59 | border: 1px solid #e0dcbf; 60 | padding: 8px 12px; 61 | border-radius: 8px; 62 | margin: 0; 63 | } 64 | blockquote footer { 65 | text-align: right; 66 | font-size: 10px; 67 | } 68 | blockquote pre { 69 | border: none; 70 | background: transparent; 71 | padding: 0; 72 | margin: 0; 73 | } 74 | q { 75 | font-style: italic; 76 | } 77 | q:before { 78 | content: ""; 79 | } 80 | q:after { 81 | content: ""; 82 | } 83 | 84 | .book-list { 85 | padding-bottom: 24px; 86 | } 87 | .book-list dt { 88 | font-size: 20px; 89 | } 90 | dl dt { 91 | font-weight: bold; 92 | } 93 | dl dd { 94 | padding: 8px 0; 95 | margin: 0; 96 | } 97 | 98 | p { 99 | margin: 12px 0; 100 | } 101 | h2 { 102 | font-size: 28px; 103 | } 104 | h3 { 105 | font-size: 18px; 106 | } 107 | h4, h5 { 108 | font-size: 15px; 109 | } 110 | h2, h3, h4, h5 { 111 | color: #000; 112 | margin: 20px 0 12px 0; 113 | } 114 | 115 | 116 | .clearfix:before, 117 | .clearfix:after { 118 | content: ""; 119 | display: table; 120 | } 121 | .clearfix:after { 122 | clear: both; 123 | } 124 | -------------------------------------------------------------------------------- /app/css/multi-step.css: -------------------------------------------------------------------------------- 1 | .multi-step { 2 | border: 1px solid #CCC; 3 | background: #FAFAFA; 4 | padding: 16px; 5 | border-radius: 8px; 6 | margin: 16px 0; 7 | position: relative; 8 | } 9 | 10 | .multi-step h2 { 11 | margin: 0 0 12px; 12 | text-align: center; 13 | } 14 | 15 | .multi-step .step-breadcrumbs { 16 | display: flex; 17 | justify-content: space-around; 18 | flex-wrap: wrap; 19 | background: #F3F3F3; 20 | padding: 8px; 21 | margin: 0 -16px; 22 | font-size: 12px; 23 | border-top: 1px solid #CCC; 24 | border-bottom: 1px solid #CCC; 25 | } 26 | .multi-step .step-breadcrumbs li { 27 | list-style: none; 28 | margin: 0; 29 | white-space: nowrap; 30 | padding: 2px 8px; 31 | line-height: 18px; 32 | border-radius: 4px; 33 | } 34 | .multi-step .step-breadcrumbs .selected { 35 | background: white; 36 | border: 1px solid #CCC; 37 | box-shadow: 0 0 10px 0 rgba(100,100,100,.1); 38 | } 39 | 40 | .multi-step .step-footer { 41 | background: #F3F3F3; 42 | padding: 0 24px; 43 | margin: 0 -16px -16px; 44 | font-size: 12px; 45 | border-top: 1px solid #CCC; 46 | border-bottom-left-radius: 8px; 47 | border-bottom-right-radius: 8px; 48 | height: 36px; 49 | line-height: 36px; 50 | } 51 | .multi-step .step-footer .next { 52 | float: right; 53 | } 54 | .multi-step .step-footer .previous { 55 | float: left; 56 | } 57 | 58 | .multi-step .step-footer, .multi-step .step-breadcrumbs { 59 | box-shadow: 0 0 10px 0 rgba(100,100,100,.1); 60 | } 61 | -------------------------------------------------------------------------------- /app/css/normalize.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */ 2 | 3 | /** 4 | * 1. Set default font family to sans-serif. 5 | * 2. Prevent iOS and IE text size adjust after device orientation change, 6 | * without disabling user zoom. 7 | */ 8 | 9 | html { 10 | font-family: sans-serif; /* 1 */ 11 | -ms-text-size-adjust: 100%; /* 2 */ 12 | -webkit-text-size-adjust: 100%; /* 2 */ 13 | } 14 | 15 | /** 16 | * Remove default margin. 17 | */ 18 | 19 | body { 20 | margin: 0; 21 | } 22 | 23 | /* HTML5 display definitions 24 | ========================================================================== */ 25 | 26 | /** 27 | * Correct `block` display not defined for any HTML5 element in IE 8/9. 28 | * Correct `block` display not defined for `details` or `summary` in IE 10/11 29 | * and Firefox. 30 | * Correct `block` display not defined for `main` in IE 11. 31 | */ 32 | 33 | article, 34 | aside, 35 | details, 36 | figcaption, 37 | figure, 38 | footer, 39 | header, 40 | hgroup, 41 | main, 42 | menu, 43 | nav, 44 | section, 45 | summary { 46 | display: block; 47 | } 48 | 49 | /** 50 | * 1. Correct `inline-block` display not defined in IE 8/9. 51 | * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. 52 | */ 53 | 54 | audio, 55 | canvas, 56 | progress, 57 | video { 58 | display: inline-block; /* 1 */ 59 | vertical-align: baseline; /* 2 */ 60 | } 61 | 62 | /** 63 | * Prevent modern browsers from displaying `audio` without controls. 64 | * Remove excess height in iOS 5 devices. 65 | */ 66 | 67 | audio:not([controls]) { 68 | display: none; 69 | height: 0; 70 | } 71 | 72 | /** 73 | * Address `[hidden]` styling not present in IE 8/9/10. 74 | * Hide the `template` element in IE 8/9/10/11, Safari, and Firefox < 22. 75 | */ 76 | 77 | [hidden], 78 | template { 79 | display: none; 80 | } 81 | 82 | /* Links 83 | ========================================================================== */ 84 | 85 | /** 86 | * Remove the gray background color from active links in IE 10. 87 | */ 88 | 89 | a { 90 | background-color: transparent; 91 | } 92 | 93 | /** 94 | * Improve readability of focused elements when they are also in an 95 | * active/hover state. 96 | */ 97 | 98 | a:active, 99 | a:hover { 100 | outline: 0; 101 | } 102 | 103 | /* Text-level semantics 104 | ========================================================================== */ 105 | 106 | /** 107 | * Address styling not present in IE 8/9/10/11, Safari, and Chrome. 108 | */ 109 | 110 | abbr[title] { 111 | border-bottom: 1px dotted; 112 | } 113 | 114 | /** 115 | * Address style set to `bolder` in Firefox 4+, Safari, and Chrome. 116 | */ 117 | 118 | b, 119 | strong { 120 | font-weight: bold; 121 | } 122 | 123 | /** 124 | * Address styling not present in Safari and Chrome. 125 | */ 126 | 127 | dfn { 128 | font-style: italic; 129 | } 130 | 131 | /** 132 | * Address variable `h1` font-size and margin within `section` and `article` 133 | * contexts in Firefox 4+, Safari, and Chrome. 134 | */ 135 | 136 | h1 { 137 | font-size: 2em; 138 | margin: 0.67em 0; 139 | } 140 | 141 | /** 142 | * Address styling not present in IE 8/9. 143 | */ 144 | 145 | mark { 146 | background: #ff0; 147 | color: #000; 148 | } 149 | 150 | /** 151 | * Address inconsistent and variable font size in all browsers. 152 | */ 153 | 154 | small { 155 | font-size: 80%; 156 | } 157 | 158 | /** 159 | * Prevent `sub` and `sup` affecting `line-height` in all browsers. 160 | */ 161 | 162 | sub, 163 | sup { 164 | font-size: 75%; 165 | line-height: 0; 166 | position: relative; 167 | vertical-align: baseline; 168 | } 169 | 170 | sup { 171 | top: -0.5em; 172 | } 173 | 174 | sub { 175 | bottom: -0.25em; 176 | } 177 | 178 | /* Embedded content 179 | ========================================================================== */ 180 | 181 | /** 182 | * Remove border when inside `a` element in IE 8/9/10. 183 | */ 184 | 185 | img { 186 | border: 0; 187 | } 188 | 189 | /** 190 | * Correct overflow not hidden in IE 9/10/11. 191 | */ 192 | 193 | svg:not(:root) { 194 | overflow: hidden; 195 | } 196 | 197 | /* Grouping content 198 | ========================================================================== */ 199 | 200 | /** 201 | * Address margin not present in IE 8/9 and Safari. 202 | */ 203 | 204 | figure { 205 | margin: 1em 40px; 206 | } 207 | 208 | /** 209 | * Address differences between Firefox and other browsers. 210 | */ 211 | 212 | hr { 213 | box-sizing: content-box; 214 | height: 0; 215 | } 216 | 217 | /** 218 | * Contain overflow in all browsers. 219 | */ 220 | 221 | pre { 222 | overflow: auto; 223 | } 224 | 225 | /** 226 | * Address odd `em`-unit font size rendering in all browsers. 227 | */ 228 | 229 | code, 230 | kbd, 231 | pre, 232 | samp { 233 | font-family: monospace, monospace; 234 | font-size: 1em; 235 | } 236 | 237 | /* Forms 238 | ========================================================================== */ 239 | 240 | /** 241 | * Known limitation: by default, Chrome and Safari on OS X allow very limited 242 | * styling of `select`, unless a `border` property is set. 243 | */ 244 | 245 | /** 246 | * 1. Correct color not being inherited. 247 | * Known issue: affects color of disabled elements. 248 | * 2. Correct font properties not being inherited. 249 | * 3. Address margins set differently in Firefox 4+, Safari, and Chrome. 250 | */ 251 | 252 | button, 253 | input, 254 | optgroup, 255 | select, 256 | textarea { 257 | color: inherit; /* 1 */ 258 | font: inherit; /* 2 */ 259 | margin: 0; /* 3 */ 260 | } 261 | 262 | /** 263 | * Address `overflow` set to `hidden` in IE 8/9/10/11. 264 | */ 265 | 266 | button { 267 | overflow: visible; 268 | } 269 | 270 | /** 271 | * Address inconsistent `text-transform` inheritance for `button` and `select`. 272 | * All other form control elements do not inherit `text-transform` values. 273 | * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. 274 | * Correct `select` style inheritance in Firefox. 275 | */ 276 | 277 | button, 278 | select { 279 | text-transform: none; 280 | } 281 | 282 | /** 283 | * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` 284 | * and `video` controls. 285 | * 2. Correct inability to style clickable `input` types in iOS. 286 | * 3. Improve usability and consistency of cursor style between image-type 287 | * `input` and others. 288 | */ 289 | 290 | button, 291 | html input[type="button"], /* 1 */ 292 | input[type="reset"], 293 | input[type="submit"] { 294 | -webkit-appearance: button; /* 2 */ 295 | cursor: pointer; /* 3 */ 296 | } 297 | 298 | /** 299 | * Re-set default cursor for disabled elements. 300 | */ 301 | 302 | button[disabled], 303 | html input[disabled] { 304 | cursor: default; 305 | } 306 | 307 | /** 308 | * Remove inner padding and border in Firefox 4+. 309 | */ 310 | 311 | button::-moz-focus-inner, 312 | input::-moz-focus-inner { 313 | border: 0; 314 | padding: 0; 315 | } 316 | 317 | /** 318 | * Address Firefox 4+ setting `line-height` on `input` using `!important` in 319 | * the UA stylesheet. 320 | */ 321 | 322 | input { 323 | line-height: normal; 324 | } 325 | 326 | /** 327 | * It's recommended that you don't attempt to style these elements. 328 | * Firefox's implementation doesn't respect box-sizing, padding, or width. 329 | * 330 | * 1. Address box sizing set to `content-box` in IE 8/9/10. 331 | * 2. Remove excess padding in IE 8/9/10. 332 | */ 333 | 334 | input[type="checkbox"], 335 | input[type="radio"] { 336 | box-sizing: border-box; /* 1 */ 337 | padding: 0; /* 2 */ 338 | } 339 | 340 | /** 341 | * Fix the cursor style for Chrome's increment/decrement buttons. For certain 342 | * `font-size` values of the `input`, it causes the cursor style of the 343 | * decrement button to change from `default` to `text`. 344 | */ 345 | 346 | input[type="number"]::-webkit-inner-spin-button, 347 | input[type="number"]::-webkit-outer-spin-button { 348 | height: auto; 349 | } 350 | 351 | /** 352 | * 1. Address `appearance` set to `searchfield` in Safari and Chrome. 353 | * 2. Address `box-sizing` set to `border-box` in Safari and Chrome. 354 | */ 355 | 356 | input[type="search"] { 357 | -webkit-appearance: textfield; /* 1 */ 358 | box-sizing: content-box; /* 2 */ 359 | } 360 | 361 | /** 362 | * Remove inner padding and search cancel button in Safari and Chrome on OS X. 363 | * Safari (but not Chrome) clips the cancel button when the search input has 364 | * padding (and `textfield` appearance). 365 | */ 366 | 367 | input[type="search"]::-webkit-search-cancel-button, 368 | input[type="search"]::-webkit-search-decoration { 369 | -webkit-appearance: none; 370 | } 371 | 372 | /** 373 | * Define consistent border, margin, and padding. 374 | */ 375 | 376 | fieldset { 377 | border: 1px solid #c0c0c0; 378 | margin: 0 2px; 379 | padding: 0.35em 0.625em 0.75em; 380 | } 381 | 382 | /** 383 | * 1. Correct `color` not being inherited in IE 8/9/10/11. 384 | * 2. Remove padding so people aren't caught out if they zero out fieldsets. 385 | */ 386 | 387 | legend { 388 | border: 0; /* 1 */ 389 | padding: 0; /* 2 */ 390 | } 391 | 392 | /** 393 | * Remove default vertical scrollbar in IE 8/9/10/11. 394 | */ 395 | 396 | textarea { 397 | overflow: auto; 398 | } 399 | 400 | /** 401 | * Don't inherit the `font-weight` (applied by a rule above). 402 | * NOTE: the default cannot safely be changed in Chrome and Safari on OS X. 403 | */ 404 | 405 | optgroup { 406 | font-weight: bold; 407 | } 408 | 409 | /* Tables 410 | ========================================================================== */ 411 | 412 | /** 413 | * Remove most spacing between table cells. 414 | */ 415 | 416 | table { 417 | border-collapse: collapse; 418 | border-spacing: 0; 419 | } 420 | 421 | td, 422 | th { 423 | padding: 0; 424 | } 425 | -------------------------------------------------------------------------------- /app/css/toc.css: -------------------------------------------------------------------------------- 1 | .toc, .toc ol, .toc ul { 2 | margin: 0; 3 | padding: 0; 4 | list-style-position: inside; 5 | } 6 | .toc li { 7 | padding: 6px 0; 8 | margin: 0; 9 | font-weight: bold; 10 | } 11 | .toc li li { 12 | padding: 2px 18px; 13 | font-weight: normal; 14 | } 15 | .toc li li:first-child { 16 | padding-top: 6px; 17 | } 18 | .toc li li:last-child { 19 | padding-bottom: 0; 20 | } 21 | .toc ol { 22 | list-style-type: square; 23 | } 24 | -------------------------------------------------------------------------------- /app/js/main.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | var els = []; 3 | els.push.apply(els, document.getElementsByTagName("h2")); 4 | els.push.apply(els, document.getElementsByTagName("h3")); 5 | els.push.apply(els, document.getElementsByTagName("h4")); 6 | els.push.apply(els, document.getElementsByTagName("h5")); 7 | for (var i=0; i 1) { 57 | var a = document.createElement("a"); 58 | a.className = "previous"; 59 | a.setAttribute("href", "#" + h3s[j-2].id); 60 | a.innerHTML = "← Previous"; 61 | footer.appendChild(a); 62 | } 63 | 64 | if (j > 0 && j < h3s.length) { 65 | // add a next link before the heading 66 | var a = document.createElement("a"); 67 | a.className = "next"; 68 | a.setAttribute("href", "#" + h3s[j].id); 69 | a.innerHTML = "Next →"; 70 | footer.appendChild(a); 71 | } 72 | 73 | if (j < h3s.length) { 74 | h3s[j].parentNode.insertBefore(footer, h3s[j]); 75 | } else { 76 | ms.appendChild(footer); 77 | } 78 | } 79 | } 80 | 81 | function updateMultiStep() { 82 | for (var i=0; i1){(c=document.createElement("a")).className="previous",c.setAttribute("href","#"+l[o-2].id),c.innerHTML="← Previous",m.appendChild(c)}if(o>0&&o 2 |

Getting Started

Computer programming is the art, craft and science of writing programs which define how computers operate. This book will teach you how to write computer programs using a programming language designed by Google named Go.

3 |

Go is a general purpose programming language with advanced features and a clean syntax. Because of its wide availability on a variety of platforms, its robust well-documented common library, and its focus on good software engineering principles, Go is an ideal language to learn as your first programming language.

4 |

The process we use to write software using Go (and most programming languages) is fairly straightforward:

5 |
  • Gather requirements

    6 |
  • Find a solution

    7 |
  • Write source code to implement the solution

    8 |
  • Compile the source code into an executable

    9 |
  • Run and test the program to make sure it works

    10 |

This process is iterative (meaning its done many times) and the steps usually overlap. But before we write our first program in Go there are a few prerequisite concepts we need to understand.

11 |

Files and Folders

A file is a collection of data stored as a unit with a name. Modern operating systems (like Windows or Mac OSX) contain millions of files which store a large variety of different types of information – everything from text documents to executable programs to multimedia files.

12 |

All files are stored in the same way on a computer: they all have a name, a definite size (measured in bytes) and an associated type. Typically the file's type is signified by the file's extension – the part of the file name that comes after the last .. For example a file with the name hello.txt has the extension txt which is used to represent textual data.

13 |

Folders (also called directories) are used to group files together. They can also contain other folders. On Windows file and folder paths (locations) are represented with the \ (backslash) character, for example: C:\Users\john\example.txt. example.txt is the file name, it is contained in the folder john, which is itself contained in the folder Users which is stored on drive C (which represents the primary physical hard drive in Windows). On OSX (and most other operating systems) file and folder paths are represented with the / (forward slash) character, for example: /Users/john/example.txt. Like on Windows example.txt is the file name, it is contained in the folder john, which is in the folder Users. Unlike Windows, OSX does not specify a drive letter where the file is stored.

14 | 15 | 16 |

Windows

17 | 18 |

On Windows files and folders can be browsed using Windows Explorer (accessible by double-clicking “My Computer” or typing win+e):

19 |

20 | 21 | 22 |

OSX

23 | 24 |

On OSX files and folders can be browsed using Finder (accessible by clicking the Finder icon – the face icon in the lower left bar):

25 |

26 |

The Terminal

Most of the interactions we have with computers today are through sophisticated graphical user interfaces (GUIs). We use keyboards, mice and touchscreens to interact with visual buttons or other types of controls that are displayed on a screen.

27 |

It wasn't always this way. Before the GUI we had the terminal – a simpler textual interface to the computer where rather than manipulating buttons on a screen we issued commands and received replies. We had a conversation with the computer.

28 |

And although it might appear that most of the computing world has left behind the terminal as a relic of the past, the truth is that the terminal is still the fundamental user interface used by most programming languages on most computers. The Go programming language is no different, and so before we write a program in Go we need to have a rudimentary understanding of how a terminal works.

29 |

Windows

30 | 31 |

In Windows the terminal (also known as the command line) can be brought up by typing the windows key + r (hold down the windows key then press r), typing cmd.exe and hitting enter. You should see a black window appear that looks like this:

32 |


By default the command line starts in your home directory. (In my case this is C:\Users\caleb) You issue commands by typing them in and hitting enter. Try entering the command dir, which lists the contents of a directory. You should see something like this:

33 |
C:\Users\caleb>dir
34 | Volume in drive C has no label.
35 | Volume Serial Number is B2F5-F125

Followed by a list of the files and folders contained in your home directory. You can change directories by using the command cd. For example you probably have a folder called Desktop. You can see its contents by entering cd Desktop and then entering dir. To go back to your home directory you can use the special directory name .. (two periods next to each other): cd ... A single period represents the current folder (known as the working folder), so cd . doesn't do anything. There are a lot more commands you can use, but this should be enough to get you started.

36 |

OSX

37 | 38 |

In OSX the terminal can be reached by going to Finder → Applications → Utilities → Terminal. You should see a window like this:

39 |


By default the terminal starts in your home directory. (In my case this is /Users/caleb) You issue commands by typing them in and hitting enter. Try entering the command ls, which lists the contents of a directory. You should see something like this:

40 |
caleb-min:~ caleb$ ls
41 | Desktop      Downloads      Movies     Pictures
42 | Documents    Library        Music      Public

These are the files and folders contained in your home directory (in this case there are no files). You can change directories using the cd command. For example you probably have a folder called Desktop. You can see its contents by entering cd Desktop and then entering ls. To go back to your home directory you can use the special directory name .. (two periods next to each other): cd ... A single period represents the current folder (known as the working folder), so cd . doesn't do anything. There are a lot more commands you can use, but this should be enough to get you started.

43 |

Text Editors

The primary tool programmers use to write software is a text editor. Text editors are similar to word processing programs (Microsoft Word, Open Office, …) but unlike such programs they don't do any formatting, (No bold, italic, …) instead they operate only on plain text. Both OSX and Windows come with text editors but they are highly limited and I recommend installing a better one.

44 |

To make the installation of this software easier an installer is available at the book's website: http://www.golang-book.com/. This installer will install the Go tool suite, setup environmental variables and install a text editor.

45 |

Windows

46 | 47 |

For windows the installer will install the Scite text editor. You can open it by going to Start → All Programs → Go → Scite. You should see something like this:

48 |


The text editor contains a large white text area where text can be entered. To the left of this text area you can see the line numbers. At the bottom of the window is a status bar which displays information about the file and your current location in it (right now it says that we are on line 1, column 1, text is being inserted normally, and we are using windows-style newlines).

49 |

You can open files by going to File → Open and browsing to your desired file. Files can be saved by going to File → Save or File → Save As.

50 |

As you work in a text editor it is useful to learn keyboard shortcuts. The menus list the shortcuts to their right. Here are a few of the most common:

51 |
  • Ctrl + S – save the current file

    52 |
  • Ctrl + X – cut the currently selected text (remove it and put it in your clipboard so it can be pasted later)

    53 |
  • Ctrl + C – copy the currently selected text

    54 |
  • Ctrl + V – paste the text currently in the clipboard

    55 |
  • Use the arrow keys to navigate, Home to go to the beginning of the line and End to go to the end of the line

    56 |
  • Hold down shift while using the arrow keys (or Home and End) to select text without using the mouse

    57 |
  • Ctrl + F – brings up a find in file dialog that you can use to search the contents of a file

    58 |
59 |

OSX

60 | 61 |

For OSX the installer installs the Text Wrangler text editor:

62 |

63 |

Like Scite on Windows Text Wrangler contains a large white area where text is entered. Files can be opened by going to File → Open. Files can be saved by going to File → Save or File → Save As. Here are some useful keyboard shortcuts: (Command is the ⌘ key)

64 |
  • Command + S – save the current file

    65 |
  • Command + X – cut the currently selected text (remove it and put it in your clipboard so it can be pasted later)

    66 |
  • Command + C – copy the currently selected text

    67 |
  • Command + V – paste the text currently in the clipboard

    68 |
  • Use the arrow keys to navigate

    69 |
  • Command + F – brings up a find in file dialog that you can use to search the contents of a file

    70 |

Go Tools

Go is a compiled programming language, which means source code (the code you write) is translated into a language that your computer can understand. Therefore before we can write a Go program, we need the Go compiler.

71 |

The installer will setup Go for you automatically. We will be using version 1 of the language. (More information can be found at http://www.golang.org)

72 |

Let's make sure everything is working. Open up a terminal and type the following:

73 |
go version

You should see the following:

74 |
go version go1.0.2

Your version number may be slightly different. If you get an error about the command not being recognized try restarting your computer.

75 |

The Go tool suite is made up of several different commands and sub-commands. A list of those commands is available by typing:

76 |
go help

We will see how they are used in subsequent chapters.

77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 |
IndexNext →
86 | 87 | 88 | -------------------------------------------------------------------------------- /templates/books/intro/10.gohtml: -------------------------------------------------------------------------------- 1 |
2 | 3 |

Concurrency

4 |

Large programs are often made up of many smaller sub-programs. For example a web server handles requests made from web browsers and serves up HTML web pages in response. Each request is handled like a small program.

5 |

It would be ideal for programs like these to be able to run their smaller components at the same time (in the case of the web server to handle multiple requests). Making progress on more than one task simultaneously is known as concurrency. Go has rich support for concurrency using goroutines and channels.

6 | 7 |

Goroutines

8 |

A goroutine is a function that is capable of running concurrently with other functions. To create a goroutine we use the keyword go followed by a function invocation:

9 |
package main
 10 | 
 11 | import "fmt"
 12 | 
 13 | func f(n int) {
 14 |   for i := 0; i < 10; i++ {
 15 |     fmt.Println(n, ":", i)
 16 |   }
 17 | }
 18 | 
 19 | func main() {
 20 |   go f(0)
 21 |   var input string
 22 |   fmt.Scanln(&input)
 23 | }
24 | 25 |

This program consists of two goroutines. The first goroutine is implicit and is the main function itself. The second goroutine is created when we call go f(0). Normally when we invoke a function our program will execute all the statements in a function and then return to the next line following the invocation. With a goroutine we return immediately to the next line and don't wait for the function to complete. This is why the call to the Scanln function has been included; without it the program would exit before being given the opportunity to print all the numbers.

26 | 27 |

Goroutines are lightweight and we can easily create thousands of them. We can modify our program to run 10 goroutines by doing this:

28 | 29 |
func main() {
 30 |   for i := 0; i < 10; i++ {
 31 |     go f(i)
 32 |   }
 33 |   var input string
 34 |   fmt.Scanln(&input)
 35 | }
36 | 37 |

You may have noticed that when you run this program it seems to run the goroutines in order rather than simultaneously. Let's add some delay to the function using time.Sleep and rand.Intn:

38 |
package main
 39 | 
 40 | import (
 41 |   "fmt"
 42 |   "time"
 43 |   "math/rand"
 44 | )
 45 | 
 46 | func f(n int) {
 47 |   for i := 0; i < 10; i++ {
 48 |     fmt.Println(n, ":", i)
 49 |     amt := time.Duration(rand.Intn(250))
 50 |     time.Sleep(time.Millisecond * amt)
 51 |   }
 52 | }
 53 | 
 54 | func main() {
 55 |   for i := 0; i < 10; i++ {
 56 |     go f(i)
 57 |   }
 58 |   var input string
 59 |   fmt.Scanln(&input)
 60 | }
61 | 62 |

f prints out the numbers from 0 to 10, waiting between 0 and 250 ms after each one. The goroutines should now run simultaneously.

63 | 64 |

Channels

65 |

Channels provide a way for two goroutines to communicate with one another and synchronize their execution. Here is an example program using channels:

66 |
package main
 67 | 
 68 | import (
 69 |   "fmt"
 70 |   "time"
 71 | )
 72 | 
 73 | func pinger(c chan string) {
 74 |   for i := 0; ; i++ {
 75 |     c <- "ping"
 76 |   }
 77 | }
 78 | 
 79 | func printer(c chan string) {
 80 |   for {
 81 |     msg := <- c
 82 |     fmt.Println(msg)
 83 |     time.Sleep(time.Second * 1)
 84 |   }
 85 | }
 86 | 
 87 | func main() {
 88 |   var c chan string = make(chan string)
 89 | 
 90 |   go pinger(c)
 91 |   go printer(c)
 92 | 
 93 |   var input string
 94 |   fmt.Scanln(&input)
 95 | }
96 | 97 |

This program will print “ping” forever (hit enter to stop it). A channel type 98 | is represented with the keyword chan followed by the type of the 99 | things that are passed on the channel (in this case we are passing strings). 100 | The <- (left arrow) operator is used to send and receive 101 | messages on the channel. c <- "ping" means send "ping". msg := <- c means receive a message and store it in msg. The fmt line could also have been written like this: fmt.Println(<-c) in which case we could remove the previous line.

102 |

Using a channel like this synchronizes the two goroutines. When pinger attempts to send a message on the channel it will wait until printer is ready to receive the message. (this is known as blocking) Let's add another sender to the program and see what happens. Add this function:

103 | 104 |
func ponger(c chan string) {
105 |   for i := 0; ; i++ {
106 |     c <- "pong"
107 |   }
108 | }
109 | 110 |

And modify main:

111 |
func main() {
112 |   var c chan string = make(chan string)
113 | 
114 |   go pinger(c)
115 |   go ponger(c)
116 |   go printer(c)
117 | 
118 |   var input string
119 |   fmt.Scanln(&input)
120 | }
121 | 122 |

The program will now take turns printing “ping” and “pong”.

123 | 124 |

Channel Direction

125 | 126 |

We can specify a direction on a channel type thus restricting it to either sending or receiving. For example pinger's function signature can be changed to this:

127 |
func pinger(c chan<- string)

Now c can only be sent to. Attempting to receive from c will result in a compiler error. Similarly we can change printer to this:

128 |
func printer(c <-chan string)

A channel that doesn't have these restrictions is known as bi-directional. A bi-directional channel can be passed to a function that takes send-only or receive-only channels, but the reverse is not true.

129 |

Select

130 | 131 |

Go has a special statement called select which works like a switch but for channels:

132 |
func main() {
133 |   c1 := make(chan string)
134 |   c2 := make(chan string)
135 | 
136 |   go func() {
137 |     for {
138 |       c1 <- "from 1"
139 |       time.Sleep(time.Second * 2)
140 |     }
141 |   }()
142 | 
143 |   go func() {
144 |     for {
145 |       c2 <- "from 2"
146 |       time.Sleep(time.Second * 3)
147 |     }
148 |   }()
149 | 
150 |   go func() {
151 |     for {
152 |       select {
153 |       case msg1 := <- c1:
154 |         fmt.Println(msg1)
155 |       case msg2 := <- c2:
156 |         fmt.Println(msg2)
157 |       }
158 |     }
159 |   }()
160 | 
161 |   var input string
162 |   fmt.Scanln(&input)
163 | }

This program prints “from 1” every 2 seconds and “from 2” every 3 seconds. select picks the first channel that is ready and receives from it (or sends to it). If more than one of the channels are ready then it randomly picks which one to receive from. If none of the channels are ready, the statement blocks until one becomes available.

164 |

The select statement is often used to implement a timeout:

165 |
select {
166 | case msg1 := <- c1:
167 |   fmt.Println("Message 1", msg1)
168 | case msg2 := <- c2:
169 |   fmt.Println("Message 2", msg2)
170 | case <- time.After(time.Second):
171 |   fmt.Println("timeout")
172 | }

time.After creates a channel and after the given duration will send the current time on it. (we weren't interested in the time so we didn't store it in a variable) We can also specify a default case:

173 |
select {
174 | case msg1 := <- c1:
175 |   fmt.Println("Message 1", msg1)
176 | case msg2 := <- c2:
177 |   fmt.Println("Message 2", msg2)
178 | case <- time.After(time.Second):
179 |   fmt.Println("timeout")
180 | default:
181 |   fmt.Println("nothing ready")
182 | }

The default case happens immediately if none of the channels are ready.

183 |

Buffered Channels

184 | 185 |

It's also possible to pass a second parameter to the make function when creating a channel:

186 |
c := make(chan int, 1)

This creates a buffered channel with a capacity of 1. Normally channels are synchronous; both sides of the channel will wait until the other side is ready. A buffered channel is asynchronous; sending or receiving a message will not wait unless the channel is already full.

187 | 188 | 189 |

Problems

190 | 191 |
  • How do you specify the direction of a channel type?

    192 |
  • Write your own Sleep function using time.After.

    193 |
  • What is a buffered channel? How would you create one with a capacity of 20?

    194 |
195 | 196 | 197 | 198 | 199 | 200 | 201 |
← PreviousIndexNext →
202 | 203 |
204 | -------------------------------------------------------------------------------- /templates/books/intro/11.gohtml: -------------------------------------------------------------------------------- 1 |
2 | 3 |

Packages

4 | 5 |

Go was designed to be a language that encourages good software engineering practices. An important part of high quality software is code reuse – embodied in the principle “Don't Repeat Yourself.”

6 | 7 |

As we saw in chapter 7 functions are the first layer we turn to allow code reuse. Go also provides another mechanism for code reuse: packages. Nearly every program we've seen so far included this line:

8 | 9 |
import "fmt"
10 | 11 |

fmt is the name of a package that includes a variety of functions related to formatting and output to the screen. Bundling code in this way serves 3 purposes:

12 | 13 |
    14 |
  • It reduces the chance of having overlapping names. This keeps our function names short and succinct

  • 15 |
  • It organizes code so that its easier to find code you want to reuse.

  • 16 |
  • It speeds up the compiler by only requiring recompilation of smaller chunks of a program. Although we use the package fmt, we don't have to recompile it every time we change our program.

  • 17 |
18 | 19 |

Creating Packages

20 |

Packages only really make sense in the context of a separate program which uses them. Without this separate program we have no way of using the package we create. Let's create an application that will use a package we will write. Create a folder in ~/src/golang-book called chapter11. Inside that folder create a file called main.go which contains this:

21 |
package main
22 | 
23 | import "fmt"
24 | import "golang-book/chapter11/math"
25 | 
26 | func main() {
27 |   xs := []float64{1,2,3,4}
28 |   avg := math.Average(xs)
29 |   fmt.Println(avg)
30 | }
31 | 32 |

Now create another folder inside of the chapter11 folder called math. Inside of this folder create a file called math.go that contains this:

33 |
package math
34 | 
35 | func Average(xs []float64) float64 {
36 |   total := float64(0)
37 |   for _, x := range xs {
38 |     total += x
39 |   }
40 |   return total / float64(len(xs))
41 | }
42 | 43 |

Using a terminal in the math folder you just created run go install. This will compile the math.go program and create a linkable object file: ~/pkg/os_arch/golang-book/chapter11/math.a. (where os is something like windows and arch is something like amd64)

44 |

Now go back to the chapter11 folder and run go run main.go. You should see 2.5. Some things to note:

45 |
    46 |
  • math is the name of a package that is part of Go's standard distribution, but since Go packages can be hierarchical we are safe to use the same name for our package. (The real math package is just math, ours is golang-book/chapter11/math)

  • 47 |
  • When we import our math library we use its full name (import "golang-book/chapter11/math"), but inside of the math.go file we only use the last part of the name (package math).

  • 48 |
  • We also only use the short name math when we reference functions from our library. If we wanted to use both libraries in the same program Go allows us to use an alias:

    49 |
    import m "golang-book/chapter11/math"
    50 | 
    51 | func main() {
    52 |   xs := []float64{1,2,3,4}
    53 |   avg := m.Average(xs)
    54 |   fmt.Println(avg)
    55 | }
    56 |

    m is the alias.

    57 |
  • 58 |
  • You may have noticed that every function in the packages we've seen start with a capital letter. In Go if something starts with a capital letter that means other packages (and programs) are able to see it. If we had named the function average instead of Average our main program would not have been able to see it.

    59 |

    It's a good practice to only expose the parts of our package that we want other packages using and hide everything else. This allows us to freely change those parts later without having to worry about breaking other programs, and it makes our package easier to use.

    60 |
  • 61 |
  • 62 |

    Package names match the folders they fall in. There are ways around this, but it's a lot easier if you stay within this pattern.

    63 |
  • 64 |
65 | 66 |

Documentation

67 |

Go has the ability to automatically generate documentation for packages we write in a similar way to the standard package documentation. In a terminal run this command:

68 |
godoc golang-book/chapter11/math Average
69 | 70 |

You should see information displayed for the function we just wrote. We can improve this documentation by adding a comment before the function:

71 |
// Finds the average of a series of numbers
72 | func Average(xs []float64) float64 {
73 | 74 |

If you run go install in the math folder, then re-run the godoc command you should see our comment below the function definition. This documentation is also available in web form by running this command:

75 |
godoc -http=":6060"

and entering this URL into your browser:

76 |
http://localhost:6060/pkg/

You should be able to browse through all of the packages installed on your system.

77 | 78 | 79 |

Problems

80 | 81 |
    82 |
  • Why do we use packages?

  • 83 |
  • What is the difference between an identifier that starts with a capital letter and one which doesn’t? (Average vs average)

  • 84 |
  • What is a package alias? How do you make one?

  • 85 |
  • We copied the average function from chapter 7 to our new package. Create Min and Max functions which find the minimum and maximum values in a slice of float64s.

  • 86 |
  • How would you document the functions you created in #3?

  • 87 |
88 | 89 | 90 | 91 | 92 | 93 |
← PreviousIndexNext →
94 | 95 | 96 |
97 | -------------------------------------------------------------------------------- /templates/books/intro/12.gohtml: -------------------------------------------------------------------------------- 1 |
2 | 3 |

Testing

4 | 5 |

Programming is not easy; even the best programmers are incapable of writing programs that work exactly as intended every time. Therefore an important part of the software development process is testing. Writing tests for our code is a good way to ensure quality and improve reliability.

6 | 7 |

Go includes a special program that makes writing tests easier, so let's create some tests for the package we made in the last chapter. In the math folder from chapter11 create a new file called math_test.go that contains this:

8 | 9 |
package math
10 | 
11 | import "testing"
12 | 
13 | func TestAverage(t *testing.T) {
14 |   var v float64
15 |   v = Average([]float64{1,2})
16 |   if v != 1.5 {
17 |     t.Error("Expected 1.5, got ", v)
18 |   }
19 | }
20 | 21 |

Now run this command:

22 |
go test
23 | 24 |

You should see this:

25 |
$ go test
26 | PASS
27 | ok      golang-book/chapter11/math      0.032s
28 | 29 |

The go test command will look for any tests in any of the files in the current folder and run them. Tests are identified by starting a function with the word Test and taking one argument of type *testing.T. In our case since we're testing the Average function we name the test function TestAverage.

30 | 31 |

Once we have the testing function setup we write tests that use the code we're testing. In this case we know the average of [1,2] should be 1.5 so that's what we check. It's probably a good idea to test many different combinations of numbers so let's change our test program a little:

32 |
package math
33 | 
34 | import "testing"
35 | 
36 | type testpair struct {
37 |   values []float64
38 |   average float64
39 | }
40 | 
41 | var tests = []testpair{
42 |   { []float64{1,2}, 1.5 },
43 |   { []float64{1,1,1,1,1,1}, 1 },
44 |   { []float64{-1,1}, 0 },
45 | }
46 | 
47 | func TestAverage(t *testing.T) {
48 |   for _, pair := range tests {
49 |     v := Average(pair.values)
50 |     if v != pair.average {
51 |       t.Error(
52 |         "For", pair.values,
53 |         "expected", pair.average,
54 |         "got", v,
55 |       )
56 |     }
57 |   }
58 | }

This is a very common way to setup tests (abundant examples can be found in the source code for the packages included with Go). We create a struct to represent the inputs and outputs for the function. Then we create a list of these structs (pairs). Then we loop through each one and run the function.

59 | 60 | 61 |

Problems

62 | 63 |
    64 |
  • Writing a good suite of tests is not always easy, but the process of writings tests often reveals more about a problem then you may at first realize. For example, with our Average function what happens if you pass in an empty list ([]float64{})? How could we modify the function to return 0 in this case?

  • 65 |
  • Write a series of tests for the Min and Max functions you wrote in the previous chapter.

  • 66 |
67 | 68 | 69 | 70 | 71 | 72 |
← PreviousIndexNext →
73 | 74 |
75 | -------------------------------------------------------------------------------- /templates/books/intro/14.gohtml: -------------------------------------------------------------------------------- 1 |
2 | 3 |

Next Steps

4 |

5 | We now have all the information we need to write most Go programs. But it 6 | would be dangerous to conclude that therefore we are competent programmers. 7 | Programming is as much a craft as it is just having knowledge. This chapter 8 | will provide you with some suggestions about how best to master the craft of 9 | programming. 10 |

11 | 12 |

Study the Masters

13 |

14 | Part of becoming a good artist or writer is studying the works of the masters. 15 | It's no different with programming. One of the best ways to become a 16 | skilled programmer is to study the source code produced by others. Go is well 17 | suited to this task since the source code for the entire project is freely 18 | available. 19 |

20 |

21 | For example we might take a look at the source code to the 22 | io/ioutil library available at: 23 |

24 |

25 | http://golang.org/src/pkg/io/ioutil/ioutil.go 26 |

27 |

28 | Read the code slowly and deliberately. Try to understand every line and read 29 | the supplied comments. For example in the ReadFile method 30 | there's a comment that says this: 31 |

32 |
// It's a good but not certain bet that FileInfo
33 | // will tell us exactly how much to read, so
34 | // let's try it but be prepared for the answer
35 | // to be wrong.
36 |

37 | This method probably started out simpler than what it became so this is a 38 | great example of how programs can evolve after testing and why it's 39 | important to supply comments with those changes. All of the source code for 40 | all of the packages is available at: 41 |

42 |

43 | http://golang.org/src/pkg/ 44 |

45 |

Make Something

46 |

47 | One of the best ways to hone your skills is to practice coding. There are a 48 | lot of ways to do this: You could work on challenging programming problems 49 | from sites like Project Euler 50 | (http://projecteuler.net/) 51 | or try your hand at a larger project. Perhaps try to implement a web server 52 | or write a simple game. 53 |

54 |

Team Up

55 |

56 | Most real-world software projects are done in teams, therefore learning how 57 | to work in a team is crucial. If you can, find a friend – maybe a classmate – 58 | and team up on a project. Learn how to divide a project into pieces you can 59 | both work on simultaneously. 60 |

61 |

62 | Another option is to work on an open source project. Find a 3rd party library, 63 | write some code (perhaps fix a bug), and submit it to the maintainer. Go has a 64 | growing community which can be reached via the mailing list 65 | (http://groups.google.com/group/golang-nuts). 66 |

67 | 68 | 69 | 70 | 71 | 72 |
← PreviousIndex
73 | 74 |
75 | -------------------------------------------------------------------------------- /templates/books/intro/2.gohtml: -------------------------------------------------------------------------------- 1 |
2 |

Your First Program

3 |

4 | Traditionally the first program you write in any programming language is 5 | called a “Hello World” program – a program that simply outputs 6 | Hello World to your terminal. Let's write one using Go. 7 |

8 |

9 | First create a new folder where we can store our program. Create a folder 10 | named ~/src/golang-book/chapter2. (Where ~ means 11 | your home directory) From the terminal you can do this by entering the 12 | following commands: 13 |

14 |
mkdir src/golang-book
15 | mkdir src/golang-book/chapter2
16 |

17 | Using your text editor type in the following: 18 |

19 |
package main
20 | 
21 | import "fmt"
22 | 
23 | // this is a comment
24 | 
25 | func main() {
26 |     fmt.Println("Hello World")
27 | }
28 |

29 | Make sure your file is identical to what is shown here and save it as 30 | main.go in the folder we just created. Open up a new terminal 31 | and type in the following: 32 |

33 |
cd src/golang-book/chapter2
34 | go run main.go
35 |

36 | You should see Hello World displayed in your terminal. 37 | The go run command takes the subsequent files (separated by 38 | spaces), compiles them into an executable saved in a temporary directory and 39 | then runs the program. If you didn't see Hello World 40 | displayed you may have made a mistake when typing in the program. The Go 41 | compiler will give you hints about where the mistake lies. Like most 42 | compilers, the Go compiler is extremely pedantic and has no tolerance for 43 | mistakes. 44 |

45 |

How to Read a Go Program

46 |

47 | Let's look at this program in more detail. Go programs are read top to 48 | bottom, left to right. (like a book) The first line says this: 49 |

50 |
package main

This is known as a “package declaration”. Every Go program must start with a package declaration. Packages are Go's way of organizing and reusing code. There are two types of Go programs: executables and libraries. Executable applications are the kinds of programs that we can run directly from the terminal. (in Windows they end with .exe) Libraries are collections of code that we package together so that we can use them in other programs. We will explore libraries in more detail later, for now just make sure to include this line in any program you write.

51 |

The next line is a blank line. Computers represent newlines with a special character (or several characters). Newlines, spaces and tabs are known as whitespace (because you can't see them). Go mostly doesn't care about whitespace, we use it to make programs easier to read. (You could remove this line and the program would behave in exactly the same way)

52 |

Then we see this:

53 |
import "fmt"

The import keyword is how we include code from other packages to use with our program. The fmt package (shorthand for format) implements formatting for input and output. Given what we just learned about packages what do you think the fmt package's files would contain at the top of them?

54 |

Notice that fmt above is surrounded by double quotes. The use of double quotes like this is known as a “string literal” which is a type of “expression”. In Go strings represent a sequence of characters (letters, numbers, symbols, …) of a definite length. Strings are described in more detail in the next chapter, but for now the important thing to keep in mind is that an opening " character must eventually be followed by another " character and anything in between the two is included in the string. (The " character itself is not part of the string)

55 |

The line that starts with // is known as a comment. Comments are ignored by the Go compiler and are there for your own sake (or whoever picks up the source code for your program). Go supports two different styles of comments: // comments in which all the text between the // and the end of the line is part of the comment and /* */ comments where everything between the *s is part of the comment. (And may include multiple lines)

56 |

After this you see a function declaration:

57 |
func main() {
58 |     fmt.Println("Hello World")
59 | }

Functions are the building blocks of a Go program. They have inputs, outputs and a series of steps called statements which are executed in order. All functions start with the keyword func followed by the name of the function (main in this case), a list of zero or more “parameters” surrounded by parentheses, an optional return type and a “body” which is surrounded by curly braces. This function has no parameters, doesn't return anything and has only one statement. The name main is special because it's the function that gets called when you execute the program.

60 |

The final piece of our program is this line:

61 |
    fmt.Println("Hello World")

This statement is made of three components. First we access another function inside of the fmt package called Println (that's the fmt.Println piece, Println means Print Line). Then we create a new string that contains Hello World and invoke (also known as call or execute) that function with the string as the first and only argument.

62 |

At this point we've already seen a lot of new terminology and you may be a bit overwhelmed. Sometimes its helpful to deliberately read your program out loud. One reading of the program we just wrote might go like this:

63 |

Create a new executable program, which references the fmt library and contains one function called main. That function takes no arguments, doesn't return anything and does the following: Access the Println function contained inside of the fmt package and invoke it using one argument – the string Hello World.

64 |

The Println function does the real work in this program. You can find out more about it by typing the following in your terminal:

65 |
godoc fmt Println

Among other things you should see this:

66 |
Println formats using the default formats for its operands and writes to standard output. Spaces are always added between operands and a newline is appended. It returns the number of bytes written and any write error encountered.

Go is a very well documented programming language but this documentation can be difficult to understand unless you are already familiar with programming languages. Nevertheless the godoc command is extremely useful and a good place to start whenever you have a question.

67 |

Back to the function at hand, this documentation is telling you that the Println function will send whatever you give to it to standard output – a name for the output of the terminal you are working in. This function is what causes Hello World to be displayed.

68 |

In the next chapter we will explore how Go stores and represents things like Hello World by learning about types.

69 | 70 | 71 |

Problems

72 | 73 |
  • What is whitespace?

    74 |
  • What is a comment? What are the two ways of writing a comment?

    75 |
  • Our program began with package main. What would the files in the fmt package begin with?

    76 |
  • We used the Println function defined in the fmt package. If we wanted to use the Exit function from the os package what would we need to do?

    77 |
  • Modify the program we wrote so that instead of printing Hello World it prints Hello, my name is followed by your name.

    78 |
← PreviousIndexNext →
79 |
80 | -------------------------------------------------------------------------------- /templates/books/intro/4.gohtml: -------------------------------------------------------------------------------- 1 |
2 | 3 |

Variables

Up until now we have only seen programs that use literal values (numbers, strings, etc.) but such programs aren't particularly useful. To make truly useful programs we need to learn two new concepts: variables and control flow statements. This chapter will explore variables in more detail.

4 |

A variable is a storage location, with a specific type and an associated name. Let's change the program we wrote in chapter 2 so that it uses a variable:

5 |
package main
  6 | 
  7 | import "fmt"
  8 | 
  9 | func main() {
 10 |   var x string = "Hello World"
 11 |   fmt.Println(x)
 12 | }

Notice that the string literal from the original program still appears in this program, but rather than send it directly to the Println function we assign it to a variable instead. Variables in Go are created by first using the var keyword, then specifying the variable name (x), the type (string) and finally assigning a value to the variable (Hello World). The last step is optional so an alternative way of writing the program would be like this:

13 |
package main
 14 | 
 15 | import "fmt"
 16 | 
 17 | func main() {
 18 |   var x string
 19 |   x = "Hello World"
 20 |   fmt.Println(x)
 21 | }

Variables in Go are similar to variables in algebra but there are some subtle differences:

22 |

First when we see the = symbol we have a tendency to read that as “x equals the string Hello World”. There's nothing wrong with reading our program that way, but it's better to read it as “x takes the string Hello World” or “x is assigned the string Hello World”. This distinction is important because (as their name would suggest) variables can change their value throughout the lifetime of a program. Try running the following:

23 |
package main
 24 | 
 25 | import "fmt"
 26 | 
 27 | func main() {
 28 |   var x string
 29 |   x = "first"
 30 |   fmt.Println(x)
 31 |   x = "second"
 32 |   fmt.Println(x)
 33 | }

In fact you can even do this:

34 |
var x string
 35 | x = "first "
 36 | fmt.Println(x)
 37 | x = x + "second"
 38 | fmt.Println(x)

This program would be nonsense if you read it like an algebraic theorem. But it makes sense if you are careful to read the program as a list of commands. When we see x = x + "second" we should read it as “assign the concatenation of the value of the variable x and the string literal second to the variable x.” The right side of the = is done first and the result is then assigned to the left side of the =.

39 |

The x = x + y form is so common in programming that Go has a special assignment statement: +=. We could have written x = x + "second" as x += "second" and it would have done the same thing. (Other operators can be used the same way)

40 |

Another difference between Go and algebra is that we use a different symbol for equality: ==. (Two equal signs next to each other) == is an operator like + and it returns a boolean. For example:

41 |
var x string = "hello"
 42 | var y string = "world"
 43 | fmt.Println(x == y)

This program should print false because hello is not the same as world. On the other hand:

44 |
var x string = "hello"
 45 | var y string = "hello"
 46 | fmt.Println(x == y)

This will print true because the two strings are the same.

47 |

Since creating a new variable with a starting value is so common Go also supports a shorter statement:

48 |
x := "Hello World"

Notice the : before the = and that no type was specified. The type is not necessary because the Go compiler is able to infer the type based on the literal value you assign the variable. (Since you are assigning a string literal, x is given the type string) The compiler can also do inference with the var statement:

49 |
var x = "Hello World"

The same thing works for other types:

50 |
x := 5
 51 | fmt.Println(x)

Generally you should use this shorter form whenever possible.

52 |

How to Name a Variable

Naming a variable properly is an important part of software development. Names must start with a letter and may contain letters, numbers or the _ (underscore) symbol. The Go compiler doesn't care what you name a variable so the name is meant for your (and others) benefit. Pick names which clearly describe the variable's purpose. Suppose we had the following:

53 |
x := "Max"
 54 | fmt.Println("My dog's name is", x)

In this case x is not a very good name for a variable. A better name would be:

55 |
name := "Max"
 56 | fmt.Println("My dog's name is", name)

or even:

57 |
dogsName := "Max"
 58 | fmt.Println("My dog's name is", dogsName)

In this last case we use a special way to represent multiple words in a variable name known as lower camel case (also know as mixed case, bumpy caps, camel back or hump back). The first letter of the first word is lowercase, the first letter of the subsequent words is uppercase and all the other letters are lowercase.

59 |

Scope

Going back to the program we saw at the beginning of the chapter:

60 |
package main
 61 | 
 62 | import "fmt"
 63 | 
 64 | func main() {
 65 |   var x string = "Hello World"
 66 |   fmt.Println(x)
 67 | }

Another way of writing this program would be like this:

68 |
package main
 69 | 
 70 | import "fmt"
 71 | 
 72 | var x string = "Hello World"
 73 | 
 74 | func main() {
 75 |   fmt.Println(x)
 76 | }

Notice that we moved the variable outside of the main function. This means that other functions can access this variable:

77 |
var x string = "Hello World"
 78 | 
 79 | func main() {
 80 |   fmt.Println(x)
 81 | }
 82 | 
 83 | func f() {
 84 |   fmt.Println(x)
 85 | }

The f function now has access to the x variable. Now suppose that we wrote this instead:

86 |
func main() {
 87 |   var x string = "Hello World"
 88 |   fmt.Println(x)
 89 | }
 90 | 
 91 | func f() {
 92 |   fmt.Println(x)
 93 | }

If you run this program you should see an error:

94 |
.\main.go:11: undefined: x

The compiler is telling you that the x variable inside of the f function doesn't exist. It only exists inside of the main function. The range of places where you are allowed to use x is called the scope of the variable. According to the language specification “Go is lexically scoped using blocks”. Basically this means that the variable exists within the nearest curly braces { } (a block) including any nested curly braces (blocks), but not outside of them. Scope can be a little confusing at first; as we see more Go examples it should become more clear.

95 |

Constants

Go also has support for constants. Constants are basically variables whose values cannot be changed later. They are created in the same way you create variables but instead of using the var keyword we use the const keyword:

96 |
package main
 97 | 
 98 | import "fmt"
 99 | 
100 | func main() {
101 |   const x string = "Hello World"
102 |   fmt.Println(x)
103 | }

This:

104 |
const x string = "Hello World"
105 | x = "Some other string"

Results in a compile-time error:

106 |
.\main.go:7: cannot assign to x

Constants are a good way to reuse common values in a program without writing them out each time. For example Pi in the math package is defined as a constant.

107 |

Defining Multiple Variables

Go also has another shorthand when you need to define multiple variables:

108 |
var (
109 |   a = 5
110 |   b = 10
111 |   c = 15
112 | )

Use the keyword var (or const) followed by parentheses with each variable on its own line.

113 |

An Example Program

Here's an example program which takes in a number entered by the user and doubles it:

114 |
package main
115 | 
116 | import "fmt"
117 | 
118 | func main() {
119 |   fmt.Print("Enter a number: ")
120 |   var input float64
121 |   fmt.Scanf("%f", &input)
122 | 
123 |   output := input * 2
124 | 
125 |   fmt.Println(output)
126 | }

We use another function from the fmt package to read the user input (Scanf). &input will be explained in a later chapter, for now all we need to know is that Scanf fills input with the number we enter.

127 | 128 | 129 |

Problems

130 | 131 |
  • What are two ways to create a new variable?

    132 |
  • What is the value of x after running:
    x := 5; x += 1?

    133 |
  • What is scope and how do you determine the scope of a variable in Go?

    134 |
  • What is the difference between var and const?

    135 |
  • Using the example program as a starting point, write a program that converts from Fahrenheit into Celsius. (C = (F - 32) * 5/9)

    136 |
  • Write another program that converts from feet into meters. (1 ft = 0.3048 m)

    137 |
138 | 139 | 140 | 141 | 142 | 143 |
← PreviousIndexNext →
144 | 145 |
146 | -------------------------------------------------------------------------------- /templates/books/intro/5.gohtml: -------------------------------------------------------------------------------- 1 |
2 | 3 |

Control Structures

Now that we know how to use variables it's time to start writing some useful programs. First let's write a program that counts to 10, starting from 1, with each number on its own line. Using what we've learned so far we could write this:

4 |
package main
  5 | 
  6 | import "fmt"
  7 | 
  8 | func main() {
  9 |   fmt.Println(1)
 10 |   fmt.Println(2)
 11 |   fmt.Println(3)
 12 |   fmt.Println(4)
 13 |   fmt.Println(5)
 14 |   fmt.Println(6)
 15 |   fmt.Println(7)
 16 |   fmt.Println(8)
 17 |   fmt.Println(9)
 18 |   fmt.Println(10)
 19 | }

Or this:

20 |
package main
 21 | import "fmt"
 22 | 
 23 | func main() {
 24 |   fmt.Println(`1
 25 | 2
 26 | 3
 27 | 4
 28 | 5
 29 | 6
 30 | 7
 31 | 8
 32 | 9
 33 | 10`)
 34 | }

But both of these programs are pretty tedious to write. What we need is a way of doing something multiple times.

35 |

For

The for statement allows us to repeat a list of statements (a block) multiple times. Rewriting our previous program using a for statement looks like this:

36 |
package main
 37 | 
 38 | import "fmt"
 39 | 
 40 | func main() {
 41 |   i := 1
 42 |   for i <= 10 {
 43 |     fmt.Println(i)
 44 |     i = i + 1
 45 |   }
 46 | }

First we create a variable called i that we use to store the number we want to print. Then we create a for loop by using the keyword for, providing a conditional expression which is either true or false and finally supplying a block to execute. The for loop works like this:

47 |
  • We evaluate (run) the expression i <= 10 (“i less than or equal to 10”). If this evaluates to true then we run the statements inside of the block. Otherwise we jump to the next line of our program after the block. (in this case there is nothing after the for loop so we exit the program)

    48 |
  • After we run the statements inside of the block we loop back to the beginning of the for statement and repeat step 1.

    49 |

The i = i + 1 line is extremely important, because without it i <= 10 would always evaluate to true and our program would never stop. (When this happens this is referred to as an infinite loop)

50 |

As an exercise let's walk through the program like a computer would:

51 |
  • Create a variable named i with the value 1

    52 |
  • Is i <= 10? Yes.

    53 |
  • Print i

    54 |
  • Set i to i + 1 (i now equals 2)

    55 |
  • Is i <= 10? Yes.

    56 |
  • Print i

    57 |
  • Set i to i + 1 (i now equals 3)

    58 |
  • 59 |
  • Set i to i + 1 (i now equals 11)

    60 |
  • Is i <= 10? No.

    61 |
  • Nothing left to do, so exit

    62 | 63 |

Other programming languages have a lot of different types of loops (while, do, until, foreach, …) but Go only has one that can be used in a variety of different ways. The previous program could also have been written like this:

64 |
func main() {
 65 |   for i := 1; i <= 10; i++ {
 66 |     fmt.Println(i)
 67 |   }
 68 | }

Now the conditional expression also contains two other statements with semicolons between them. First we have the variable initialization, then we have the condition to check each time and finally we “increment” the variable. (adding 1 to a variable is so common that we have a special operator: ++. Similarly subtracting 1 can be done with --)

69 |

We will see additional ways of using the for loop in later chapters.

70 |

If

Let's modify the program we just wrote so that instead of just printing the numbers 1-10 on each line it also specifies whether or not the number is even or odd. Like this:

71 |
1 odd
 72 | 2 even
 73 | 3 odd
 74 | 4 even
 75 | 5 odd
 76 | 6 even
 77 | 7 odd
 78 | 8 even
 79 | 9 odd
 80 | 10 even

First we need a way of determining whether or not a number is even or odd. An easy way to tell is to divide the number by 2. If you have nothing left over then the number is even, otherwise it's odd. So how do we find the remainder after division in Go? We use the % operator. 1 % 2 equals 1, 2 % 2 equals 0, 3 % 2 equals 1 and so on.

81 |

Next we need a way of choosing to do different things based on a condition. For that we use the if statement:

82 |
if i % 2 == 0 {
 83 |   // even
 84 | } else {
 85 |   // odd
 86 | }

An if statement is similar to a for statement in that it has a condition followed by a block. If statements also have an optional else part. If the condition evaluates to true then the block after the condition is run, otherwise either the block is skipped or if the else block is present that block is run.

87 |

If statements can also have else if parts:

88 |
if i % 2 == 0 {
 89 |   // divisible by 2
 90 | } else if i % 3 == 0 {
 91 |   // divisible by 3
 92 | } else if i % 4 == 0 {
 93 |   // divisible by 4
 94 | }

The conditions are checked top down and the first one to result in true will have its associated block executed. None of the other blocks will execute, even if their conditions also pass. (So for example the number 8 is divisible by both 4 and 2, but the // divisible by 4 block will never execute because the // divisible by 2 block is done first)

95 |

Putting it all together we have:

96 |
func main() {
 97 |   for i := 1; i <= 10; i++ {
 98 |     if i % 2 == 0 {
 99 |       fmt.Println(i, "even")
100 |     } else {
101 |       fmt.Println(i, "odd")
102 |     }
103 |   }
104 | }

Let's walk through this program:

105 |
  • Create a variable i of type int and give it the value 1

    106 |
  • Is i less than or equal to 10? Yes: jump to the block

    107 |
  • Is the remainder of i ÷ 2 equal to 0? No: jump to the else block

    108 |
  • Print i followed by odd

    109 |
  • Increment i (the statement after the condition)

    110 |
  • Is i less than or equal to 10? Yes: jump to the block

    111 |
  • Is the remainder of i ÷ 2 equal to 0? Yes: jump to the if block

    112 |
  • Print i followed by even

    113 |

  • 114 |

The remainder operator, while rarely seen outside of elementary school, turns out to be really useful when programming. You'll see it turn up everywhere from zebra striping tables to partitioning data sets.

115 |

Switch

Suppose we wanted to write a program that printed the English names for numbers. Using what we've learned so far we might start by doing this:

116 |
if i == 0 {
117 |   fmt.Println("Zero")
118 | } else if i == 1 {
119 |   fmt.Println("One")
120 | } else if i == 2 {
121 |   fmt.Println("Two")
122 | } else if i == 3 {
123 |   fmt.Println("Three")
124 | } else if i == 4 {
125 |   fmt.Println("Four")
126 | } else if i == 5 {
127 |   fmt.Println("Five")
128 | }

Since writing a program in this way would be pretty tedious Go provides another statement to make this easier: the switch statement. We can rewrite our program to look like this:

129 |
switch i {
130 | case 0: fmt.Println("Zero")
131 | case 1: fmt.Println("One")
132 | case 2: fmt.Println("Two")
133 | case 3: fmt.Println("Three")
134 | case 4: fmt.Println("Four")
135 | case 5: fmt.Println("Five")
136 | default: fmt.Println("Unknown Number")
137 | }

A switch statement starts with the keyword switch followed by an expression (in this case i) and then a series of cases. The value of the expression is compared to the expression following each case keyword. If they are equivalent then the statement(s) following the : is executed.

138 |

Like an if statement each case is checked top down and the first one to succeed is chosen. A switch also supports a default case which will happen if none of the cases matches the value. (Kind of like the else in an if statement)

139 |

These are the main control flow statements. Additional statements will be explored in later chapters.

140 | 141 | 142 |

Problems

143 | 144 |
  • What does the following program print:

    145 |
    i := 10
    146 | if i > 10 {
    147 |   fmt.Println("Big")
    148 | } else {
    149 |   fmt.Println("Small")
    150 | }
  • Write a program that prints out all the numbers evenly divisible by 3 between 1 and 100. (3, 6, 9, etc.)

    151 |
  • Write a program that prints the numbers from 1 to 100. But for multiples of three print "Fizz" instead of the number and for the multiples of five print "Buzz". For numbers which are multiples of both three and five print "FizzBuzz".

    152 |
153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 |
← PreviousIndexNext →
161 | 162 |
163 | -------------------------------------------------------------------------------- /templates/books/intro/8.gohtml: -------------------------------------------------------------------------------- 1 |
2 | 3 |

Pointers

4 |

When we call a function that takes an argument, that argument is copied to the function:

5 |
func zero(x int) {
 6 |   x = 0
 7 | }
 8 | func main() {
 9 |   x := 5
10 |   zero(x)
11 |   fmt.Println(x) // x is still 5
12 | }
13 | 14 |

In this program the zero function will not modify the original x variable in the main function. But what if we wanted to? One way to do this is to use a special data type known as a pointer:

15 |
func zero(xPtr *int) {
16 |   *xPtr = 0
17 | }
18 | func main() {
19 |   x := 5
20 |   zero(&x)
21 |   fmt.Println(x) // x is 0
22 | }
23 | 24 |

Pointers reference a location in memory where a value is stored rather than the value itself. (They point to something else) By using a pointer (*int) the zero function is able to modify the original variable.

25 |

The * and & operators

26 |

In Go a pointer is represented using the * (asterisk) character followed by the type of the stored value. In the zero function xPtr is a pointer to an int.

27 |

* is also used to “dereference” pointer variables. Dereferencing a pointer gives us access to the value the pointer points to. When we write *xPtr = 0 we are saying “store the int 0 in the memory location xPtr refers to”. If we try xPtr = 0 instead we will get a compiler error because xPtr is not an int it's a *int, which can only be given another *int.

28 |

Finally we use the & operator to find the address of a variable. &x returns a *int (pointer to an int) because x is an int. This is what allows us to modify the original variable. &x in main and xPtr in zero refer to the same memory location.

29 |

new

Another way to get a pointer is to use the built-in new function:

30 |
func one(xPtr *int) {
31 |   *xPtr = 1
32 | }
33 | func main() {
34 |   xPtr := new(int)
35 |   one(xPtr)
36 |   fmt.Println(*xPtr) // x is 1
37 | }

new takes a type as an argument, allocates enough memory to fit a value of that type and returns a pointer to it.

38 |

In some programming languages there is a significant difference between using new and &, with great care being needed to eventually delete anything created with new. Go is not like this, it's a garbage collected programming language which means memory is cleaned up automatically when nothing refers to it anymore.

39 |

Pointers are rarely used with Go's built-in types, but as we will see in the next chapter, they are extremely useful when paired with structs.

40 | 41 | 42 |

Problems

43 | 44 |
    45 |
  • How do you get the memory address of a variable?

  • 46 |
  • How do you assign a value to a pointer?

  • 47 |
  • How do you create a new pointer?

  • 48 |
  • What is the value of x after running this program:

    49 |
    func square(x *float64) {
    50 |   *x = *x * *x
    51 | }
    52 | func main() {
    53 |   x := 1.5
    54 |   square(&x)
    55 | }
  • 56 |
  • Write a program that can swap two integers (x := 1; y := 2; swap(&x, &y) should give you x=2 and y=1).

  • 57 |
58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 |
← PreviousIndexNext →
66 | 67 |
68 | -------------------------------------------------------------------------------- /templates/books/intro/9.gohtml: -------------------------------------------------------------------------------- 1 |
2 | 3 |

Structs and Interfaces

4 |

Although it would be possible for us to write programs only using Go's built-in data types, at some point it would become quite tedious. Consider a program that interacts with shapes:

5 |
package main
  6 | 
  7 | import ("fmt"; "math")
  8 | 
  9 | func distance(x1, y1, x2, y2 float64) float64 {
 10 |   a := x2 – x1
 11 |   b := y2 – y1
 12 |   return math.Sqrt(a*a + b*b)
 13 | }
 14 | func rectangleArea(x1, y1, x2, y2 float64) float64 {
 15 |   l := distance(x1, y1, x1, y2)
 16 |   w := distance(x1, y1, x2, y1)
 17 |   return l * w
 18 | }
 19 | func circleArea(x, y, r float64) float64 {
 20 |   return math.Pi * r*r
 21 | }
 22 | func main() {
 23 |   var rx1, ry1 float64 = 0, 0
 24 |   var rx2, ry2 float64 = 10, 10
 25 |   var cx, cy, cr float64 = 0, 0, 5
 26 | 
 27 |   fmt.Println(rectangleArea(rx1, ry1, rx2, ry2))
 28 |   fmt.Println(circleArea(cx, cy, cr))
 29 | }
30 | 31 |

Keeping track of all the coordinates makes it difficult to see what the program is doing and will likely lead to mistakes.

32 | 33 |

Structs

34 |

An easy way to make this program better is to use a struct. A struct is a type which contains named fields. For example we could represent a Circle like this:

35 |
type Circle struct {
 36 |   x float64
 37 |   y float64
 38 |   r float64
 39 | }
40 | 41 |

The type keyword introduces a new type. It's followed by the name of the type (Circle), the keyword struct to indicate that we are defining a struct type and a list of fields inside of curly braces. Each field has a name and a type. Like with functions we can collapse fields that have the same type:

42 |
type Circle struct {
 43 |   x, y, r float64
 44 | }
45 | 46 |

Initialization

47 | 48 |

We can create an instance of our new Circle type in a variety of ways:

49 |
var c Circle
50 | 51 |

Like with other data types, this will create a local Circle variable that is by default set to zero. For a struct zero means each of the fields is set to their corresponding zero value (0 for ints, 0.0 for floats, "" for strings, nil for pointers, …) We can also use the new function:

52 |
c := new(Circle)
53 | 54 |

This allocates memory for all the fields, sets each of them to their zero value and returns a pointer. (*Circle) More often we want to give each of the fields a value. We can do this in two ways. Like this:

55 |
c := Circle{x: 0, y: 0, r: 5}
56 | 57 |

Or we can leave off the field names if we know the order they were defined:

58 |
c := Circle{0, 0, 5}

Fields

59 | 60 |

We can access fields using the . operator:

61 |
fmt.Println(c.x, c.y, c.r)
 62 | c.x = 10
 63 | c.y = 5
64 | 65 |

Let's modify the circleArea function so that it uses a Circle:

66 |
func circleArea(c Circle) float64 {
 67 |   return math.Pi * c.r*c.r
 68 | }
69 | 70 |

In main we have:

71 |
c := Circle{0, 0, 5}
 72 | fmt.Println(circleArea(c))
73 | 74 |

One thing to remember is that arguments are always copied in Go. If we attempted to modify one of the fields inside of the circleArea function, it would not modify the original variable. Because of this we would typically write the function like this:

75 |
func circleArea(c *Circle) float64 {
 76 |   return math.Pi * c.r*c.r
 77 | }
78 | 79 |

And change main:

80 |
c := Circle{0, 0, 5}
 81 | fmt.Println(circleArea(&c))

Methods

Although this is better than the first version of this code, we can improve it significantly by using a special type of function known as a method:

82 |
func (c *Circle) area() float64 {
 83 |   return math.Pi * c.r*c.r
 84 | }
85 | 86 |

In between the keyword func and the name of the function we've added a “receiver”. The receiver is like a parameter – it has a name and a type – but by creating the function in this way it allows us to call the function using the . operator:

87 |
fmt.Println(c.area())

This is much easier to read, we no longer need the & operator (Go automatically knows to pass a pointer to the circle for this method) and because this function can only be used with Circles we can rename the function to just area.

88 | 89 |

Let's do the same thing for the rectangle:

90 |
type Rectangle struct {
 91 |   x1, y1, x2, y2 float64
 92 | }
 93 | func (r *Rectangle) area() float64 {
 94 |   l := distance(r.x1, r.y1, r.x1, r.y2)
 95 |   w := distance(r.x1, r.y1, r.x2, r.y1)
 96 |   return l * w
 97 | }
98 | 99 |

main has:

100 |
r := Rectangle{0, 0, 10, 10}
101 | fmt.Println(r.area())

Embedded Types

102 | 103 |

A struct's fields usually represent the has-a relationship. For example a Circle has a radius. Suppose we had a person struct:

104 |
type Person struct {
105 |   Name string
106 | }
107 | func (p *Person) Talk() {
108 |   fmt.Println("Hi, my name is", p.Name)
109 | }
110 | 111 |

And we wanted to create a new Android struct. We could do this:

112 |
type Android struct {
113 |   Person Person
114 |   Model string
115 | }
116 | 117 |

This would work, but we would rather say an Android is a Person, rather than an Android has a Person. Go supports relationships like this by using an embedded type. Also known as anonymous fields, embedded types look like this:

118 |
type Android struct {
119 |   Person
120 |   Model string
121 | }
122 | 123 |

We use the type (Person) and don't give it a name. When defined this way the Person struct can be accessed using the type name:

124 |
a := new(Android)
125 | a.Person.Talk()
126 | 127 |

But we can also call any Person methods directly on the Android:

128 |
a := new(Android)
129 | a.Talk()
130 | 131 |

The is-a relationship works this way intuitively: People can talk, an android is a person, therefore an android can talk.

132 | 133 |

Interfaces

134 |

You may have noticed that we were able to name the Rectangle's area method the same thing as the Circle's area method. This was no accident. In both real life and in programming, relationships like these are commonplace. Go has a way of making these accidental similarities explicit through a type known as an Interface. Here is an example of a Shape interface:

135 |
type Shape interface {
136 |   area() float64
137 | }
138 | 139 |

Like a struct an interface is created using the type keyword, followed by a name and the keyword interface. But instead of defining fields, we define a “method set”. A method set is a list of methods that a type must have in order to “implement” the interface.

140 | 141 |

In our case both Rectangle and Circle have area methods which return float64s so both types implement the Shape interface. By itself this wouldn't be particularly useful, but we can use interface types as arguments to functions:

142 |
func totalArea(shapes ...Shape) float64 {
143 |   var area float64
144 |   for _, s := range shapes {
145 |     area += s.area()
146 |   }
147 |   return area
148 | }
149 | 150 |

We would call this function like this:

151 |
fmt.Println(totalArea(&c, &r))
152 | 153 |

Interfaces can also be used as fields:

154 |
type MultiShape struct {
155 |   shapes []Shape
156 | }
157 | 158 |

We can even turn MultiShape itself into a Shape by giving it an area method:

159 |
func (m *MultiShape) area() float64 {
160 |   var area float64
161 |   for _, s := range m.shapes {
162 |     area += s.area()
163 |   }
164 |   return area
165 | }
166 | 167 |

Now a MultiShape can contain Circles, Rectangles or even other MultiShapes.

168 | 169 |

Problems

170 | 171 |
  • What's the difference between a method and a function?

    172 |
  • Why would you use an embedded anonymous field instead of a normal named field?

    173 |
  • Add a new method to the Shape interface called perimeter which calculates the perimeter of a shape. Implement the method for Circle and Rectangle.

    174 |
175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 |
← PreviousIndexNext →
183 | 184 |
185 | -------------------------------------------------------------------------------- /templates/books/intro/front.gohtml: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 |

Installers

5 |

6 | I no longer maintain installers here. For instructions on how to get a text 7 | editor and go installed see the 8 | Machine Setup guide. 9 |

10 | 11 |

The Book

12 |

13 | An Introduction to Programming in Go.
14 | Copyright © 2012 by Caleb Doxsey
15 | ISBN: 978-1478355823 16 |

17 |

18 | This book is no longer available for purchase, but it is still available for 19 | free online below or in PDF form. 20 |

21 |

22 | An updated version is available from 23 | O'Reilly. 24 |

25 |

26 | Questions, comments, corrections or concerns can be sent to 27 | Caleb Doxsey. 28 |

29 | 30 | 31 |

Table of Contents

32 |
    33 |
  1. Getting Started 34 |
      35 |
    1. Files and Folders
    2. 36 |
    3. The Terminal
    4. 37 |
    5. Text Editors
    6. 38 |
    7. Go Tools
    8. 39 |
    40 |
  2. 41 |
  3. Your First Program 42 |
      43 |
    1. How to Read a Go Program
    2. 44 |
    45 |
  4. 46 |
  5. Types 47 |
      48 |
    1. Numbers
    2. 49 |
    3. Strings
    4. 50 |
    5. Booleans
    6. 51 |
    52 |
  6. 53 |
  7. Variables 54 |
      55 |
    1. How to Name a Variable
    2. 56 |
    3. Scope
    4. 57 |
    5. Constants
    6. 58 |
    7. Defining Multiple Variables
    8. 59 |
    9. An Example Program
    10. 60 |
    61 |
  8. 62 |
  9. Control Structures 63 |
      64 |
    1. For
    2. 65 |
    3. If
    4. 66 |
    5. Switch
    6. 67 |
    68 |
  10. 69 |
  11. Arrays, Slices and Maps 70 |
      71 |
    1. Arrays
    2. 72 |
    3. Slices
    4. 73 |
    5. Maps
    6. 74 |
    75 |
  12. 76 |
  13. Functions 77 |
      78 |
    1. Your Second Function
    2. 79 |
    3. Returning Multiple Values
    4. 80 |
    5. Variadic Functions
    6. 81 |
    7. Closure
    8. 82 |
    9. Recursion
    10. 83 |
    11. Defer, Panic & Recover
    12. 84 |
    85 |
  14. 86 |
  15. Pointers 87 |
      88 |
    1. The * and & operators
    2. 89 |
    3. new
    4. 90 |
    91 |
  16. 92 |
  17. Structs and Interfaces 93 |
      94 |
    1. Structs
    2. 95 |
    3. Methods
    4. 96 |
    5. Interfaces
    6. 97 |
    98 |
  18. 99 |
  19. Concurrency 100 |
      101 |
    1. Goroutines
    2. 102 |
    3. Channels
    4. 103 |
    104 |
  20. 105 |
  21. Packages 106 |
      107 |
    1. Creating Packages
    2. 108 |
    3. Documentation
    4. 109 |
    110 |
  22. 111 |
  23. Testing 112 |
      113 |
    1. 114 |
    2. The Core Packages 115 |
        116 |
      1. Strings
      2. 117 |
      3. Input / Output
      4. 118 |
      5. Files & Folders
      6. 119 |
      7. Errors
      8. 120 |
      9. Containers & Sort
      10. 121 |
      11. Hashes & Cryptography
      12. 122 |
      13. Servers
      14. 123 |
      15. Parsing Command Line Arguments
      16. 124 |
      17. Synchronization Primitives
      18. 125 |
      126 |
    3. 127 |
    4. Next Steps 128 |
        129 |
      1. Study the Masters
      2. 130 |
      3. Make Something
      4. 131 |
      5. Team Up
      6. 132 |
      133 |
    5. 134 |
    135 |
    136 | -------------------------------------------------------------------------------- /templates/books/intro/layout.gohtml: -------------------------------------------------------------------------------- 1 | 8 | {{.Body}} 9 | 22 | -------------------------------------------------------------------------------- /templates/books/web/00-01.gohtml: -------------------------------------------------------------------------------- 1 |
    2 |

    Introduction

    3 |

    4 | This book will teach you the basics of server-side web development with Go 5 | and the Google App Engine platform. Although web deveopment is not 6 | particularly difficult when compared to other types of software development, 7 | it can be challenging due to the sheer number of technologies involved. 8 |

    9 |

    10 | For this reason this book is not an exaustive treatment of web development. 11 | Rather than provide a merely cursory overview of each and every technology, 12 | we will dive deep on a particular way of building web applications with the 13 | hope of producing a real, functional piece of software that we actually 14 | understand and which we can use can use as the basis for tackling other 15 | areas of web development. 16 |

    17 |

    18 | This book is broken into 3 sections: 19 |

    20 |
      21 |
    1. Programming in Go
    2. 22 |
    3. Web Development with Go
    4. 23 |
    5. Web Development with Google App Engine
    6. 24 |
    25 |

    26 | Each chapter of each section will include explanations, walkthroughs, 27 | problems and projects. It's vital that you work through the problems and 28 | projects as you are much more likely to truly learn the material by using 29 | it. 30 |

    31 |

    32 | Before diving into Go there are some steps you need to take to setup your 33 | machine so that it is ready for development. If you haven't already done 34 | so take a look at the Machine Setup 35 | guide. 36 |

    37 | 38 | 39 | 40 | 43 | 46 | 49 | 50 |
    41 | ← Previous 42 | 44 | Index 45 | 47 | Next → 48 |
    51 |
    52 | -------------------------------------------------------------------------------- /templates/books/web/01-03.gohtml: -------------------------------------------------------------------------------- 1 |
    2 |

    A Deeper Look

    3 |

    4 | New programmers often express a desire to have a deeper understanding of 5 | how their program works. In this chapter we'll take a brief look at just 6 | what Go programs are doing behind the scenes. 7 |

    8 | 9 |

    Memory

    10 |

    11 | Variables are an abstract concept which the Go compiler understands and 12 | translates into something a computer can actually use. 13 |

    14 |

    15 | A computer is very complex, but its basic architecture - the Von 16 | Neumann architecture - involves 3 components: 17 |

    18 |
      19 |
    • 20 |

      21 | A central processing unit (CPU) which actually performs the instructions 22 | generated by the Go compiler 23 |

      24 |
    • 25 |
    • 26 |

      27 | Various input / output devices (like your keyboard, monitor, hard drive, 28 | WiFi, etc...) 29 |

      30 |
    • 31 |
    • 32 |

      33 | Read/write, random access memory (RAM) which stores both the data and 34 | instructions for your program 35 |

      36 |
    • 37 |
    38 |

    39 | Main memory is a really, really big array of bytes. Imagine a giant post 40 | office with billions of mailboxes. Each one of those mailboxes has an 41 | address (Box #1, Box #2 ... Box #1,000,000,000) and each one of 42 | those mailboxes can contain a single byte - a byte being made up of 8 bits (or 43 | on/off flags) and so storing a number between 0 and 255. (255 is 44 | 28-1 since we start at 0) 45 |

    46 |

    47 | It turns out we can represent pretty much anything this way. In particular 48 | we represent "Hello World" by converting each letter into a 49 | number and then assigning those numbers into a sequential series of boxes: 50 |

    51 | 52 |

    53 | So the way a program works is that variables are translated into memory 54 | addresses (the box numbers above). This: 55 |

    56 |
    fmt.Println(x)
    57 |

    58 | Means something like: 59 |

    60 |
    fmt.Println(  [BOX #1,001 -> BOX #1,011]  )
    61 |

    62 | Indeed before the advent of programming languages like Go, this is how 63 | programmers had to work with a computer. All that record keeping was tedious 64 | and error prone and the use of named variables with well defined types and 65 | scope rules makes it a whole lot easier to write software. 66 |

    67 |

    68 | The representation for Hello World we used above is an example 69 | of a type known as a string. In the next chapter we will discuss 70 | many different types. 71 |

    72 | 73 |

    Input and Output

    74 |

    75 | In the above example how does fmt.Println actually result in 76 | Hello World being displayed on the screen? 77 |

    78 |

    79 | Well this is really complex, but here's the basic idea: 80 |

    81 |
      82 |
    • 83 |

      84 | We know that Hello World is actually just a sequence of 85 | memory addresses (#1,000 - #1,011), so fmt.Println is 86 | given the starting address and a length 87 |

      88 |
    • 89 |
    • 90 |

      91 | If we look at the code for fmt.Println (available 92 | here), we see 93 | that it just calls fmt.Fprintln with os.Stdout. 94 |

      95 |
    • 96 |
    • 97 |

      98 | os.Stdout is a special file that represents the output of 99 | the terminal and we can write to it as if it were any other file. 100 |

      101 |
    • 102 |
    • 103 |

      104 | Writing to a file is done via a special mechanism known as a system call. 105 | System calls are implemented by our Operating System and when we make 106 | one we are transferring ownership to the Operating System for a specific 107 | purpose. Like the programs we write, the Operating System is itself a 108 | large program. 109 |

      110 |
    • 111 |
    • 112 |

      113 | Through a convoluted set of processes the character data we passed in 114 | (Hello World) is translated into a bitmap of pixel data. 115 | For example H might become this: 116 |

      117 | 118 |
    • 119 |
    • 120 |

      121 | That pixel data is then placed somewhere on a very large grid of pixel 122 | data. This large grid of data is sent to your display that then draws 123 | each pixel with the appropriate color. 124 |

      125 |

      126 | Crucially that large grid is itself stored as a big sequence of bytes 127 | in memory somewhere. Each pixel is probably represented by 3 bytes: 1 128 | byte for red, 1 byte for green and 1 byte for blue (RGB) and the 129 | combination of those primary colors allows us to make any color. 130 |

      131 |
    • 132 |
    133 | 134 |

    135 | Now, perhaps when you were first introduced to our Hello World 136 | program you had this question: "How exactly does a computer work anyway?", 137 | and you saw this chapter and thought: "Aww, here we go he's going to answer 138 | my question", and now having seen a brief description you're left more 139 | confused and with more question than when you started. You just wanted to 140 | know how fmt.Println worked, and now you want to know how 141 | stdout works, how system calls work, how text is converted into pixels, 142 | how your display renders pixels, etc... Haven't I just made the situation 143 | worse? 144 |

    145 |

    146 | I think the key here is that although learning the innate details of how 147 | computers work is useful, it is not necessary to know these things to 148 | program effectively. 149 |

    150 |

    151 | A large, complex machine like a computer is made up of thousands of 152 | components and fundamentally each component works the same way: it takes in data, 153 | processes it, and sends it out again. That data is in binary form - 1s and 154 | 0s or ons and offs - which are usually grouped together as byte-sized 155 | (8-bit) pieces. 156 |

    157 |

    158 | In order to understand one component it is only really necessary to 159 | understand the format of the input data it expects, how it processes that 160 | data and the format of the output data it generates. 161 |

    162 |

    163 | In our example, as long as we store Hello World in the format 164 | I described above, we can trust that fmt.Println will do the 165 | right thing. In turn fmt.Println can trust that 166 | fmt.Fprintln will do what it's supposed to do, and the OS 167 | write system call will do what it's supposed to do, and the OS can trust 168 | that whatever mechanism it uses to convert text data into pixels will do 169 | what it's supposed to do and so-on down the line. 170 |

    171 |

    172 | It would be impossible to write software without relying on abstractions. 173 | Any single program - when considered in its entirety - is 174 | simply far too complex to grasp exhaustively. Programming requires a great 175 | deal of knowledge (what we're covering in this book), but it also requires 176 | some degree of skill: productive programmers have learned the fine art of 177 | taking a complex system, breaking it down into easier-to-graps sub-systems 178 | and then whittling that collection of sub-systems into only the ones that 179 | actually matter, and ignoring all the rest. 180 |

    181 | 182 | 183 |

    Allocation

    184 | 185 | 186 |

    The Stored Program Computer

    187 |

    188 | One of the most fascinating things about a computer is that it not only 189 | stores data (like the string Hello World) in main memory, it 190 | also stores instructions there. 191 |

    192 |

    Clocks

    193 |

    194 | Let's look at a basic mechanical machine: a pendulum clock. 195 |

    196 |

    197 | A pendulum clock has a pendulum (a weight on a string) which swings back and 198 | forth due to the force of gravity. A physics formula describes how often 199 | that will occur, with the key property being that the period of a swing (how 200 | long it takes) is mostly independent of the angle it starts at. 201 |

    202 |

    203 | Through the use of an escapement the motion of the pendulum can be converted 204 | into fixed increments and then through the use of various gears attached to 205 | ticking hands those increments can be used to represent a human-readable 206 | clock face. 207 |

    208 |

    209 | In a sense the program underlying a clock has the same 3 210 | components all programs do: 211 |

    212 |
      213 |
    • 214 |

      215 | The input is the motion of the pendulum. 216 |

      217 |
    • 218 |
    • 219 |

      220 | The processesing is performed by all of the various gears and weights. 221 |

      222 |
    • 223 |
    • 224 |

      225 | The output is a visible clock-face that displays the current time. 226 |

      227 |
    • 228 |
    229 |

    230 | This program is defined in the language of mechnical machines: the layout 231 | and configuration of mechanical components according to the laws of physics. 232 | When properly configured the clock will show the correct time. 233 | So, in a sense, a clock-maker is a kind of programmer. 234 |

    235 |

    236 | The problem with a clock, like most machines, is that in order to change 237 | the program one would need to take it apart and rearrange all of its 238 | components. You would need bigger or smaller gears, more or less weight, 239 | a longer rod or a different kind of face. 240 |

    241 |

    242 | Early computers were programmed in a similar way: through the manipulation 243 | of tubes, switches and levers you could change what a computer would do 244 | when run. 245 |

    246 |

    247 | But what if you could create a program that runs other programs? 248 |

    249 | 250 | 251 | 252 | 253 | 256 | 259 | 262 | 263 |
    254 | ← Previous 255 | 257 | Index 258 | 260 | Next → 261 |
    264 |
    265 | -------------------------------------------------------------------------------- /templates/books/web/01-04.gohtml: -------------------------------------------------------------------------------- 1 |
    2 |

    Types

    3 |

    Integers

    4 |

    Floating Point Numbers

    5 |

    Strings

    6 |

    Booleans

    7 | 8 | 9 | 10 |

    Problems

    11 |
      12 |
    1. 13 |

      14 | Create a program that can convert the temperature in Fahrenheit to 15 | Celsius. 16 |

      17 |
    2. 18 |
    19 | 20 | 21 | 22 | 23 | 26 | 29 | 32 | 33 |
    24 | ← Previous 25 | 27 | Index 28 | 30 | Next → 31 |
    34 |
    35 | -------------------------------------------------------------------------------- /templates/books/web/02-01.gohtml: -------------------------------------------------------------------------------- 1 |
    2 |

    Protocols

    3 | 4 | 5 |

    Networks

    6 | 7 | 8 |

    TCP

    9 | 10 |
    11 |

    Problems

    12 |
      13 |
    1. 14 |

      15 | Create a TCP server named echo that repeats whatever is 16 | sent to it. 17 |

      18 |
    2. 19 |
    3. 20 |

      21 | Create a TCP server named rot13 that takes a line of 22 | text, applies a 23 | ROT-13 24 | transformation to it, and sends it back. 25 |

      26 |
    4. 27 |
    28 |
    29 | 30 | 31 |

    HTTP

    32 | 33 |
    34 |

    Problems

    35 |
      36 |
    1. 37 |

      38 | Create a TCP server that sends an HTTP Hello World 39 | response to the client. 40 |

      41 |
    2. 42 |
    43 |
    44 | 45 | 46 | 47 | 50 | 53 | 54 |
    48 | Index 49 | 51 | Next → 52 |
    55 |
    56 | -------------------------------------------------------------------------------- /templates/books/web/02-02.gohtml: -------------------------------------------------------------------------------- 1 |
    2 |

    The HTTP Package

    3 | 4 |

    Handlers

    5 |
    6 |

    Problems

    7 |
      8 |
    1. 9 |

      10 | Create a Hello World server using the 11 | net/http package. 12 |

      13 |
    2. 14 |
    15 |
    16 | 17 |

    Routing

    18 |
    19 |

    Problems

    20 |
      21 |
    1. 22 |

      23 | Create an HTTP server that returns Hello A when 24 | /a is visited and Hello B when 25 | /b is visited. 26 |

      27 |
    2. 28 |
    3. 29 |

      30 | Create an HTTP server that returns even when an 31 | even-numbered path is visited (/0, /2, 32 | /4, ...) and odd when an odd-numbered 33 | path is visited (/1, /3, /5, 34 | ...). 35 |

      36 |
    4. 37 |
    38 |
    39 | 40 |

    Forms

    41 |
    42 |

    Problems

    43 |
      44 |
    1. 45 |

      46 | Create an HTTP server that returns whatever is passed in as a query 47 | string parameter named data. For example when /?data=test 48 | is visited it would return test. 49 |

      50 |
    2. 51 |
    3. 52 |

      53 | Modify the previous server so that it also supports a form POST 54 | parameter. 55 |

      56 |
    4. 57 |
    5. 58 |

      59 | Create an HTTP server that implements a basic calculator which 60 | supports addition, multiplication, subtraction and division using 61 | some combination of paths, query string parameters or form values. For 62 | example: /add?x=1&y=2 for 1 + 2, 63 | returning 3. 64 |

      65 |
    6. 66 |
    67 |
    68 | 69 |

    Headers

    70 |
    71 |

    Problems

    72 |
      73 |
    1. 74 |

      75 | Create an HTTP server that redirects clients to another URL. 76 |

      77 |
    2. 78 |
    3. 79 |

      80 | Create an HTTP server that requires 81 | 82 | basic access authentication 83 | . 84 |

      85 |
    4. 86 |
    5. 87 |

      88 | Most HTTP clients support optional GZIP compression of responses via 89 | the Accept-Encoding header. Create an HTTP server that 90 | returns a GZIP-encoded response when this header is used. 91 |

      92 |
    6. 93 |
    94 |
    95 | 96 |

    Cookies

    97 |
    98 |
      99 |
    1. 100 | Create an HTTP server that uses a cookie to store a counter that is 101 | incremented each time a client visits the server and returns the current 102 | value of the counter. For example the 1st visit should display 103 | 1, the 2nd 2 and so on. (Assuming the client 104 | supports cookies) 105 |
    2. 106 |
    107 |
    108 | 109 | 110 | 111 | 114 | 117 | 120 | 121 |
    112 | ← Previous 113 | 115 | Index 116 | 118 | Next → 119 |
    122 |
    123 | -------------------------------------------------------------------------------- /templates/books/web/02-03.gohtml: -------------------------------------------------------------------------------- 1 |
    2 |

    Assets

    3 | 4 |

    Files

    5 |
    6 |

    Problems

    7 |
      8 |
    1. 9 |

      10 | Create an HTTP server that serves files relative to the current 11 | directory. 12 |

      13 |
    2. 14 |
    3. 15 |

      16 | Create an 17 |

    4. 18 |
    19 |
    20 | 21 |

    Templates

    22 |
    23 |

    Problems

    24 |
    25 | 26 | 27 | 28 | 31 | 34 | 37 | 38 |
    29 | ← Previous 30 | 32 | Index 33 | 35 | Next → 36 |
    39 |
    40 | -------------------------------------------------------------------------------- /templates/books/web/front.gohtml: -------------------------------------------------------------------------------- 1 |
    2 | 3 |

    Table of Contents

    4 |
      5 | {{range .Parts}} 6 |
    1. 7 | {{.Title}} 8 |
        9 | {{range .Chapters}} 10 |
      1. 11 | {{.Title}} 12 |
          13 | {{range .Sections}} 14 |
        1. 15 | {{.Title}} 16 |
        2. 17 | {{end}} 18 |
        19 |
      2. 20 | {{end}} 21 |
      22 |
    2. 23 | {{end}} 24 |
    3. Introduction 25 |
    4. 26 |
    5. Go Basics 27 |
    6. 28 |
    29 |
    30 | -------------------------------------------------------------------------------- /templates/books/web/layout.gohtml: -------------------------------------------------------------------------------- 1 | 8 | {{.Body}} 9 | 19 | -------------------------------------------------------------------------------- /templates/books/web/templates/templates.gohtml: -------------------------------------------------------------------------------- 1 | {{define ""}} 2 | -------------------------------------------------------------------------------- /templates/guides/02_bootcamp.gohtml: -------------------------------------------------------------------------------- 1 | 5 |
    6 |

    Go Web Programming Bootcamp

    7 |

    8 | The following videos were put together in July of 2015 for the 9 | Summer Web Bootcamp 10 | at Fresno City College. The videos cover the material in An Introduction 11 | to Programming in Go along with the basics of server-side web 12 | development with Go and Google App Engine. 13 |

    14 |

    15 | Thanks to the hard work of Todd McLeod (and others) these 16 | videos are available for free on Youtube. An outline is available at 17 | is.gd/gobootcamp. An additional 18 | outline is available 19 | here. 20 | Source code is available on 21 | Github. 22 | Questions, concerns or comments can be sent to 23 | Caleb Doxsey. 24 |

    25 | 26 |

    Links

    27 |
      28 |
    1. Week 1 29 |
        30 |
      1. Day 1: Machine Setup, Hello World, Variables, Types, A Deeper Look, Control Structures
      2. 31 |
      3. Day 2: Strings Revisited, Arrays, Slices and Maps, Functions
      4. 32 |
      5. Day 3: Review, Pointers, Structs and Interfaces
      6. 33 |
      7. Day 4
      8. 34 |
      9. Day 5
      10. 35 |
      36 |
    2. 37 |
    3. Week 2 38 |
        39 |
      1. Day 1
      2. 40 |
      3. Day 2
      4. 41 |
      5. Day 3
      6. 42 |
      7. Day 4
      8. 43 |
      9. Day 5
      10. 44 |
      45 |
    4. 46 |
    5. Week 3 47 |
        48 |
      1. Day 1: To-Do List, Twitter Clone, Data Store
      2. 49 |
      3. Day 2: Templates, Projection Queries, Email, Polling
      4. 50 |
      5. Day 3: Sort, Web, SQL
      6. 51 |
      7. Day 4: Long-Polling, App Engine Channels, Chat, Search
      8. 52 |
      9. Day 5: Search, Cloud Storage, Cloud API, URL Fetch
      10. 53 |
      54 |
    6. 55 |
    7. Week 4 56 |
        57 |
      1. Day 1: Markdown, Self-Destructing Messages, Side-Channel Attacks, Cloud Storage, Stocks, Net HTML
      2. 58 |
      3. Day 2: ChartJS, Credit Cards, OAuth, Dropbox OAuth, GitHub OAuth, GitHub, Task Queue
      4. 59 |
      60 |
    8. 61 |
    62 | 63 |

    64 | Most of the presented material is basically correct, though sometimes I 65 | wasn't very clear or made broad, general assertions, which are debatable but 66 | merely stated with no tip of the hat to a contrary point of view. These 67 | videos are intended for beginner instruction not technical perfection. 68 |

    69 |

    70 | Unfortunately I also made a few outright mistakes. Errata: 71 |

      72 |
    • I misinterpreted the meaning of Scanln, expecting it to read an 73 | entire line, when in fact it only reads to the first space.
    • 74 |
    • Permissions are used as octal, not hexadecimal. I showed one example 75 | using 0x777 when it should've been 0777.
    • 76 |
    • When discussing hashing I think I said "pairing bit", but meant 77 | "parity bit".
    • 78 |
    • At some point I said a for range loop on a string is byte by byte. 79 | Strings are stored as bytes, but the for range loop is actually rune 80 | by rune. It will interpret UTF8 for you.
    • 81 |
    82 |

    83 |
    84 | -------------------------------------------------------------------------------- /templates/guides/bootcamp/week-1/day-1.gohtml: -------------------------------------------------------------------------------- 1 | 6 |
    7 |

    Week 1, Day 1

    8 | 9 |

    Videos

    10 | 11 |
      12 |
    1. Part 1 (no content)
    2. 13 |
    3. Part 2: Introduction, Machine Setup
    4. 14 |
    5. Part 3: Background and Hello World
    6. 15 |
    7. Part 4: Go Commands and Hello World
    8. 16 |
    9. Part 5: Documentation, Variables
    10. 17 |
    11. Part 6A: Variables, Constants, Scope, Imports, Whitespace
    12. 18 |
    13. Part 6B
    14. 19 |
    15. Part 7: Miles to Kilometers
    16. 20 |
    17. Part 8: Q &amp; A
    18. 21 |
    19. Part 9: Types
    20. 22 |
    21. Part 10: Types, Numbers
    22. 23 |
    23. Part 11: Types, Strings
    24. 24 |
    25. Part 12: Control Structures
    26. 25 |
    27. Part 13: A Deeper Look
    28. 26 |
    27 | 28 |

    Outline

    29 |
      30 |
    1. 31 |

      Machine Setup

      32 | 35 |
    2. 36 |
    3. 37 |

      Hello World

      38 |
        39 |
      • Files & Folders
      • 40 |
      • Terminal
      • 41 |
      • Text Editor
      • 42 |
      • Hello World
      • 43 |
      • godoc
      • 44 |
      45 |

      Problems

      46 |
        47 |
      1. Create a program which prints “Hello World” to the terminal.
      2. 48 |
      3. What is whitespace?
      4. 49 |
      5. What is a comment? What are the two ways of writing a comment?
      6. 50 |
      7. Our program began with package main. What would the files in the fmt package begin with?
      8. 51 |
      9. We used the Println function defined in the fmt package. If we wanted to use the Exit function from the os package what would we need to do?
      10. 52 |
      11. Modify the program we wrote so that instead of printing Hello World it prints Hello, my name is followed by your name.
      12. 53 |
      54 |
    4. 55 |
    5. 56 |

      Variables

      57 |
        58 |
      • Samples
      • 59 |
      • Blank Identifiers
      • 60 |
      • Short Variable Declarations
      • 61 |
      • Assignment
      • 62 |
      • Zero Values
      • 63 |
      • Scope
      • 64 |
      • Constants
      • 65 |
      66 |

      Problems

      67 |
        68 |
      1. Create a program which prints “Hello <NAME>” with <NAME> replaced with your name to the terminal using a variable.
      2. 69 |
      3. Use fmt.Scanf to read a user’s name and print “Hello <NAME>” with <NAME> replaced with the user’s name to the terminal.
      4. 70 |
      5. Create a program which converts: 71 |
          72 |
        • Miles to Kilometers
        • 73 |
        • Fahrenheit to Celsius
        • 74 |
        • Pounds to Kilograms
        • 75 |
        76 |
      6. 77 |
      78 |
    6. 79 |
    7. 80 |

      Types

      81 |
        82 |
      • Integers
      • 83 |
      • Floating Point Numbers
      • 84 |
      • Strings
      • 85 |
      • Booleans
      • 86 |
      87 |

      Problems

      88 |
        89 |
      1. How are integers stored on a computer?
      2. 90 |
      3. We know that (in base 10) the largest 1 digit number is 9 and the largest 2 digit number is 99. Given that in binary the largest 2 digit number is 11 (3), the largest 3 digit number is 111 (7) and the largest 4 digit number is 1111 (15) what's the largest 8 digit number? (hint: 101-1 = 9 and 102-1 = 99)
      4. 91 |
      5. Although overpowered for the task you can use Go as a calculator. Write a program that computes 32132 × 42452 and prints it to the terminal. (Use the * operator for multiplication)
      6. 92 |
      7. What is a string? How do you find its length?
      8. 93 |
      9. What's the value of the expression (true && false) || (false && true) || !(false && false)?
      10. 94 |
      95 |
    8. 96 |
    9. 97 |

      A Deeper Look

      98 |
        99 |
      1. Memory
      2. 100 |
      3. Stack vs Heap
      4. 101 |
      102 |
    10. 103 |
    11. 104 |

      Control Structures

      105 |
        106 |
      1. For
      2. 107 |
      3. If
      4. 108 |
      5. Switch
      6. 109 |
      110 |

      Problems

      111 |
        112 |
      1. Write a program that prints out all the numbers evenly divisible by 3 between 1 and 100. (3, 6, 9, etc.)
      2. 113 |
      3. Write a program that prints the numbers from 1 to 100. But for multiples of three print "Fizz" instead of the number and for the multiples of five print "Buzz". For numbers which are multiples of both three and five print "FizzBuzz".
      4. 114 |
      115 |
    12. 116 |
    117 |
    118 | -------------------------------------------------------------------------------- /templates/guides/bootcamp/week-1/day-2.gohtml: -------------------------------------------------------------------------------- 1 | 6 |
    7 |

    Week 1, Day 2

    8 | 9 |

    Videos

    10 | 11 |
      12 |
    1. Part 1: Review (variables, types)
    2. 13 |
    3. Part 2: Review (types, control structures)
    4. 14 |
    5. Part 3: Review (control structures, continue/break)
    6. 15 |
    7. Part 4: Strings Revisited
    8. 16 |
    9. Part 5: Miles to Kilometers
    10. 17 |
    11. Part 6: Distance Converter
    12. 18 |
    13. Part 7: Arrays, Slices, Maps
    14. 19 |
    15. Part 8: Maps
    16. 20 |
    17. Part 9: Slice and Map Problems
    18. 21 |
    19. Part 10: Functions
    20. 22 |
    21. Part 11: Functions
    22. 23 |
    23. Part 12: Functions
    24. 24 |
    25. Part 13: Closure, Defer, Recursion
    26. 25 |
    27. Part 14: Recursion
    28. 26 |
    29. Part 15: Recursion
    30. 27 |
    28 | 29 |

    Outline

    30 |
      31 |
    1. 32 |

      Strings Revisited

      33 |
        34 |
      • Immutability
      • 35 |
      • strings
      • 36 |
      • strconv
      • 37 |
      • Command line arguments
      • 38 |
      39 |

      Problems

      40 |
        41 |
      1. Modify our miles to kilometers program to display in the following format: 42 |
         43 | +-------------------------+
         44 | | Miles: 50               |
         45 | +-------------------------+
         46 | | Kilometers: 80.47       |
         47 | +-------------------------+
         48 | 
        49 | Miles will be input by the user, and kilometers should be formatted to 2 decimal places.
      2. 50 |
      3. Modify the above program so that it generates HTML instead of text. For example: 51 |
         52 | <!DOCTYPE html>
         53 | <html>
         54 | 	<head></head>
         55 | 	<body>
         56 | 		Miles: 50<br>
         57 | 		Kilometers: 80.47
         58 | 	</body>
         59 | </html>
         60 | 
        61 | Feel free to use any HTML tags and CSS you may know.
      4. 62 |
      5. Create a program which parses a query to do distance conversions. For example, from a terminal:
      6. 63 |
        $ distance_converter 50mi km
        64 | Should produce: 65 |
        80.47km
        66 | It should support miles (mi), kilometers (km), feet (ft) and meters (m). 67 |
      7. One classic method for composing secret messages is called a square code. The spaces are removed from the english text and the characters are written into a square (or rectangle). For example, the sentence "If man was meant to stay on the ground god would have given us roots" is 54 characters long, so it is written into a rectangle with 7 rows and 8 columns. 68 |
         69 | ifmanwas
         70 | meanttos
         71 | tayonthe
         72 | groundgo
         73 | dwouldha
         74 | vegivenu
         75 | sroots
        76 | The coded message is obtained by reading down the columns going left to right. For example, the message above is coded as: 77 |
        imtgdvs fearwer mayoogo anouuio ntnnlvt wttddes aohghn sseoau
        78 | In your program, have the user enter a message in english with no spaces between the words. Have the maximum message length be 81 characters. Display the encoded message. (Watch out that no "garbage" characters are printed.) Here are some more examples: 79 |
         80 | Input                                 Output
         81 | haveaniceday                          hae and via ecy
         82 | feedthedog                            fto ehg ee  dd
         83 | chillout                              clu hlt io
        84 |
      8. 85 |
      86 |
    2. 87 |
    3. 88 |

      Arrays, Slices and Maps

      89 |
        90 |
      • Arrays
      • 91 |
      • Slices
      • 92 |
      • Maps
      • 93 |
      94 |

      Problems

      95 |
        96 |
      1. How do you access the 4th element of an array or slice?
      2. 97 |
      3. What is the length of a slice created using: make([]int, 3, 9)?
      4. 98 |
      5. Given the array: 99 |
        x := [6]string{"a","b","c","d","e","f"}
        100 | what would x[2:5] give you? 101 |
      6. 102 |
      7. Write a program that finds the smallest number in this list: 103 |
        x := []int{
        104 | 	48,96,86,68,
        105 | 	57,82,63,70,
        106 | 	37,34,83,27,
        107 | 	19,97, 9,17,
        108 | }
        109 |
      8. 110 |
      9. Write a program that takes in a state code and returns the state’s name. (eg CA -> California)
      10. 111 |
      112 |
    4. 113 |
    5. 114 |

      Functions

      115 |
        116 |
      • Functions
      • 117 |
      • Multiple Return Values
      • 118 |
      • Variadic Functions
      • 119 |
      • Closure
      • 120 |
      • Recursion
      • 121 |
      • Panic & Recover
      • 122 |
      123 |

      Problems

      124 |
        125 |
      1. sum is a function which takes a slice of numbers and adds them together. What would its function signature look like in Go?
      2. 126 |
      3. Implement the sum function
      4. 127 |
      5. Write a function which takes an integer and halves it and returns true if it was even or false if it was odd. For example half(1) should return (0, false) and half(2) should return (1, true).
      6. 128 |
      7. Write a function with one variadic parameter that finds the greatest number in a list of numbers.
      8. 129 |
      9. Using makeEvenGenerator as an example, write a makeOddGenerator function that generates odd numbers.
      10. 130 |
      11. The Fibonacci sequence is defined as: 131 |
        fib(0) = 0, fib(1) = 1, fib(n) = fib(n-1) + fib(n-2)
        . 132 | Write a recursive function which can find fib(n).
      12. 133 |
      13. What are defer, panic and recover? How do you recover from a run-time panic?
      14. 134 |
      15. Create a function which reverses a list of integers: 135 |
        reverse([]int{1,2,3}) → []int{3,2,1}
        136 |
      16. 137 |
      138 |
    6. 139 |
    140 |
    141 | -------------------------------------------------------------------------------- /templates/guides/bootcamp/week-1/day-3.gohtml: -------------------------------------------------------------------------------- 1 | 6 |
    7 |

    Week 1, Day 3

    8 | 9 |

    Videos

    10 | 11 |
      12 |
    1. Part 1: Review, Go → Javascript, Gravatar
    2. 13 |
    3. Part 2: Stderr
    4. 14 |
    5. Part 3: Gravatar Profiles cont'd, Go Tour, Word Count
    6. 15 |
    7. Part 4: Word Count solution
    8. 16 |
    9. Part 5: Count Clumps
    10. 17 |
    11. Part 6: Count Clumps cont'd
    12. 18 |
    13. Part 7: Pointers
    14. 19 |
    15. Part 8: Pointers cont'd
    16. 20 |
    17. Part 9: Swap, Rotate,
    18. 21 |
    19. Part 10: Structs
    20. 22 |
    21. Part 11: Structs cont'd
    22. 23 |
    23. Part 12: Embedded Types, Interfaces
    24. 24 |
    25. Part 13: Interfaces cont'd
    26. 25 |
    26 | 27 |

    Outline

    28 |
      29 |
    1. 30 |

      Review

      31 |
        32 |
      • Create Javascript Cheat Sheet: is.gd/XaJQal.
      • 33 |
      • Pair-program on problems
      • 34 |
      35 |

      Problems

      36 |
        37 |
      1. Create a program which reads user information (at least name and 38 | email) and creates a profile page in HTML. Also use or generate a 39 | profile image from gravatar.com.
      2. 40 |
      3. Implement WordCount. It should return a map of the counts of each 41 | “word” in a string. (You might find strings.Fields 42 | helpful.) WordCount("test test") → 43 | map[string]int{ "test": 2 }
      4. 44 |
      5. Implement a centeredAverage function that computes the 45 | average of a list of numbers, but removes the largest and smallest 46 | values. centeredAverage([]float64{1, 2, 3, 4, 100}) → 47 | 3
      6. 48 |
      7. Given a non-empty list, return true if there is a place to split the 49 | list so that the sum of the numbers on one side is equal to the sum of 50 | the numbers on the other side.
        51 | canBalance([]int{1, 1, 1, 2, 1})true
        52 | canBalance([]int{2, 1, 1, 2, 1})false
        53 | canBalance([]int{10, 10})true
      8. 54 |
      9. Say that a "clump" in a list is a series of 2 or more adjacent 55 | elements of the same value. Return the number of clumps in the given 56 | list.
        57 | countClumps([]int{1, 2, 2, 3, 4, 4})2
        58 | countClumps([]int{1, 1, 2, 1, 1})2
        59 | countClumps([]int{1, 1, 1, 1, 1})1
      10. 60 |
      61 |
    2. 62 |
    3. 63 |

      Pointers

      64 |
        65 |
      • * and &
      • 66 |
      • new
      • 67 |
      • Scan
      • 68 |
      69 |

      Problems

      70 |
        71 |
      1. How do you get the memory address of a variable?
      2. 72 |
      3. How do you assign a value to a pointer?
      4. 73 |
      5. How do you create a new pointer?
      6. 74 |
      7. What is the value of x after running this program: 75 |
         76 | func square(x *float64) {
         77 | 	*x = *x * *x
         78 | }
         79 | func main() {
         80 | 	x := 1.5
         81 | 	square(&x)
         82 | }
         83 | 
        84 |
      8. 85 |
      9. Write a program that can swap two integers ( 86 | x := 1; y := 2; swap(&x, &y) should 87 | give you x==2 and y==1).
      10. 88 |
      11. Generalize swap into a rotate function so that it works with any 89 | number of variables: rotate(&x, &y, &z), with 90 | x=1, y=2, y=3, yields 91 | x=2, y=3, z=1.
      12. 92 |
      13. Create a rotateRight function which does the same thing as rotate 93 | but in the other direction.
      14. 94 |
      95 |
    4. 96 |
    5. 97 |

      Structs and Interfaces

      98 |
        99 |
      • Structs
      • 100 |
      • Initialization
      • 101 |
      • Fields
      • 102 |
      • Methods
      • 103 |
      • Embedded Types
      • 104 |
      105 |

      Problems

      106 |
        107 |
      1. What's the difference between a method and a function?
      2. 108 |
      3. Why would you use an embedded anonymous field instead of a normal 109 | named field?
      4. 110 |
      5. Add a new method to the Shape interface called perimeter which 111 | calculates the perimeter of a shape. Implement the method for Circle 112 | and Rectangle.
      6. 113 |
      114 |
    6. 115 |
    116 |
    117 | -------------------------------------------------------------------------------- /templates/guides/bootcamp/week-1/day-4.gohtml: -------------------------------------------------------------------------------- 1 | 6 |
    7 |

    Week 1, Day 4

    8 | 9 |

    Videos

    10 | 11 |
      12 |
    1. Part 1
    2. 13 |
    3. Part 2
    4. 14 |
    5. Part 3
    6. 15 |
    7. Part 4
    8. 16 |
    9. Part 5
    10. 17 |
    11. Part 6
    12. 18 |
    13. Part 7
    14. 19 |
    15. Part 8
    16. 20 |
    17. Part 9
    18. 21 |
    19. Part 10
    20. 22 |
    21. Part 11
    22. 23 |
    24 |
    25 | -------------------------------------------------------------------------------- /templates/guides/bootcamp/week-1/day-5.gohtml: -------------------------------------------------------------------------------- 1 | 6 |
    7 |

    Week 1, Day 5

    8 | 9 |

    Videos

    10 | 11 |
      12 |
    1. Part 2
    2. 13 |
    3. Part 3
    4. 14 |
    5. Part 4
    6. 15 |
    7. Part 6
    8. 16 |
    9. Part 7
    10. 17 |
    11. Part 8
    12. 18 |
    13. Part 9
    14. 19 |
    15. Part 10
    16. 20 |
    17. Part 11
    18. 21 |
    22 |
    23 | -------------------------------------------------------------------------------- /templates/guides/bootcamp/week-2/day-1.gohtml: -------------------------------------------------------------------------------- 1 | 6 |
    7 |

    Week 2, Day 1

    8 | 9 |

    Videos

    10 | 11 |
      12 |
    1. Part 1
    2. 13 |
    3. Part 2
    4. 14 |
    5. Part 3
    6. 15 |
    7. Part 4
    8. 16 |
    9. Part 5
    10. 17 |
    11. Part 6
    12. 18 |
    13. Part 7
    14. 19 |
    15. Part 8
    16. 20 |
    17. Part 9
    18. 21 |
    19. Part 10
    20. 22 |
    23 |
    24 | -------------------------------------------------------------------------------- /templates/guides/bootcamp/week-2/day-2.gohtml: -------------------------------------------------------------------------------- 1 | 6 |
    7 |

    Week 2, Day 2

    8 | 9 |

    Videos

    10 | 11 |
      12 |
    1. Part 1
    2. 13 |
    3. Part 2
    4. 14 |
    5. Part 3
    6. 15 |
    7. Part 4
    8. 16 |
    9. Part 5
    10. 17 |
    11. Part 6
    12. 18 |
    13. Part 7
    14. 19 |
    15. Part 8
    16. 20 |
    17. Part 9
    18. 21 |
    22 |
    23 | -------------------------------------------------------------------------------- /templates/guides/bootcamp/week-2/day-3.gohtml: -------------------------------------------------------------------------------- 1 | 6 |
    7 |

    Week 2, Day 3

    8 | 9 |

    Videos

    10 | 11 |
      12 |
    1. Part 1
    2. 13 |
    3. Part 2
    4. 14 |
    5. Part 3
    6. 15 |
    7. Part 4
    8. 16 |
    9. Part 5
    10. 17 |
    11. Part 6
    12. 18 |
    13. Part 7
    14. 19 |
    20 |
    21 | -------------------------------------------------------------------------------- /templates/guides/bootcamp/week-2/day-4.gohtml: -------------------------------------------------------------------------------- 1 | 6 |
    7 |

    Week 2, Day 4

    8 | 9 |

    Videos

    10 | 11 |
      12 |
    1. Part 1
    2. 13 |
    3. Part 2
    4. 14 |
    5. Part 3
    6. 15 |
    7. Part 4
    8. 16 |
    9. Part 5
    10. 17 |
    11. Part 6
    12. 18 |
    13. Part 7
    14. 19 |
    15. Part 8
    16. 20 |
    17. Part 9
    18. 21 |
    19. Part 10
    20. 22 |
    23 |
    24 | -------------------------------------------------------------------------------- /templates/guides/bootcamp/week-2/day-5.gohtml: -------------------------------------------------------------------------------- 1 | 6 |
    7 |

    Week 2, Day 5

    8 | 9 |

    Videos

    10 | 11 |
      12 |
    1. Part 1
    2. 13 |
    3. Part 2
    4. 14 |
    5. Part 3
    6. 15 |
    7. Part 4
    8. 16 |
    9. Part 5
    10. 17 |
    11. Part 6
    12. 18 |
    19 |
    20 | -------------------------------------------------------------------------------- /templates/guides/bootcamp/week-3/day-1.gohtml: -------------------------------------------------------------------------------- 1 | 6 |
    7 |

    Week 3, Day 1

    8 | 9 |

    Videos

    10 | 11 |
      12 |
    1. Part 1: To-Do List
    2. 13 |
    3. Part 2: To-Do List cont'd
    4. 14 |
    5. Part 3: Twitter Clone
    6. 15 |
    7. Part 4: Data Store
    8. 16 |
    17 |
    18 | -------------------------------------------------------------------------------- /templates/guides/bootcamp/week-3/day-2.gohtml: -------------------------------------------------------------------------------- 1 | 6 | 19 | -------------------------------------------------------------------------------- /templates/guides/bootcamp/week-3/day-3.gohtml: -------------------------------------------------------------------------------- 1 | 6 |
    7 |

    Week 3, Day 3

    8 | 9 |

    Videos

    10 | 11 |
      12 |
    1. Part 1: Sort
    2. 13 |
    3. Part 2: Web
    4. 14 |
    5. Part 3: SQL
    6. 15 |
    16 |
    17 | -------------------------------------------------------------------------------- /templates/guides/bootcamp/week-3/day-4.gohtml: -------------------------------------------------------------------------------- 1 | 6 |
    7 |

    Week 3, Day 4

    8 | 9 | 10 |

    Videos

    11 | 12 |
      13 |
    1. Part 1: Long Polling
    2. 14 |
    3. Part 2: App Engine Channel
    4. 15 |
    5. Part 3: Chat
    6. 16 |
    7. Part 4: App Engine Chat
    8. 17 |
    9. Part 5: App Engine Search
    10. 18 |
    19 |
    20 | -------------------------------------------------------------------------------- /templates/guides/bootcamp/week-3/day-5.gohtml: -------------------------------------------------------------------------------- 1 | 6 |
    7 |

    Week 3, Day 5

    8 | 9 |

    Videos

    10 | 11 |
      12 |
    1. Part 1: Search
    2. 13 |
    3. Part 2: Cloud Storage
    4. 14 |
    5. Part 3: Cloud Storage cont'd
    6. 15 |
    7. Part 4: Cloud Storage cont'd
    8. 16 |
    9. Part 5: Cloud API
    10. 17 |
    11. Part 5: URL Fetch
    12. 18 |
    19 |
    20 | -------------------------------------------------------------------------------- /templates/guides/bootcamp/week-4/day-1.gohtml: -------------------------------------------------------------------------------- 1 | 6 | 23 | -------------------------------------------------------------------------------- /templates/guides/bootcamp/week-4/day-2.gohtml: -------------------------------------------------------------------------------- 1 | 6 |
    7 |

    Week 4, Day 2

    8 | 9 |

    Videos

    10 | 11 |
      12 |
    1. Part 1: ChartJS
    2. 13 |
    3. Part 2: Credit Cards
    4. 14 |
    5. Part 3: Credit Cards cont'd
    6. 15 |
    7. Part 4: OAuth
    8. 16 |
    9. Part 5: Dropbox OAuth
    10. 17 |
    11. Part 6: GitHub OAuth
    12. 18 |
    13. Part 7: GitHub
    14. 19 |
    15. Part 8: Task Queue
    16. 20 |
    21 |
    22 | -------------------------------------------------------------------------------- /templates/guides/layout.gohtml: -------------------------------------------------------------------------------- 1 | {{.Body}} 2 | 7 | -------------------------------------------------------------------------------- /templates/index.gohtml: -------------------------------------------------------------------------------- 1 |
    2 |

    Go Resources

    3 |

    Books

    4 |
    5 | 6 |
    7 |
    An Introduction to Programming in Go
    8 |
    9 | A short, concise introduction to computer programming using the language 10 | Go. Designed by Google, Go is a general purpose programming language with 11 | modern features, clean syntax and a robust well-documented common library, 12 | making it an ideal language to learn as your first programming language. 13 |
    14 |
    15 |
    16 |
    17 | 18 |
    19 |
    Introducing Go
    20 |
    21 | Perfect for beginners familiar with programming basics, this hands-on 22 | guide provides an easy introduction to Go, the general-purpose 23 | programming language from Google. Author Caleb Doxsey covers the 24 | language’s core features with step-by-step instructions and exercises 25 | in each chapter to help you practice what you learn. 26 |
    27 |
    28 |
    29 | 30 |

    Guides

    31 |
      32 |
    1. Machine Setup 33 |
        34 |
      1. Windows
      2. 35 |
      3. OSX
      4. 36 |
      37 |
    2. 38 |
    3. Go Concurrency from the Ground Up 39 |
        40 |
      • Learn about Go's concurrency features by implementing them in another programming language.
      • 41 |
      42 |
    4. 43 |
    5. Bootcamp 44 |
        45 |
      • A 4-week instructional series that covers the material in 46 | An Introduction to Programming in Go as well as the basics of 47 | server-side web development and Google App Engine.
      • 48 |
      49 |
    6. 50 |
    51 |
    52 | 57 | -------------------------------------------------------------------------------- /templates/layout.gohtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{if .Title}}{{.Title}} | {{end}}Go Resources 5 | 6 | 7 | 8 | 9 | 10 | 11 |
    12 | {{.Body}} 13 |
    14 | 15 | 16 | 17 | --------------------------------------------------------------------------------