-
Notifications
You must be signed in to change notification settings - Fork 26
/
introduction-to-go.slide.bak
1813 lines (1034 loc) · 56.8 KB
/
introduction-to-go.slide.bak
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
Introduction to Go
Tokyo, Japan
10 Dec 2016
Dave Cheney
http://dave.cheney.net/
@davecheney
* License and Materials
This presentation is licensed under the [[https://creativecommons.org/licenses/by-sa/4.0/][Creative Commons Attribution-ShareAlike 4.0 International]] licence.
The materials for this presentation are available on GitHub:
.link https://github.com/davecheney/introduction-to-go
You are encouraged to remix, transform, or build upon the material, providing you give appropriate credit and distribute your contributions under the same license.
If you have suggestions or corrections to this presentation, please raise [[https://github.com/davecheney/introduction-to-go/isues][an issue on the GitHub project]].
* Agenda
This workshop is aimed at programmers with experience in another programming language and want to learn how to apply their skills to Go.
This workshop consists of five main sections:
- Basic Syntax
- Advanced Syntax
- Development environment and tooling
- The standard library
- Packages and applications
After each section we'll have time for questions.
As we work through the day there will be less of me talking, and more exercises to help you learn Go via doing.
* The Go programming language
- Modern
- Compact, concise, general-purpose
- Imperative, statically type-checked, dynamically type-safe
- Garbage-collected
- Compiles to native code, statically linked
- Fast compilation, efficient execution
Designed by programmers for programmers!
.link https://talks.golang.org/2014/taste.slide#2 Source: Robert Griesemer, A Taste of Go.
* Speed
Go is often noted for its fast compilation, but this is only one facet of the idea of Go being a _fast_ language to program in.
"False dichotomy of static languages being 'slow and painful' and dynamic languages being 'fast and fun'" -Rob Pike
"Clumsy type systems drive people to dynamically typed languages" -Robert Griesemer
Go is an attempt to demonstrate that a language can be both fast in terms of the programs it produces and fast (productive?) for the authors.
* Safety
- Typed, and type safe
var i int = -1
var u uint = 200
i = u // nope, incompatible types
- Array accesses are bounds checked
s := make([]string, 10)
x := s[20] // will panic at runtime
- All memory is zeroed if not explicitly initialised
var q int // initialised to 0
var f = 7 // initialised to 7, type defaults to int
- No implicit conversions; booleans and integers are not aliases
i := 2
if i { ... } // nope, no coercion to bool
* Good support for concurrency and communication
- Multicore CPUs are a reality.
- Multiprocessing is not a solution.
- Networking support baked into the standard library, integrated into the runtime.
* Garbage collected
Go is a garbage collected language.
- Eliminates the bookkeeping errors related to ownership of shared values.
- Eliminates an entire class of use after free and memory leak bugs.
- Enables simpler, cleaner, APIs.
The garbage collector handles heaps into the 100's of GB range, and is designed for extremely low "stop the world" pauses.
In Go 1.7 these pauses are now less than 100 microseconds.
* Opinionated
Go is an opinionated language.
- Unused local variables are an error.
- Unused imports are also an error.
- The compiler does not issue warnings, only errors.
- A single way to format code as defined by `go`fmt`.
* Hello, http!
.play -edit src/hellohttp/hellohttp.go
* Basic Syntax
* Basic Syntax
In this section we will walk through the basic syntax of a short Go program.
For this section all the code exercises will be inside this slide deck itself.
At the end of this section you'll know:
- How to declare constants and variables
- How to write `for` loops and use `if`.
- How types work.
- How to write your own functions.
- How packages and `import` statements work.
* Constants
A good place to start talking about Go are _Constants_.
Constants are values that do not change.
Here are some examples of constants:
1
"hello"
false
1.3
These are called _literal_constants_ because the value of evaluating each of these is the constant itself.
* Types of constants
There are six kinds of constants
- integer constants: `1`, `0`, `-6`, `9999999999999999999`, …
- floating point constants: `3.14`, `7.5e-2`, …
- complex number constants (rare): `1`-`0.707i`, …
- string constants: `"Hello,`東京"`, …
- rune constants: `'a'`, `'す'`, `'シ'`, `'1'`, …
- boolean constants: `true`, `false`
* const
To make a constant, we declare one with the `const` keyword.
.play -edit src/const/const1/main.go /START OMIT/,/END OMIT/
Whenever you see a *Run* button on a slide, you can execute the code.
- Press the *Run* button now and see what happens.
- Press the *Close* button to close the output window.
You can also edit the code right here in the slide.
- Edit the code to replace my name, with yours.
- All source code in Go is UTF-8, you can use Kanji.
- Press the *Run* button to see the results.
- If you make a mistake, just reload the page.
* Identifiers
This is a good time to talk about _identifiers_.
An identifier is a name your give to something in your code.
In Go an identifier is any word that starts with a _letter_.
.play -edit src/identifier/identifier1/main.go /START OMIT/,/END OMIT/
A letter is anything that Unicode defines to be a letter, this includes Kanji, Cyrillic, Latin, etc.
- Identifiers are not restricted to ASCII, edit the slide and change `students` to `学生の` and press *Run*.
- If you make a mistake, just reload the page.
* Identifiers (cont.)
An identifier must start with a unicode letter, or the underscore character, `_`.
Numbers are not permitted at the start of an identifier, but can appear later in the identifier.
.play -edit src/identifier/identifier2/main.go /START OMIT/,/END OMIT/
Here are some examples of _invalid_ identifiers.
- Change the name of the identifier so that the program compiles.
- Press the *Run* button to see the results.
- If you make a mistake, just reload the page.
* Comments
Go supports two kinds of comments:
- Inline comments, which start with a double forward slash, `//`.
- Block comments, which start with a forward slash and a star, `/*`, and end with a star and forward slash, `*/`.
.play -edit src/comments/comments1/main.go /START OMIT/,/END OMIT/
Code that is commented out will not be compiled or run.
- Remove the comments in this program so it compiles.
- Press the *Run* button to see the results, it should compile and print `1`2`3`.
- If you make a mistake, just reload the page.
* Declarations
There are six kinds of _declarations_ in Go, we've seen one of them already.
They are:
- `const`: declares a new constant.
- `var`: declares a new variable.
- `type`: declares a new type.
- `func`: declares a new function, or method.
- `package`: declares the package this `.go` source file belongs to.
- `import`: declares that this package imports declarations from another.
We'll cover each of the remaining five declarations in this section.
* Variables
A variable holds a value that can be changed over time.
You _declare_ a new variable with the `var` declaration.
.play -edit src/variable/variable1/main.go /START OMIT/,/END OMIT/
Just like constants, variable _identifiers_ can be any any valid unicode word.
- Press the *Run* button to see the result.
_note_: The circumference is printed in scientific notation 😕, that's ok, we'll talk about how to fix it later when we talk about the `fmt` package.
* Unused variable declarations
Unused variables are often the source of bugs. If you declare a variable in the scope of your function but do not use it, the Go compiler will complain.
If the variable is unused, you should delete it, or assign it temporarily to the magic variable called `_`.
.play -edit src/variable/variable2/main.go /START OMIT/,/END OMIT/
This program has four unused variables.
- Fix the program by removing the comment from the two lines at the bottom.
- Delete, or comment out, the declaration of `自転車` as it is unused.
- Press the *Run* button to check that your program compiles.
* Statements
A _statement_ is a command to do something:
- _Declare_a_new_integer_variable_x_and_assign_it_the_value_10_.
- _Add_4_to_the_value_of_x_and_store_the_result_in_y_.
- _While_x_less_than_20_perform_these_statements_.
There are several kinds of statements in Go, we've seen a few already. The most common statements are:
- Declarations: `const`pi`=`3.14159265359`, `type`Counter`int32`, …
- Assignments: `count`=`count`+`1`, …
- Increment/Decrement: `x++`, `y--`
- Conditionals: `if`…`{`…`}`else`{`…`}`, `switch`{`…`}`
- Loops: `for`…`{`…`}`
- Control flow: `break`, `fallthrough`, `continue`, `goto`, `return`.
* Assignment
It is common that you need to change the value stored in a variable, this is called _Assignment_.
.play -edit src/assignment/assignment1/main.go /START OMIT/,/END OMIT/
In this example, we declare
- Press *Run* to check that program prints, `1`, `2`, `4`.
# - Update the program to declare a new variable, `z`, which has a value 2x larger than `y`.
* Assignment (cont.)
You can only assign a new value to _variables_.
.play -edit src/assignment/assignment2/main.go /START OMIT/,/END OMIT/
It is a syntax error to assign a new value to a constant.
- Press *Run* and see the program does not compile.
- Edit the sample code to change the declaration of `x` from a constant (`const`) to a variable (`var`).
- Press *Run* and check the program compiles and prints the correct answer, 2.
* Increment and decrement
Go supports a limited form of variable post-increment and post-deincrement, ie. `x++`, `x--`.
.play -edit src/increment/increment1/main.go /START OMIT/,/END OMIT/
- Press *Run* and see the program prints `2`,
- Edit the sample code to subtract `1` from `i` using the deincrement operator `i--`.
- Press *Run* and check the program compiles and prints the correct answer, 0.
* Increment and decrement (cont.)
`i++` and `i--` are _statements_, not an _expressions_, they do not produce a value.
.play -edit src/increment/increment2/main.go /START OMIT/,/END OMIT/
This program has a syntax error.
- Edit the sample code to correct the error by moving the `i++` statement above the declaration of `var`j`.
- Press *Run* and check the program compiles and prints the correct answer, 2, 2.
* Looping
Go has a single `for` loop construct that combines
- `while` _condition_ `{`…`}`
- `do`{`…`}`while` _condition_
- `do`{`…`}`until` _condition_
into one syntax.
- `for` _(init_statement)_; _condition_; _(post_statement)_ `{`…`}`
The parts of a `for` statement are:
- init statement: used to initalise the loop variable; `i`=`0`.
- condition: user to test if the loop is done; `i`<`10`, `true` means keep looping.
- post statement: user to increment the loop variable; `i++`, `i`=`i`-`1`.
* Looping (cont.)
Let's practice using loops.
.play -edit src/loops/loops1/main.go /START OMIT/,/END OMIT/
This program counts from `1` to `10`, can you make it print only the _even_ numbers.
- Edit the program to make it print only the even numbers between `1` and `10`, inclusive.
- Press *Run* and check the program compiles and prints the correct answer, `2`, `4`, `6`, `8`, `10`.
_note_: you do not need to put `(` braces around the `for` condition `)`. In fact, if you do it's a syntax error. Try it.
* Looping (cont.)
Let's practice counting down, this is where you would use a `while` loop in other languages.
.play -edit src/loops/loops2/main.go /START OMIT/,/END OMIT/
This program counts down from `10` to `1`, can you make it count from `7` to `3`.
- Edit the program to make it print only the numbers from `7` down to `3`.
- Press *Run* and check the program compiles and prints the correct answer, `7`, `6`, `5`, `4`, `3`.
_note_: this `for` loop only has a _condition_, there is no _init_statement_ or _post_statement_, so we can omit the semicolons, `;`.
* Conditional statements
Go has two conditional statements, `if` and `switch`.
`if` is used to choose between two choices based on a _condition_.
if v > 0 {
println("v is greater than zero")
} else {
println("v is less than or equal to zero")
}
In some cases the body of the `else` block may be omitted. This is very common when checking preconditions in a method of a function.
if v == 0 {
// nothing to do
return
}
// handle v
* if
Let's revisit our previous even numbers `for` loop example.
.play -edit src/conditionals/conditionals1/main.go /START OMIT/,/END OMIT/
This program counts from `1` to `10`, can you make it print only the _even_ numbers.
- Uncomment the `if`i%2`==`0`{` and `}` lines to make the program print only the even numbers between `1` and `10`.
- Press *Run* and check the program compiles and prints the correct answer, `2`, `4`, `6`, `8`, `10`.
_note_: `%` is the _modulo_ operator in Go. All even numbers divide wholly by `2`, leaving `0` as their _modulo_ (or remainder).
* continue
Unlike languages like Java, `if` statements in Go are often used as _guard_clauses_.
We say that when everything is true the code reads from the top to the bottom of the page.
We can rewrite the previous program using a new statement, `continue`, which _skips_ the body of the loop.
.play -edit src/conditionals/conditionals2/main.go /START OMIT/,/END OMIT/
- Uncomment the `if`i%1`==`1`{`, `continue`, and `}` lines.
- Press *Run* and check the program compiles and prints the correct answer, `2`, `4`, `6`, `8`, `10`.
* break
This program is an _infinite_loop_. There is no _condition_expression_ in the `for` loop.
We can use the `break` statement, which breaks out of the _current_ loop, to fix it.
.play -edit src/conditionals/conditionals3/main.go /START OMIT/,/END OMIT/
- Uncomment the `if`i`>`10`{`, `break`, and `}` lines.
- Press *Run* and check the program compiles and prints the correct answer, `2`, `4`, `6`, `8`, `10`.
* Type inference
In the examples so far we've avoided talking about types, this is because Go supports _type_inference_.
Type inference lets you omit the type of a variable during declaration.
For example:
var i = 7
Go sees that `i` is being declared and initalised with the value `7`, so the compiler infers the type of `i` is an `int`.
However if we did
var s = "seven"
Go sees that `s` is being initalised with the _string_ `"seven"`, so the compiler infers the type of `s` is a `string`.
* Explicit type declaration
Sometimes you will want to tell Go to use a specific type.
You do this when you declare a variable:
var i int = 4
var s string = "おはようございます"
Which tells the compiler that you are declaring `i` explicitly to be an `int` with the value `7`, and `s` to be a `string` with the value `"おはようございます"`
We'll talk about the kinds of types that Go supports on the next slide.
* Types
Go is a strongly typed language, like Java, C, C++, and Python. Go has nine kinds of types, they are:
- strings: `string`.
- signed integers: `int8`, `int16`, `int32`, `int64`.
- unsigned integers: `uint8`, `uint6`, `uint32`, `uint64`.
- aliases: `byte`, `rune`, `int`, `uint`.
- booleans: `bool`.
- IEEE floating point: `float32`, `float64`.
- Complex types: `complex64`, `complex128`.
- Compound types: `array`, `slice`, `map`, `struct`.
- Pointer types: `*int`, `*bytes.Buffer`.
* String types
Strings are the most common data type in Go programs.
String types behave much as you would expect in other languages.
.play -edit src/strings/strings1/main.go /START OMIT/,/END OMIT/
Strings may be _concatenated_ with the `+` operator.
- Press *Run* to see the result.
_note_: In Go an empty string is `""`, not `null` or `nil`.
* Integer types
Integer types are the second most common in Go.
Integer types come in two types; _signed_ and _unsigned_.
Integer types also come in several sizes, represented by the number of bits they represent;
- Signed integers: `int8`, `int16`, `int32`, `int64`.
- Unsigned integers: `uint8`, `uint16`, `uint32`, `uint64`.
Go has two integer types
- `int`, alias for `int32` or `int64` depending on platform.
- `uint`, alias for `uint32` or `uint64` depending on platform.
whose size depends on the platform you used to build your Go program.
* Integer types (cont.)
Why does Go support so many kinds of integer types?
Different _sized_ integer types can accomodate different ranges of numbers.
.play -edit src/types/types1/main.go /START OMIT/,/END OMIT/
This program contains two type errors.
- Press *Run* to discover the two type errors.
- Fix the program by changing the declared types of `x` and `y`.
- Press *Run* and check the program compiles and prints the correct answer, `400`, `-7`
* Functions
Now it's time to talk about _functions_.
All Go you write is made up of functions, in fact, you've been writing functions all along.
.play -edit src/functions/functions1/main.go /START OMIT/,/END OMIT/
This is the same program as the previous example, showing the _function_declaration_, which was previously hidden.
- All Go programs start in a function called `main`, we call this the _main_function_.
* func
You can declare your own functions with the `func` declaration.
A function's name must be a valid identifier, just like `const` and `var`.
.play -edit src/functions/functions2/main.go /START OMIT/,/END OMIT/
This program declares two functions, `main` and `hello`.
- Uncomment the `println("こんにちは")` statement in `func`hello`.
- Press *Run* and check the program compiles and prints こんにちは three times.
_note_: `println` is a _built_in_ function provided, you don't need to declare it.
* Function parameters
To make functions useful, you often need to pass _arguments_ to a function.
To pass an argument to a function, the type of the argument and the type of the function's _formal_parameter_ must be the same.
.play -edit src/functions/functions3/main.go /START OMIT/,/END OMIT/
In this program the type of the argument passed to `hello` does not match the type of the `name` parameter.
- Fix the declaration of `hello` so that the type of the parameter matches the type of the argument provided.
- Press *Run* and check the program compiles and prints `こんにちは`David`.
* Packages
A package is the unit in which software is shared and reused in Go. All Go code is arranged into packages.
Each source file in a package must begin with the same `package` declaration.
A package's name must be a valid identifier, just like `const`, `var`, and `func`.
.play -edit src/packages/packages1/main.go
This is the same example as the previous slide, revealing the `package` declaration.
`package`main` is the name of the package which contains the entry point to your program, `func`main`.
* main packages
This program has the wrong `package` declaration.
.play -edit src/packages/packages2/main.go
- Press *Run* and observe the compile error.
- Change the `package` declaration to make the program compile.
- Press *Run* to check that program prints its greeting.
* Import
The final declaration we'll cover in this section is the _import_ declaration.
The `import` declaration allows you to use code from other _packages_ into your package.
When you `import` a package, the _public_ types, functions, variables, types, and constants, are available with a prefix of the package's name.
time.Now // denotes the Now function in package time
Note that
import "fmt"
import "time"
and
import (
"fmt"
"time"
)
both import the `fmt` and `time` packages. The syntax is different, but they are equivalent.
* Import (cont.)
The `import` declaration must appear _after_ the `package` declaration, but before any `type`, `const`, `var`, or `func` declarations.
.play -edit src/imports/imports1/main.go
This program does not compile as the `import` declaration is in the wrong place.
- Move the `var`now`=`time.Now()` declaration _below_ the `import` declaration.
- Press *Run* to check that program prints the current time.
* Import (cont.)
Packages contain both _public_ and _private_ symbols. We also call these _exported_ and _not_exported_, respectively.
.play -edit src/imports/imports2/main.go
This program does not compile as it refers to two _private_ symbols.
- Fix the program by using the correct case for `Println` and `Time`.
- Press *Run* to check that program prints the current time.
_note_: If you are running this slide from [[https://go-talks.golang.org/][gotalks.golang.org]], the time may be reported as `2009-11-10`23:00:00`+0000`UTC`. This is a technical limitation.
* fmt package
Do you remember this program?
.play -edit src/imports/imports3/main.go
Here it is again, showing the `func`, `package` and `import` declarations making it a complete Go program.
This program also uses the `Println` function from the `fmt` package, which is more capable than the built in `println` function.
- Press *Run* to see how `fmt.Println` prints this output.
* Recap
Now you know the basics of Go!
You've learnt:
- How to declare constants and variables
- How to write `for` loops and use `if`.
- How types work.
- How to write your own functions.
- How packages and `import` statements work.
Time for a quick break!
* Advanced Syntax
* Advanced Syntax
This section builds on the previous by exploring each of the things we learnt in a little more detail.
In this section we'll use the Go Playground, a simple online code editor to perform our exercises.
* Coding style
All Go code is formatted according to a single style guide which is enforced with a tool called `gofmt`
Having one single style that all Go code is formatted in improves readability and avoids the time wasted arguing about code formatting.
"Gofmt's style is no one's favorite, yet gofmt is everyone's favorite."
.caption [[https://go-proverbs.github.io/][Go Proverb]].
The Go playground can format your code according to the canonical Go style.
- Follow [[https://play.golang.org/p/0Hz57BQdTA][this link]] and press the *Format* button to see this in action.
* Zero value
In previous examples we've written code like this
var name = "go"
var counter = 1
Which both _declares_ and _initalises_ the variables `counter` and `name` respectively. What happens if we have code like this?
.code src/zerovalue/zerovalue1/main.go
What will ths print?
- Follow [[https://play.golang.org/p/jioUB0t_LW][this link]] and press the *Run* button to see this in action.
* Zero value (cont.)
In Go, there is no unitialised memory. The Go runtime will always ensure that the memory allocated for each variable is initalised before use.
If we write something like
var name string
var counter int
Then the memory assigned to the variables `name` and `counter` will be zeroed, as we have not provided an _initaliser_.
- The value of `name` will be `""` because that is the value of a string with zero length.
- The value of `counter` will be zero, because that is the value of an `int` if we wrote `0` to its memory location.
* Zero value (cont.)
Every type in Go has an associated _zero_value_. The value of that variable if we wrote zeros to its memory.
- The zero value for integer types: `int`, `int8`, `uint`, `uint64`, etc, is `0`.
- The zero value for floating point types: `float32`, `float64`, `complex128`, etc, is `0.0`.
- The zero value for arrays is the zero value for each element, ie. `[3]int` is `0`, `0`, `0`.
- The zero value for slices is `nil`.
- The zero value for structs is the zero value for each field.
* Equality
As Go is a strongly typed language, for two variables to be equal, both their _type_and_their_value_ must be equal.
Trying to compare two variables of _different_ types is detected at runtime.
.code src/equality/equality1/main.go
- Follow [[https://play.golang.org/p/LwiJm2xuXK][this link]] and press the *Run* button.
- Fix the program by declaring `x` and `y` to be the _same_ type.
- Press the *Run* button and confirm the program now prints `true`.
* Type conversions
Sometimes you have variables of different integer types, you can _convert_ from one type to another using a conversion _expression_.
The expression `T(v)` converts the value `v` to the type `T`.
.code -edit src/types/types2/main.go
In this example the assignment of `y`=`x` fails because `x` and `y` are different integer types.
- Follow [[https://play.golang.org/p/wvG41C0lH4][this link]] and press the *Run* button.
- Fix the program by _converting_ `x` to an `int` with `int(x)`.
- Press the *Run* button and confirm the program now prints `700`.
* Type conversions (cont.)
If you have variables of different _widths_, you can _convert_ from one type to another.
.code -edit src/types/types3/main.go
- Follow [[https://play.golang.org/p/l4Q48pWAla][this link]] and press the *Run* button.
- Fix the program by _converting_ `x` to an `int64` with `int64(x)`.
- Press the *Run* button and confirm the program now prints `32000`.
* Type conversions (cont.)
We can do the opposite and convert a wider type to a narrower type.
.code -edit src/types/types4/main.go
- Follow [[https://play.golang.org/p/NbNwRjbmRu][this link]] and press the *Run* button. Does it print the answer you expected?
- Fix the program by _declaring_ `y` as an `int32`.
- Press the *Run* button and confirm the program now prints `64000`.
* Integer overflow
Whenever you declare a variable in Go, you have to choose how many bits of memory it will consume.
When you convert a variable with a _smaller_ number of bits to a variable with a larger number of bits, this is fine, because they all fit.
When you convert a variable with a _larger_ number of bits to a variable with a smaller number of bits there is a risk of truncation, because there are less bits available to represent your number.
- Follow [[https://play.golang.org/p/NbNwRjbmRu][this link]] and press the *Run* button. Does it print the answer you expected?
- Fix the program by reducing the value of `x`. Hint: the value needs to be less than 33,000.
- Press the *Run* button and confirm the program now prints `y` correctly.
* Short declaration syntax
As you've probably noticed, Go has several ways to declare variables. All three of these are the same
var x = 0
var x int = 0
var x int
If you've come from a language like Ruby or Python, you're probably wondering if this very common operation can be made more concise. Indeed it can.
x := 0
This is what we call a _short_declaration_, which is the same as
var x int = 0
Short declaration is very common in Go programs, you'll see it everywhere, so let's do some exercises to familarise you with its use.
* Short declaration syntax (cont.)
A common use of the short declaration syntax is in `for` loops. Consider this program
var i int
for i = 1; i < 11; i++ {
fmt.Println(i)
}
This can be also written as
for i := 1; i < 11; i++ {
fmt.Println(i)
}
[[https://play.golang.org/p/3Vl75w72JO][This program]] contains two `var` declarations and two `for` loops.
- Follow [[https://play.golang.org/p/3Vl75w72JO][this link]] and press the *Run* button.
- Rewrite the program using the short declaration syntax; there should be no `var` declarations, only `:=`.
* Slices
The next kind of type to discuss is the _Slice_.
A slice is an ordered collection of values of a _single_ type.
The syntax for declaring a slice variable is very similar to declaraing a _scalar_ variable.
var i int // an int called i
var j []int // a slice of ints called j
In this example,
- `i` is a variable of type `int`.
- `j` is a variable of type `[]int`, that is, a slice of `int`.
Slices are very important in Go programs, so we'll spend a bit of time discussiong them.
_note_: A slice is _not_ an array. Go also supports arrays, but you'll see later than they aren't very common, or very easy to use, so we won't discuss them at the moment.
* How large is a slice?
If I declare a slice, `[]int`, how many items can it hold?
The _zero_value_ of a slice is empty, that is, it has a _length_ of zero; it can hold 0 items.
.code -edit src/slices/slices1/main.go
We can retrieve the length of a slice with the built-in `len` function.
- Follow [[https://play.golang.org/p/gZYvdE2zbT][this link]] and press the *Run* button.
- Did you guess the right answer?
* Making a slice
We can create a slice with space to hold items using the built-in `make` function.
.code -edit src/slices/slices2/main.go
In this example, on the first line `var i []int` declares `i` to be a slice of `int`.
On the second line, `i` is _assigned_ the result of `make([]int,`20)`.
- Follow [[https://play.golang.org/p/i_IWqjik6u][this link]] and press the *Run* button.
- Did `fmt.Println(len(i))` print the result you expected?
* Making a slice (cont.)
Because declaring a slice variable and initalising it with `make` is a common operation, it is common to see the _short_variable_declaration_ used to combine this operations.
.code -edit src/slices/slices3/main.go
This example declares `i` _and_ initalises it to be a slice of `int` with a length of 20.
- Follow [[https://play.golang.org/p/b92SJ0Gx9s][this link]] and press the *Run* button.
- Did `fmt.Println(len(i))` print the result you expected?
* Slice exercises
Let's do a quick exercise to familarise yourself with using slices.
.code -edit src/slices/slices4/main.go
- Follow [[https://play.golang.org/p/AJk1Jgp1iE][this link]] for instructions.
- Declare a variable called `i` which is a slice of 5 `int`.
- Declare a variable called `f` which is a slice of 9 `float64`.
- Declare a variable called `s` which is a slice of 4 `string`.
- Does your program print the expected result, `5`9`4`?
* Index expressions
To access, or assign, the contents of a slice element at index `i`, use the form `s[i]`.
Slices are zero indexed, so `s[0]` is the 1st element, `s[1]` is the second element, and so on.
When the _index_expression_ appears on the _left_hand_side_ of the equals operator, `=`
s[7] = 20
We are assigning the number 20 to the 8'th element of the slice `s`.
When the _index_expression_ appears on the _right_hand_side_ of the equals operator, `=`
x := s[7]
We are assigning the value at the 8th element of `s` to the variable `x`.
* Slice zero value
We saw earlier that the _zero_value_ of the slice
var s []int
was and empty slice, a slice with length of zero.
What is the value of each of the elements of a newly created, with make, slice?
.play -edit src/slices/slices5/main.go
- Follow [[https://play.golang.org/p/kGh_C1l6KW][this link]] and press the *Run* button.
- Did the program print the result you expected?
* Slice initialisation
We want to create an `[]int` slice of the first 10 prime numbers, how could we do this?
One solution could be to create the slice and assign a value to each element in the slice.
.play -edit src/slices/slices6/main.go
* Slice initialisation (cont.)
Doing this manually is verbose and boring; how would you do this for the first 50 primes?
Go supports a method of assignment where we both _declare_ and _initalise_ the slice at once.
.play -edit src/slices/slices7/main.go
This is called the _composite_literal_ syntax.
- Follow [[https://play.golang.org/p/P-eBqzPCWh][this link]] and complete the exercise.
* append
So far we've been using slices with a known length. You can extend the contents of a slice with the built-in `append` function.
.play -edit src/slices/slices8/main.go
`append` increases the length of the slice to accomodate the new items, then returns a new slice value.
You can `append` mutliple values in one statement, providing they are all the same type.
.link https://blog.golang.org/slices Further reading: Arrays, slices (and strings): The mechanics of 'append' (blog.golang.org)
* Subslices
What if we have a large slice, and want to refer to only a part of it.
We call this slicing a slice, or _subslicing_.
Subslicing looks similar to the _indexing_ operation we saw a few slide ago, except it refers to a range of slice indexes.
.play -edit src/slices/slices12/main.go
The expression `brothers[0:3]` evaluates to a slice of the 1st to 3rd Marx brother.
- Follow [[https://play.golang.org/p/d1-jl42aTF][this link]] and complete the exercise.
* Subslices (cont.)
An important thing to remember when slicing a slice, is that both slices refer to the _same_ underying data.
.play -edit src/slices/slices10/main.go
To create two independant slice values, you would use the `copy` function, which we'll discuss later.
* Bounds checking
Each slice has a length which is decided when it is made.
You can increase the length of the slice with the `append` function, and create a smaller slice from a larger one using the slice operator.
What happens if you accidentally exceed the bounds of the slice?
.play -edit src/slices/slices11/main.go
- Follow [[https://play.golang.org/p/mIWm0a1amp][this link]] and press the *Run* button.
- Comment out `fmt.Println(primes[-1])` and see what happens.
* Multiple assignment
Go allows you to perform multiple assignments and declarations in one statement.
For example, if we wanted to declare, `x`, `y`, and `z`, with the values `1`, `2`, and `3` respectively. We could write
var x = 1
var y = 2
var z = 3
We can write the same thing like this
var x, y, z = 1, 2, 3
- Follow [[https://play.golang.org/p/d2hDJQAfkt][this link]] for some examples of multiple declaration.
* Multiple return values
Multiple assignment is important to understand because you can return multiple values from a function.
func f(i int)
This is a function declaration for `f` which takes one argument, an `int`.