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