OSDN Git Service

Regular updates
[twpd/master.git] / go.md
1 ---
2 title: Go
3 layout: 2017/sheet
4 prism_languages: [go, bash]
5 weight: -3
6 tags: [Featured]
7 category: C-like
8 updated: 2017-09-15
9 ---
10
11 ## Getting started
12 {: .-three-column}
13
14 ### Hello world
15 {: .-prime}
16
17 #### hello.go
18 {: .-file}
19
20 ```go
21 package main
22
23 import "fmt"
24
25 func main() {
26   message := greetMe("world")
27   fmt.Println(message)
28 }
29
30 func greetMe(name string) string {
31   return "Hello, " + name + "!"
32 }
33 ```
34
35 ```bash
36 $ go build
37 ```
38
39 Or try it out in the [Go repl](https://repl.it/languages/go), or [A Tour of Go](https://tour.golang.org/welcome/1).
40
41 ### Variables
42
43 #### Variable declaration
44
45 ```go
46 var msg string
47 msg = "Hello"
48 ```
49
50 #### Shortcut of above (Infers type)
51
52 ```go
53 msg := "Hello"
54 ```
55
56 ### Constants
57
58 ```go
59 const Phi = 1.618
60 ```
61
62 Constants can be character, string, boolean, or numeric values.
63
64 See: [Constants](https://tour.golang.org/basics/15)
65
66 ## Basic types
67 {: .-three-column}
68
69 ### Strings
70
71 ```go
72 str := "Hello"
73 ```
74
75 ```go
76 str := `Multiline
77 string`
78 ```
79
80 Strings are of type `string`.
81
82 ### Numbers
83
84 #### Typical types
85
86 ```go
87 num := 3          // int
88 num := 3.         // float64
89 num := 3 + 4i     // complex128
90 num := byte('a')  // byte (alias for uint8)
91 ```
92
93 #### Other types
94
95 ```go
96 var u uint = 7        // uint (unsigned)
97 var p float32 = 22.7  // 32-bit float
98 ```
99
100 ### Arrays
101
102 ```go
103 // var numbers [5]int
104 numbers := [...]int{0, 0, 0, 0, 0}
105 ```
106
107 Arrays have a fixed size.
108
109 ### Slices
110
111 ```go
112 slice := []int{2, 3, 4}
113 ```
114
115 ```go
116 slice := []byte("Hello")
117 ```
118
119 Slices have a dynamic size, unlike arrays.
120
121 ### Pointers
122
123 ```go
124 func main () {
125   b := *getPointer()
126   fmt.Println("Value is", b)
127 }
128 ```
129 {: data-line="2"}
130
131 ```go
132 func getPointer () (myPointer *int) {
133   a := 234
134   return &a
135 }
136 ```
137 {: data-line="3"}
138
139 Pointers point to a memory location of a variable. Go is fully garbage-collected.
140
141 See: [Pointers](https://tour.golang.org/moretypes/1)
142
143 ### Type conversions
144
145 ```go
146 i := 2
147 f := float64(i)
148 u := uint(i)
149 ```
150
151 See: [Type conversions](https://tour.golang.org/basics/13)
152
153 ## Flow control
154 {: .-three-column}
155
156 ### Conditional
157
158 ```go
159 if day == "sunday" || day == "saturday" {
160   rest()
161 } else if day == "monday" && isTired() {
162   groan()
163 } else {
164   work()
165 }
166 ```
167 {: data-line="1,3,5"}
168
169 See: [If](https://tour.golang.org/flowcontrol/5)
170
171 ### Statements in if
172
173 ```go
174 if _, err := getResult(); err != nil {
175   fmt.Println("Uh oh")
176 }
177 ```
178 {: data-line="1"}
179
180 A condition in an `if` statement can be preceded with a statement before a `;`.
181
182 See: [If with a short statement](https://tour.golang.org/flowcontrol/6)
183
184 ### Switch
185
186 ```go
187 switch day {
188   case "sunday":
189     // cases don't "fall through" by default!
190     fallthrough
191
192   case "saturday":
193     rest()
194
195   default:
196     work()
197 }
198 ```
199
200 See: [Switch](https://github.com/golang/go/wiki/Switch)
201
202 ### For loop
203
204 ```go
205 for count := 0; count <= 10; count++ {
206   fmt.Println("My counter is at", count)
207 }
208 ```
209
210 See: [For loops](https://tour.golang.org/flowcontrol/1)
211
212 ### For-Range loop
213
214 ```go
215 entry := []string{"Jack","John","Jones"}
216 for i, val := range entry {
217   fmt.Printf("At position %d, the character %s is present\n", i, val)
218 }
219 ```
220
221 See: [For-Range loops](https://gobyexample.com/range)
222
223 ## Functions
224 {: .-three-column}
225
226 ### Lambdas
227
228 ```go
229 myfunc := func() bool {
230   return x > 10000
231 }
232 ```
233 {: data-line="1"}
234
235 Functions are first class objects.
236
237 ### Multiple return types
238
239 ```go
240 a, b := getMessage()
241 ```
242
243 ```go
244 func getMessage() (a string, b string) {
245   return "Hello", "World"
246 }
247 ```
248 {: data-line="2"}
249
250
251 ### Named return values
252
253 ```go
254 func split(sum int) (x, y int) {
255   x = sum * 4 / 9
256   y = sum - x
257   return
258 }
259 ```
260 {: data-line="4"}
261
262 By defining the return value names in the signature, a `return` (no args) will return variables with those names.
263
264 See: [Named return values](https://tour.golang.org/basics/7)
265
266 ## Packages
267 {: .-three-column}
268
269 ### Importing
270
271 ```go
272 import "fmt"
273 import "math/rand"
274 ```
275
276 ```go
277 import (
278   "fmt"        // gives fmt.Println
279   "math/rand"  // gives rand.Intn
280 )
281 ```
282
283 Both are the same.
284
285 See: [Importing](https://tour.golang.org/basics/1)
286
287 ### Aliases
288
289 ```go
290 import r "math/rand"
291 ```
292 {: data-line="1"}
293
294 ```go
295 r.Intn()
296 ```
297
298 ### Exporting names
299
300 ```go
301 func Hello () {
302   ···
303 }
304 ```
305
306 Exported names begin with capital letters.
307
308 See: [Exported names](https://tour.golang.org/basics/3)
309
310 ### Packages
311
312 ```go
313 package hello
314 ```
315
316 Every package file has to start with `package`.
317
318 ## Concurrency
319 {: .-three-column}
320
321 ### Goroutines
322
323 ```go
324 func main() {
325   // A "channel"
326   ch := make(chan string)
327
328   // Start concurrent routines
329   go push("Moe", ch)
330   go push("Larry", ch)
331   go push("Curly", ch)
332
333   // Read 3 results
334   // (Since our goroutines are concurrent,
335   // the order isn't guaranteed!)
336   fmt.Println(<-ch, <-ch, <-ch)
337 }
338 ```
339 {: data-line="3,6,7,8,13"}
340
341 ```go
342 func push(name string, ch chan string) {
343   msg := "Hey, " + name
344   ch <- msg
345 }
346 ```
347 {: data-line="3"}
348
349 Channels are concurrency-safe communication objects, used in goroutines.
350
351 See: [Goroutines](https://tour.golang.org/concurrency/1), [Channels](https://tour.golang.org/concurrency/2)
352
353 ### Buffered channels
354
355 ```go
356 ch := make(chan int, 2)
357 ch <- 1
358 ch <- 2
359 ch <- 3
360 // fatal error:
361 // all goroutines are asleep - deadlock!
362 ```
363 {: data-line="1"}
364
365 Buffered channels limit the amount of messages it can keep.
366
367 See: [Buffered channels](https://tour.golang.org/concurrency/3)
368
369 ### Closing channels
370
371 #### Closes a channel
372
373 ```go
374 ch <- 1
375 ch <- 2
376 ch <- 3
377 close(ch)
378 ```
379 {: data-line="4"}
380
381 #### Iterates across a channel until its closed
382
383 ```go
384 for i := range ch {
385   ···
386 }
387 ```
388 {: data-line="1"}
389
390 #### Closed if `ok == false`
391
392 ```go
393 v, ok := <- ch
394 ```
395
396 See: [Range and close](https://tour.golang.org/concurrency/4)
397
398 ## Error control
399
400 ### Defer
401
402 ```go
403 func main() {
404   defer fmt.Println("Done")
405   fmt.Println("Working...")
406 }
407 ```
408 {: data-line="2"}
409
410 Defers running a function until the surrounding function returns.
411 The arguments are evaluated immediately, but the function call is not ran until later.
412
413 See: [Defer, panic and recover](https://blog.golang.org/defer-panic-and-recover)
414
415 ### Deferring functions
416
417 ```go
418 func main() {
419   defer func() {
420     fmt.Println("Done")
421   }()
422   fmt.Println("Working...")
423 }
424 ```
425
426 {: data-line="2,3,4"}
427
428 Lambdas are better suited for defer blocks.
429
430 ```go
431 func main() {
432   var d = int64(0)
433   defer func(d *int64) {
434     fmt.Printf("& %v Unix Sec\n", *d)
435   }(&d)
436   fmt.Print("Done ")
437   d = time.Now().Unix()
438 }
439 ```
440 {: data-line="3,4,5"}
441 The defer func uses current value of d, unless we use a pointer to get final value at end of main.
442
443 ## Structs
444 {: .-three-column}
445
446 ### Defining
447
448 ```go
449 type Vertex struct {
450   X int
451   Y int
452 }
453 ```
454 {: data-line="1,2,3,4"}
455
456 ```go
457 func main() {
458   v := Vertex{1, 2}
459   v.X = 4
460   fmt.Println(v.X, v.Y)
461 }
462 ```
463
464 See: [Structs](https://tour.golang.org/moretypes/2)
465
466 ### Literals
467
468 ```go
469 v := Vertex{X: 1, Y: 2}
470 ```
471
472 ```go
473 // Field names can be omitted
474 v := Vertex{1, 2}
475 ```
476
477 ```go
478 // Y is implicit
479 v := Vertex{X: 1}
480 ```
481
482 You can also put field names.
483
484 ### Pointers to structs
485
486 ```go
487 v := &Vertex{1, 2}
488 v.X = 2
489 ```
490
491 Doing `v.X` is the same as doing `(*v).X`, when `v` is a pointer.
492
493 ## Methods
494
495 ### Receivers
496
497 ```go
498 type Vertex struct {
499   X, Y float64
500 }
501 ```
502
503 ```go
504 func (v Vertex) Abs() float64 {
505   return math.Sqrt(v.X * v.X + v.Y * v.Y)
506 }
507 ```
508 {: data-line="1"}
509
510 ```go
511 v: = Vertex{1, 2}
512 v.Abs()
513 ```
514
515 There are no classes, but you can define functions with _receivers_.
516
517 See: [Methods](https://tour.golang.org/methods/1)
518
519 ### Mutation
520
521 ```go
522 func (v *Vertex) Scale(f float64) {
523   v.X = v.X * f
524   v.Y = v.Y * f
525 }
526 ```
527 {: data-line="1"}
528
529 ```go
530 v := Vertex{6, 12}
531 v.Scale(0.5)
532 // `v` is updated
533 ```
534
535 By defining your receiver as a pointer (`*Vertex`), you can do mutations.
536
537 See: [Pointer receivers](https://tour.golang.org/methods/4)
538
539 ## References
540
541 - [A tour of Go](https://tour.golang.org/welcome/1) _(tour.golang.org)_
542 - [Golang wiki](https://github.com/golang/go/wiki/) _(github.com)_
543 - [Awesome Go](https://awesome-go.com/) _(awesome-go.com)_
544 - [Go by Example](https://gobyexample.com/) _(gobyexample.com)_
545 - [Effective Go](https://golang.org/doc/effective_go.html) _(golang.org)_
546 - [JustForFunc Youtube](https://www.youtube.com/channel/UC_BzFbxG2za3bp5NRRRXJSw) _(youtube.com)_
547 - [Style Guide](https://github.com/golang/go/wiki/CodeReviewComments) _(github.com)_