-
Notifications
You must be signed in to change notification settings - Fork 1
/
02-fundamentals.slide
553 lines (346 loc) · 11.9 KB
/
02-fundamentals.slide
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
# Fundamentals #1
Course Go
Tags: golang, go
## Outline
- Built-in types
- Variables
- Control flow
- Functions
- Custom types
- Pointers
## Keywords
[Mat Ryer: Things in Go I Never Use](https://youtu.be/5DVV36uqQ4E?si=hZDbgTxZiUAvAS3g)
```
break case chan const continue
default defer else fallthrough for
func go goto if import
interface map package range return
select struct switch type var
```
First lecture covered:
```
import
package
```
This lecture covers most of them:
```
break case const continue
default defer else fallthrough for
func goto if
return
struct switch type var
```
## Built-in types
## Built-in types
- Similar to C
- No auto casts
- Type inference and default types
```
bool
string
int int8 int16 int32 int64
uint uint8 uint16 uint32 uint64 uintptr
byte // alias for uint8
rune // alias for int32
// represents a Unicode code point
float32 float64
complex64 complex128
```
## Default values
- Each type has it's default value
- Booleans: **`false`**
- Strings: **`""`**
- Numeric types: **`0`**
- Runes: **`''`** == **`0`** == **`U+0000`**
- Complex: **`0+0i`**
- Pointer types: **`nil`**
- More on those later
## Variables
## Variables
- Declarations
- Using **`var`**
- Using **`:=`**
- Infers the type of the variable
- Cannot be used when declaring global variables (only function level)
- Assignments
- Using **`=`**
- The variable has to be previously declared
## Variables
.play assets/lecture-02/variables/variables.go
## Idiomatic declarations
- Use **`var`** when you want to leverage the default value
```
// YES
var counter int
// NO
counter := 0
```
- Use **`:=`** when initializating the variable with other than the default value
```
// YES
counter := 100
// NO
var counter = 100
```
## Constants
- Declared and initialized using **`const`**
- No changes are permitted beyond declaration
- Only supports runes, strings, bools, and numeric values
.play assets/lecture-02/variables/constants.go
## Type conversions
- No auto casts
.play assets/lecture-02/variables/casting.go
## Shadowing
- Variables from outer blocks can be shadowed
.play assets/lecture-02/variables/shadowing.go
## Shadowing
- Does not work in the same block
.play assets/lecture-02/variables/shadowing-same-block.go
## Control Flow
## Conditions
- No parantheses around conditions
- Allows init statement
- Variables declared via init do not exist beyond the scope of the if block
.play assets/lecture-02/if/if.go
## Else statement
- Variables declared in the init statement are reachable in the (else-if)-else blocks
.play assets/lecture-02/if/if-else.go
## Switch statement
- Also allows init statement
- Like set of if-(else-if)-else statements
- Evaluated top-bottom, first successful case is executed
- No fallthrough by default
.play assets/lecture-02/switch/switch.go
## Switch statement fallthrough
- Fallthrough can be explicitly set
- Generally not recommended
.play assets/lecture-02/switch/fallthrough.go
## Switch statement expressions
- Allows non-constant and non-integer values
.play assets/lecture-02/switch/expressions.go
## Switch without condition
- Switch without condition is like `switch true`
.play assets/lecture-02/switch/empty.go
## Loops
- Only the `for` keyword exists (no `while`)
.play assets/lecture-02/for/for.go
## Loops
- `break` keyword
- `continue` keyword
- Same as in other languages
## Labels & goto statement
- It is here but just don't
- Pretty please...
- Your colleagues will hate you!
.play assets/lecture-02/goto/goto.go
[Edsger W. Dijkstra on goto](https://dl.acm.org/doi/10.1145/362929.362947)
## Labels with loops
- Can be used with `break` and `continue` in loops
.play assets/lecture-02/for/labels.go
## Functions
## Functions
- Defined using the `func` keyword
- Arguments are passed by value
.play assets/lecture-02/functions/functions.go
## Multiple return values
.play assets/lecture-02/functions/multiple-return-values.go
## Named return values
.play assets/lecture-02/functions/named-return-values.go
## Shortening type declarations
.play assets/lecture-02/functions/shortened-types.go
## Ignoring return values
- '`_`' idiom can be used to drop return values
.play assets/lecture-02/functions/ignore-values.go
## Lambda functions
- AKA function literals
- Can be invoked directly or assigned to a variable
.play assets/lecture-02/functions/literals.go
## Typical usages for lambda functions
- `go` blocks
- `defer` statement
- Callback functions
- Comparison functions for sorting
## Higher order functions
- Functions are like any other value
- "first-class citizens"
.play assets/lecture-02/functions/higher-order.go
## Closures
- Lambda functions that refer to variables defined outside the scope of the function
- It "closes over" another function, hence the name
- Contains code pointer and environment pointer internally
- Useful for functions that need to store it's state "somewhere"
## Closures
.play assets/lecture-02/functions/closure.go
## The infamous init function
- Basically a function for side effects
- Sets-up an initial state
- Gets called when a package is imported
- Allows multiple declarations even per file/package
- They are processed as declared/alphabetically
- Avoid it whenever possible
.play assets/lecture-02/functions/init.go /START OMIT/,/END OMIT/
## defer statement
- `defer` is a keyword in the Go
- Used to "remember" commands that will be called before `return` or function exit
- Based on LIFO (stack) of remembered commands
- The last defered call is called first
- Parameters are evaluated when `defer` is declared (i.e. in runtime)
- Not when the specified code is called
- It is possible to change function return value(s) via `defer`
- Great for cleaning-up resources
## Basic usage of defer statement
- Function `on_finish()` is called before exit from `main()`
.play assets/lecture-02/defer/defer.go
## Function declaration in defer statement
- Usually, the function definition is part of `defer` statement
- This function is anonymous - lambda, and usually it is a closure as well
.play assets/lecture-02/defer/lambda.go
## defer in loop
- 5 `defer` statements
- LIFO behaviour
.play assets/lecture-02/defer/loop.go
## defer arguments evaluation
- Actual parameters are evaluated in runtime
.play assets/lecture-02/defer/arguments-evaluation.go /START OMIT/,/END OMIT/
## defer with multiple return statements
- `defer` is called even when more `return` statements are used
.play assets/lecture-02/defer/multiple-returns.go /START OMIT/,/END OMIT/
## Practical usage of defer
.play assets/lecture-02/defer/io-example.go /START OMIT/,/END OMIT/
## defer and return values
- It is possible to change function's return value(s) via `defer`
- Works as function declared in defer is a closure
- Function return values needs to be named
- Sometimes used in applications to alter the `err` return value
## defer and return values
.play assets/lecture-02/defer/return-values.go /START OMIT/,/END OMIT/
## Custom types
## Custom types
- `type` keyword
- Go is very strict in typing (see examples)
- New types can be defined by the `type` keyword
```
type Email string
```
- This is, for example, how the `byte` and `rune` types are defined:
```
type byte = uint8
type rune = int32
```
[builtin.go](https://cs.opensource.google/go/go/+/master:src/builtin/builtin.go)
- All custom types can easily be printed
- No need to define some kind of `toString()` function
## User-defined data types
.play assets/lecture-02/types/user-types.go
## User-defined data types (passing to function)
.play assets/lecture-02/types/user-types-as-params.go
## Structures
- AKA records
- Defined using `type` and `struct` keywords
- User-defined data type
- Can also be anonymous
- Dot operator to access struct members
- Initialization using `{}`
- Members are explicitly named or follow the structure order as declared
- Structs are comparable
- Note that the structure must not contain uncomparable types (slices, maps, ...)
## Structs and dot operator
.play assets/lecture-02/structs/struct.go
## Initialization of struct members
- Similar to C language initialization
- Usage of {} parenthesis
- C-like initialization: order matters!
## Initialization of struct members
.play assets/lecture-02/structs/init.go
## Explicit struct members initialization
- Struct members are explicitly specified by name
- Greatly increases readability
- Preferred approach
## Explicit struct members initialization
.play assets/lecture-02/structs/explicit-init.go
## Structures can be compared
- `==` and `!=` operators
.play assets/lecture-02/structs/comparison.go /^func main/,/^}/
## Calling functions with structs as arguments
.play assets/lecture-02/structs/argument.go /START OMIT/,/END OMIT/
## Struct composition
.play assets/lecture-02/structs/composition.go /START OMIT/,/END OMIT/
## Struct embedding
.play assets/lecture-02/structs/embedding.go /START OMIT/,/END OMIT/
## Anonymous structure
- Just declare new variable and specify its type to `struct` _something_
.play assets/lecture-02/structs/anonymous.go
## Enums
- No direct support
- Can be somewhat simulated with
- Custom types
- And a set of predefined constants
- Go has a special **iota** for enumerating integer constants
[Go Spec: iota](https://go.dev/ref/spec#Iota)
## Enums
.play assets/lecture-02/enums/days.go /START OMIT/,/END OMIT/
## Enums
.play assets/lecture-02/enums/iota.go /START OMIT/,/END OMIT/
## Pointers
## Pointers
- Always points to an element of some type
- I.e. `void` pointers are not supported
- Default pointer value is `nil`
- Address of an element can be retrieved using the `&` operator
- Access via pointer (dereference in some other languages) using the `*` operator
- Go does not support pointer arithmetic
## Basic usage of pointers
- Note the usage of `*p_i++`
.play assets/lecture-02/pointers/to-int.go
## Panic on nil dereference
.play assets/lecture-02/pointers/panic.go
## Pointer to structure
- Note the possibility of writing `p_u.id` instead of `(*p_u).id`
.play assets/lecture-02/pointers/to-struct.go /START OMIT/,/END OMIT/
## Pointer to structure member
.play assets/lecture-02/pointers/to-struct-member.go /START OMIT/,/END OMIT/
## Return pointer to local variable from C function
#include <stdio.h>
int* get_pointer(void) {
int i = 42;
return &i;
}
int main(void) {
int *p = get_pointer();
printf("%p\n", p);
printf("%d\n", *p);
return 0;
}
## Return pointer to local variable from Go function
.play assets/lecture-02/pointers/return-reference.go
## Back to types
## Methods on types
- A _method_ is a function that has a defined receiver
- In OOP: a method is a function on an instance of an object
- Concept of a _receiver_
- Method declaration:
```
func (receiver) methodName(parameters) returnTypes {
// body
}
```
- Methods are called like this:
```
someType.methodName(parameters)
```
- Methods can modify the receiver
- Call by value vs. call by reference
## User type with a single method
.play assets/lecture-02/methods/methods.go /START OMIT/,/END OMIT/
## Value receiver
.play assets/lecture-02/methods/value-receiver.go /START OMIT/,/END OMIT/
## Pointer receiver
.play assets/lecture-02/methods/pointer-receiver.go /START OMIT/,/END OMIT/
## Nil receiver
.play assets/lecture-02/methods/nil-receiver.go /START OMIT/,/END OMIT/
## More methods for the same type
.play assets/lecture-02/methods/multiple.go /START OMIT/,/END OMIT/
## The new keyword
- Initializes the zero value of a type and returns a pointer to it
- Generally somewhat avoided
.play assets/lecture-02/new/new.go /START OMIT/,/END OMIT/