All language subtitles for English_auto_generated_Go_Programming_–_Golang_Course_with_Bonus
Afrikaans
Akan
Albanian
Amharic
Arabic
Armenian
Azerbaijani
Basque
Belarusian
Bemba
Bengali
Bihari
Bosnian
Breton
Bulgarian
Cambodian
Catalan
Cebuano
Cherokee
Chichewa
Chinese (Simplified)
Chinese (Traditional)
Corsican
Croatian
Czech
Danish
Dutch
English
Esperanto
Estonian
Ewe
Faroese
Filipino
Finnish
French
Frisian
Ga
Galician
Georgian
German
Greek
Guarani
Gujarati
Haitian Creole
Hausa
Hawaiian
Hebrew
Hindi
Hmong
Hungarian
Icelandic
Igbo
Indonesian
Interlingua
Irish
Italian
Japanese
Javanese
Kannada
Kazakh
Kinyarwanda
Kirundi
Kongo
Korean
Krio (Sierra Leone)
Kurdish
Kurdish (Soranî)
Kyrgyz
Laothian
Latin
Latvian
Lingala
Lithuanian
Lozi
Luganda
Luo
Luxembourgish
Macedonian
Malagasy
Malay
Malayalam
Maltese
Maori
Marathi
Mauritian Creole
Moldavian
Mongolian
Myanmar (Burmese)
Montenegrin
Nepali
Nigerian Pidgin
Northern Sotho
Norwegian
Norwegian (Nynorsk)
Occitan
Oriya
Oromo
Pashto
Persian
Polish
Portuguese (Brazil)
Portuguese (Portugal)
Punjabi
Quechua
Romanian
Romansh
Runyakitara
Russian
Samoan
Scots Gaelic
Serbian
Serbo-Croatian
Sesotho
Setswana
Seychellois Creole
Shona
Sindhi
Sinhalese
Slovak
Slovenian
Somali
Spanish
Spanish (Latin American)
Sundanese
Swahili
Swedish
Tajik
Tamil
Tatar
Telugu
Thai
Tigrinya
Tonga
Tshiluba
Tumbuka
Turkish
Turkmen
Twi
Uighur
Ukrainian
Urdu
Uzbek
Vietnamese
Welsh
Wolof
Xhosa
Yiddish
Yoruba
Zulu
Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated:
1
00:00:00,120 --> 00:00:02,360
welcome to this comprehensive go
2
00:00:02,360 --> 00:00:04,920
programming course for beginners
3
00:00:04,920 --> 00:00:06,919
throughout this course you'll learn key
4
00:00:06,919 --> 00:00:09,160
Concepts and techniques to write
5
00:00:09,160 --> 00:00:12,920
performant idiomatic go code you will be
6
00:00:12,920 --> 00:00:15,160
guided by the expertise of Lane Wagner
7
00:00:15,160 --> 00:00:18,240
and Alan lers who combined have over 18
8
00:00:18,240 --> 00:00:20,880
years of coding experience alongside
9
00:00:20,880 --> 00:00:22,760
mastering topics such as variables
10
00:00:22,760 --> 00:00:25,240
function loops and more you'll also have
11
00:00:25,240 --> 00:00:27,519
the opportunity to apply your new found
12
00:00:27,519 --> 00:00:30,400
skills in seven real world projects
13
00:00:30,400 --> 00:00:32,920
ranging from building an RSS aggregator
14
00:00:32,920 --> 00:00:35,480
to implementing authentication with API
15
00:00:35,480 --> 00:00:38,079
keys so get ready to unlock the
16
00:00:38,079 --> 00:00:41,520
incredible potential of go go has been
17
00:00:41,520 --> 00:00:43,719
exploding in popularity recently it
18
00:00:43,719 --> 00:00:45,200
feels like all the most modern tech
19
00:00:45,200 --> 00:00:47,760
companies are using go to build scalable
20
00:00:47,760 --> 00:00:50,039
backend infrastructure it actually makes
21
00:00:50,039 --> 00:00:52,680
a lot of sense Go's fast lightweight has
22
00:00:52,680 --> 00:00:54,800
an amazing developer experience and is
23
00:00:54,800 --> 00:00:56,760
actually super easy to learn stick
24
00:00:56,760 --> 00:00:58,480
around and in just a few minutes I'll
25
00:00:58,480 --> 00:01:00,680
explain the rest of the reasons why go
26
00:01:00,680 --> 00:01:03,000
could be a game changer for your coding
27
00:01:03,000 --> 00:01:05,119
career at this point I'll just introduce
28
00:01:05,119 --> 00:01:06,920
myself really quickly I'm Lane the
29
00:01:06,920 --> 00:01:08,720
founder of boot. Dev and I've been
30
00:01:08,720 --> 00:01:11,520
writing go for a little over 7 years and
31
00:01:11,520 --> 00:01:13,680
I've been building software for about 10
32
00:01:13,680 --> 00:01:16,360
I've actually spent over 2 years
33
00:01:16,360 --> 00:01:18,600
designing this go course and I've taught
34
00:01:18,600 --> 00:01:21,000
thousands of students with this material
35
00:01:21,000 --> 00:01:22,799
the feedback from all of my students
36
00:01:22,799 --> 00:01:24,000
over the last couple years is actually
37
00:01:24,000 --> 00:01:26,040
been Incorporated in the course so
38
00:01:26,040 --> 00:01:28,200
everything is very battle tested and up
39
00:01:28,200 --> 00:01:30,280
todate I was actually just making some
40
00:01:30,280 --> 00:01:32,000
updates yesterday so how does this
41
00:01:32,000 --> 00:01:34,159
course actually work well we're going to
42
00:01:34,159 --> 00:01:38,520
start by doing over 100 handson coding
43
00:01:38,520 --> 00:01:41,320
lessons and exercises now when we're
44
00:01:41,320 --> 00:01:42,799
done with all of that you'll actually
45
00:01:42,799 --> 00:01:44,320
have a really strong grasp on the
46
00:01:44,320 --> 00:01:46,759
fundamentals so at that point we'll go
47
00:01:46,759 --> 00:01:48,719
build a production ready back-end server
48
00:01:48,719 --> 00:01:52,479
Ino from scratch now I'm begging you
49
00:01:52,479 --> 00:01:55,200
please do not binge watch this video
50
00:01:55,200 --> 00:01:57,600
tutorial hell is a very real place and
51
00:01:57,600 --> 00:02:00,200
it's a place that you will go if you
52
00:02:00,200 --> 00:02:03,360
don't write your own code get your hands
53
00:02:03,360 --> 00:02:05,719
on the keyboard and write some code with
54
00:02:05,719 --> 00:02:08,039
me in fact you should actually be coding
55
00:02:08,039 --> 00:02:10,319
ahead of me and only using my Solutions
56
00:02:10,319 --> 00:02:13,520
when you get stuck so head over to boot.
57
00:02:13,520 --> 00:02:15,080
and create a free account that's where
58
00:02:15,080 --> 00:02:17,440
all of the code samples for this course
59
00:02:17,440 --> 00:02:19,840
are hosted now alternatively I have
60
00:02:19,840 --> 00:02:21,840
linked a GitHub repo in the description
61
00:02:21,840 --> 00:02:24,319
below all of the raw code for the
62
00:02:24,319 --> 00:02:26,519
samples in this course are hosted there
63
00:02:26,519 --> 00:02:27,879
it won't be quite a streamline of an
64
00:02:27,879 --> 00:02:29,440
option but it is an option now you
65
00:02:29,440 --> 00:02:31,319
should also know that this course is
66
00:02:31,319 --> 00:02:33,879
just one part of the full back-end
67
00:02:33,879 --> 00:02:37,319
developer career path over on boot. so
68
00:02:37,319 --> 00:02:38,560
if you're interested in going from zero
69
00:02:38,560 --> 00:02:40,360
to hired as a backend developer you
70
00:02:40,360 --> 00:02:42,840
should definitely check that out too now
71
00:02:42,840 --> 00:02:44,319
as long as we're talking about external
72
00:02:44,319 --> 00:02:46,560
resources know that if you get stuck
73
00:02:46,560 --> 00:02:48,599
during this course you have some options
74
00:02:48,599 --> 00:02:50,640
for help first you've got the boot. deev
75
00:02:50,640 --> 00:02:52,560
Discord second you've got the free code
76
00:02:52,560 --> 00:02:54,120
Camp Discord and third you've got the
77
00:02:54,120 --> 00:02:56,680
free code Camp Forum I will link all of
78
00:02:56,680 --> 00:02:58,640
those down in the description below okay
79
00:02:58,640 --> 00:03:00,400
one last thing before we jump into the
80
00:03:00,400 --> 00:03:02,000
course if you want to connect with me
81
00:03:02,000 --> 00:03:03,560
personally or you want access to my
82
00:03:03,560 --> 00:03:06,200
other go and backend content then you
83
00:03:06,200 --> 00:03:08,920
can follow me on Twitter wag lane or you
84
00:03:08,920 --> 00:03:11,000
can subscribe to my YouTube channel at
85
00:03:11,000 --> 00:03:12,879
boot. I'll link both of those down in
86
00:03:12,879 --> 00:03:14,879
the description below with all of that
87
00:03:14,879 --> 00:03:17,080
out of the way let's talk about go
88
00:03:17,080 --> 00:03:18,760
everyone always wants to talk about how
89
00:03:18,760 --> 00:03:20,920
fast the go programming language is
90
00:03:20,920 --> 00:03:23,080
let's talk about it and let's compare go
91
00:03:23,080 --> 00:03:24,879
to some of the other more popular
92
00:03:24,879 --> 00:03:27,879
programming languages so in terms of
93
00:03:27,879 --> 00:03:31,640
execution speed
94
00:03:32,680 --> 00:03:34,760
execution
95
00:03:34,760 --> 00:03:38,000
speed go is much faster than JavaScript
96
00:03:38,000 --> 00:03:41,319
python Ruby and PHP pretty much any
97
00:03:41,319 --> 00:03:43,280
interpreted language a language that's
98
00:03:43,280 --> 00:03:45,599
not compiled is going to be slower than
99
00:03:45,599 --> 00:03:47,680
go because go is a compiled language now
100
00:03:47,680 --> 00:03:48,840
don't worry too much if you're not
101
00:03:48,840 --> 00:03:50,519
familiar with the terms compiled and
102
00:03:50,519 --> 00:03:52,560
interpreted we'll talk about those in
103
00:03:52,560 --> 00:03:54,319
just a minute for now just understand
104
00:03:54,319 --> 00:03:57,439
that go is much faster um than these
105
00:03:57,439 --> 00:03:59,000
languages when it comes to executing
106
00:03:59,000 --> 00:04:01,000
programs if we're doing computationally
107
00:04:01,000 --> 00:04:03,720
heavy work go is going to be much more
108
00:04:03,720 --> 00:04:05,439
performant um than some of these other
109
00:04:05,439 --> 00:04:08,000
languages now here on the other side
110
00:04:08,000 --> 00:04:10,640
I've listed some compiled languages so
111
00:04:10,640 --> 00:04:14,239
when it comes to compilation
112
00:04:14,239 --> 00:04:16,840
speed compilation
113
00:04:16,840 --> 00:04:19,639
speed go is actually much faster than
114
00:04:19,639 --> 00:04:21,519
these compiled languages when it comes
115
00:04:21,519 --> 00:04:23,919
to compiling the code now again we'll
116
00:04:23,919 --> 00:04:26,000
talk about compiling in a minute but for
117
00:04:26,000 --> 00:04:27,720
now just understand that you have to
118
00:04:27,720 --> 00:04:30,039
compile your code before you can can run
119
00:04:30,039 --> 00:04:31,520
it when you're working with a compiled
120
00:04:31,520 --> 00:04:33,919
language and so by having a fast
121
00:04:33,919 --> 00:04:36,280
compilation speed like go has it
122
00:04:36,280 --> 00:04:37,320
actually increases developer
123
00:04:37,320 --> 00:04:39,840
productivity quite a bit we can iterate
124
00:04:39,840 --> 00:04:41,720
more quickly on our code we can deploy
125
00:04:41,720 --> 00:04:43,919
it more quickly it's not as expensive to
126
00:04:43,919 --> 00:04:47,080
run tests to compile uh the program and
127
00:04:47,080 --> 00:04:48,919
deploy it to production um so this is
128
00:04:48,919 --> 00:04:51,199
actually a huge benefit that go has now
129
00:04:51,199 --> 00:04:52,720
I do want to point out that go does not
130
00:04:52,720 --> 00:04:54,639
necessarily run faster it does not
131
00:04:54,639 --> 00:04:56,759
necessarily have a faster execution
132
00:04:56,759 --> 00:04:59,000
speed than all of these languages but it
133
00:04:59,000 --> 00:05:01,600
does beat them handily when it comes to
134
00:05:01,600 --> 00:05:03,919
compiling not to beat a dead horse but I
135
00:05:03,919 --> 00:05:05,400
want to talk a little bit more about
136
00:05:05,400 --> 00:05:07,759
execution speed so we talked about how
137
00:05:07,759 --> 00:05:09,919
go is generally faster than the
138
00:05:09,919 --> 00:05:11,639
interpreted languages right python
139
00:05:11,639 --> 00:05:14,680
JavaScript Ruby PHP and so on it gets a
140
00:05:14,680 --> 00:05:17,160
little interesting when we compare go to
141
00:05:17,160 --> 00:05:19,199
kind of the natively compiled languages
142
00:05:19,199 --> 00:05:21,759
or the languages that compile directly
143
00:05:21,759 --> 00:05:24,319
to uh kind of machine code that runs on
144
00:05:24,319 --> 00:05:27,319
your CPU versus the compiled languages
145
00:05:27,319 --> 00:05:29,360
that run on top of a virtual machine
146
00:05:29,360 --> 00:05:31,120
right so the the two big ones that run
147
00:05:31,120 --> 00:05:33,440
on a virtual machine are Java and C
148
00:05:33,440 --> 00:05:35,639
while some of the compiled or natively
149
00:05:35,639 --> 00:05:36,759
compiled languages that you'll be
150
00:05:36,759 --> 00:05:40,199
familiar with might be rust C C++ even
151
00:05:40,199 --> 00:05:42,840
though go is a natively compiled
152
00:05:42,840 --> 00:05:44,759
language a language that compiles
153
00:05:44,759 --> 00:05:46,919
directly to machine code like rust C and
154
00:05:46,919 --> 00:05:50,039
C++ its execution speed is actually more
155
00:05:50,039 --> 00:05:54,039
similar to Java and C when it comes to
156
00:05:54,039 --> 00:05:56,479
its runtime speed how many computations
157
00:05:56,479 --> 00:05:58,840
it can do kind of per second and we'll
158
00:05:58,840 --> 00:06:00,600
talk more about this later but the
159
00:06:00,600 --> 00:06:04,720
primary reason for that is the go run
160
00:06:04,720 --> 00:06:07,599
time there's basically a chunk of code
161
00:06:07,599 --> 00:06:10,759
that's included in every go program that
162
00:06:10,759 --> 00:06:13,880
manages memory and that tends to slow
163
00:06:13,880 --> 00:06:15,840
down the execution speed a little bit
164
00:06:15,840 --> 00:06:18,599
that said it is worth pointing out that
165
00:06:18,599 --> 00:06:21,240
a go program tends to use much less
166
00:06:21,240 --> 00:06:24,599
memory than Java and csharp because
167
00:06:24,599 --> 00:06:26,720
there isn't a need for an entire virtual
168
00:06:26,720 --> 00:06:28,800
machine here we are the first coding
169
00:06:28,800 --> 00:06:30,840
challenge let me break down what we are
170
00:06:30,840 --> 00:06:32,120
supposed to do and then I'll kind of
171
00:06:32,120 --> 00:06:33,960
explain what this code over on the right
172
00:06:33,960 --> 00:06:37,560
actually does so um our assignment is to
173
00:06:37,560 --> 00:06:41,479
log the string starting textio server to
174
00:06:41,479 --> 00:06:44,520
the console instead of hello world so
175
00:06:44,520 --> 00:06:46,479
throughout this course we'll be building
176
00:06:46,479 --> 00:06:50,199
out little pieces of the textio product
177
00:06:50,199 --> 00:06:51,960
which if you're familiar with twilio
178
00:06:51,960 --> 00:06:53,680
it'll kind of be like a twilio clone
179
00:06:53,680 --> 00:06:56,599
it's a kind of backend server that sends
180
00:06:56,599 --> 00:06:58,840
SMS and email messages and works a lot
181
00:06:58,840 --> 00:07:01,919
with kind of text textual data every
182
00:07:01,919 --> 00:07:03,720
file of go code has a package
183
00:07:03,720 --> 00:07:05,960
declaration at the top here we have
184
00:07:05,960 --> 00:07:08,919
package main simply because this program
185
00:07:08,919 --> 00:07:11,639
builds into an executable go program
186
00:07:11,639 --> 00:07:13,960
right so we can run this code kind of
187
00:07:13,960 --> 00:07:16,759
Standalone the next line is importing
188
00:07:16,759 --> 00:07:18,800
the fmt package from the standard
189
00:07:18,800 --> 00:07:20,759
Library we are importing it because
190
00:07:20,759 --> 00:07:22,919
we're using it down here within the main
191
00:07:22,919 --> 00:07:25,400
function now the main function is the
192
00:07:25,400 --> 00:07:27,879
entry point to the program so every go
193
00:07:27,879 --> 00:07:31,000
program starts exec ution at the top of
194
00:07:31,000 --> 00:07:32,160
the main function which is just a
195
00:07:32,160 --> 00:07:34,759
function named main that takes no inputs
196
00:07:34,759 --> 00:07:36,960
and doesn't return anything on line six
197
00:07:36,960 --> 00:07:38,840
and seven we have some single line
198
00:07:38,840 --> 00:07:41,039
comments these don't execute they are
199
00:07:41,039 --> 00:07:42,840
not part of the program they're just
200
00:07:42,840 --> 00:07:44,759
there for documentation and single line
201
00:07:44,759 --> 00:07:46,240
comments just start with that double
202
00:07:46,240 --> 00:07:48,720
slack finally on line eight we have the
203
00:07:48,720 --> 00:07:50,280
one thing that this program actually
204
00:07:50,280 --> 00:07:52,720
does which is print the string hello
205
00:07:52,720 --> 00:07:54,360
world to the console so let me go ahead
206
00:07:54,360 --> 00:07:55,440
and run
207
00:07:55,440 --> 00:07:57,720
that see down here it printed to the
208
00:07:57,720 --> 00:08:00,319
console it's using the stand libraries
209
00:08:00,319 --> 00:08:04,039
fmt package um and the print line
210
00:08:04,039 --> 00:08:05,599
function that is exposed from that
211
00:08:05,599 --> 00:08:08,120
package uh to do so so the assignment
212
00:08:08,120 --> 00:08:10,000
here is pretty simple uh we're just
213
00:08:10,000 --> 00:08:12,479
supposed to swap out that hello world
214
00:08:12,479 --> 00:08:15,599
message for starting Tex iio server
215
00:08:15,599 --> 00:08:17,000
going to run that and make sure it looks
216
00:08:17,000 --> 00:08:18,840
like what I would
217
00:08:18,840 --> 00:08:22,000
expect we're good to go next let's fix a
218
00:08:22,000 --> 00:08:25,680
quick bug I love quick wins um we're not
219
00:08:25,680 --> 00:08:27,560
going to talk about all of this syntax
220
00:08:27,560 --> 00:08:29,879
in this program what we're interested in
221
00:08:29,879 --> 00:08:33,760
is just fixing the math bug on line 17
222
00:08:33,760 --> 00:08:35,839
so the assignment description says texo
223
00:08:35,839 --> 00:08:37,279
users are reporting that we're billing
224
00:08:37,279 --> 00:08:39,279
them for wildly inaccurate amounts
225
00:08:39,279 --> 00:08:41,159
they're supposed to be build
226
00:08:41,159 --> 00:08:45,000
for2 for each text message they
227
00:08:45,000 --> 00:08:47,760
send something else is happening so the
228
00:08:47,760 --> 00:08:51,560
total cost here is being set to the cost
229
00:08:51,560 --> 00:08:55,200
per message plus the number of messages
230
00:08:55,200 --> 00:08:56,440
now that doesn't make a lot of sense to
231
00:08:56,440 --> 00:08:58,440
me go ahead and pause the video see if
232
00:08:58,440 --> 00:09:01,440
you can figure this one out on your own
233
00:09:01,440 --> 00:09:03,600
um to me it looks like the cost per
234
00:09:03,600 --> 00:09:05,240
message should be multiplied by the
235
00:09:05,240 --> 00:09:08,640
number of messages right and let me let
236
00:09:08,640 --> 00:09:12,560
me run it like this so that we can see
237
00:09:12,560 --> 00:09:16,760
Doris spent 4.02 on text messages
238
00:09:16,760 --> 00:09:19,120
today four
239
00:09:19,120 --> 00:09:21,360
messages that doesn't make sense right
240
00:09:21,360 --> 00:09:22,920
for four messages she should not be
241
00:09:22,920 --> 00:09:26,680
build $42 if each message only cost 2
242
00:09:26,680 --> 00:09:28,600
cents so I'm going to go ahead and
243
00:09:28,600 --> 00:09:31,920
change that to multiply I would expect 8
244
00:09:31,920 --> 00:09:35,440
cents yep Dora spent 8 cents on text
245
00:09:35,440 --> 00:09:37,000
messages today cool going to go ahead
246
00:09:37,000 --> 00:09:39,640
and submit that this is one of my
247
00:09:39,640 --> 00:09:42,200
favorite XKCD Comics uh you can pause
248
00:09:42,200 --> 00:09:43,640
and read it uh really quick if you'd
249
00:09:43,640 --> 00:09:46,959
like slow and resource expensive
250
00:09:46,959 --> 00:09:49,360
compilation times a really terrible
251
00:09:49,360 --> 00:09:50,920
thing to work with I've worked on
252
00:09:50,920 --> 00:09:53,959
systems in Java and C++ that took over
253
00:09:53,959 --> 00:09:56,200
an hour to compile the code that means
254
00:09:56,200 --> 00:09:58,120
that if we find a bug and we want to
255
00:09:58,120 --> 00:10:00,079
deploy it to production even if we get
256
00:10:00,079 --> 00:10:02,160
the bug fixed within five minutes it's
257
00:10:02,160 --> 00:10:03,959
still going to take an hour just to
258
00:10:03,959 --> 00:10:06,040
build the new production version so that
259
00:10:06,040 --> 00:10:08,240
we can deploy it on our servers I've
260
00:10:08,240 --> 00:10:10,320
personally never worked on a go program
261
00:10:10,320 --> 00:10:11,959
that's taken more than just a couple of
262
00:10:11,959 --> 00:10:14,200
seconds to build and compile so the
263
00:10:14,200 --> 00:10:17,040
first question is go code generally runs
264
00:10:17,040 --> 00:10:19,200
blank than interpreted languages and
265
00:10:19,200 --> 00:10:21,440
compiles blank than other compiled
266
00:10:21,440 --> 00:10:24,240
languages like C and rust so the answer
267
00:10:24,240 --> 00:10:26,320
is going to be faster and faster right
268
00:10:26,320 --> 00:10:27,920
it runs faster than inter most
269
00:10:27,920 --> 00:10:29,760
interpreted languages and it compil Iles
270
00:10:29,760 --> 00:10:31,519
faster than most compiled
271
00:10:31,519 --> 00:10:33,800
languages so the question on this one is
272
00:10:33,800 --> 00:10:36,240
does go generally execute faster than
273
00:10:36,240 --> 00:10:38,720
rust the answer is going to be no so
274
00:10:38,720 --> 00:10:40,920
I've thrown around this word compilation
275
00:10:40,920 --> 00:10:43,200
or compiled a few times but we haven't
276
00:10:43,200 --> 00:10:45,440
really talked about what it means when
277
00:10:45,440 --> 00:10:46,440
we write
278
00:10:46,440 --> 00:10:49,360
code we write it in a human readable
279
00:10:49,360 --> 00:10:52,720
format right typically in a file in the
280
00:10:52,720 --> 00:10:57,120
case of go A.O file right maybe main.go
281
00:10:57,120 --> 00:11:00,000
and this file is going to contain
282
00:11:00,000 --> 00:11:02,720
human readable text right go code that
283
00:11:02,720 --> 00:11:05,279
we as developers work on the thing is
284
00:11:05,279 --> 00:11:08,200
your computer's Hardware doesn't know
285
00:11:08,200 --> 00:11:10,519
what any of that human readable text
286
00:11:10,519 --> 00:11:14,120
means your computer's CPU only
287
00:11:14,120 --> 00:11:15,600
understands
288
00:11:15,600 --> 00:11:19,120
binary right which is ones and
289
00:11:19,120 --> 00:11:21,600
zeros right which at the end of the day
290
00:11:21,600 --> 00:11:23,160
is just numbers right but it's just
291
00:11:23,160 --> 00:11:25,360
numbers and simple operations things
292
00:11:25,360 --> 00:11:29,680
like add and subtract so we need some
293
00:11:29,680 --> 00:11:32,160
process that we can use to convert human
294
00:11:32,160 --> 00:11:35,000
readable code to machine code that can
295
00:11:35,000 --> 00:11:37,160
be executed by the computer's hardware
296
00:11:37,160 --> 00:11:40,560
and that's all that compilation is
297
00:11:40,560 --> 00:11:42,200
compilation is just the process of
298
00:11:42,200 --> 00:11:45,160
taking some human readable code right go
299
00:11:45,160 --> 00:11:47,720
code in our instance and converting it
300
00:11:47,720 --> 00:11:50,320
to Binary or machine code that our
301
00:11:50,320 --> 00:11:52,040
computer can actually understand so what
302
00:11:52,040 --> 00:11:54,959
does this process actually look like
303
00:11:54,959 --> 00:11:57,880
Well normally you'd start by writing
304
00:11:57,880 --> 00:12:02,320
your go program so say main.go
305
00:12:02,320 --> 00:12:05,920
and you'd run it through the go compiler
306
00:12:05,920 --> 00:12:09,800
on your command line you'd type go
307
00:12:11,079 --> 00:12:14,440
build and that would produce a new file
308
00:12:14,440 --> 00:12:16,519
which is the executable program let's
309
00:12:16,519 --> 00:12:18,560
say we're doing a hello word a hello
310
00:12:18,560 --> 00:12:20,839
world program it might be
311
00:12:20,839 --> 00:12:23,839
hello
312
00:12:24,160 --> 00:12:25,720
world.exe
313
00:12:25,720 --> 00:12:28,199
right an executable program on your
314
00:12:28,199 --> 00:12:30,279
computer and you could run that
315
00:12:30,279 --> 00:12:32,519
executable directly on your operating
316
00:12:32,519 --> 00:12:34,760
system without ever having to use the go
317
00:12:34,760 --> 00:12:37,399
tool chain again so the great thing is
318
00:12:37,399 --> 00:12:39,600
you can take this hello world.exe
319
00:12:39,600 --> 00:12:42,160
program and give it to someone else and
320
00:12:42,160 --> 00:12:44,040
they can run it on their computer
321
00:12:44,040 --> 00:12:46,160
without ever having to install the go
322
00:12:46,160 --> 00:12:48,880
tool chain or even know that you used go
323
00:12:48,880 --> 00:12:50,720
to build the program in the first place
324
00:12:50,720 --> 00:12:52,240
this is different than languages like
325
00:12:52,240 --> 00:12:54,279
python where if you want to run
326
00:12:54,279 --> 00:12:56,760
someone's python code you have to use
327
00:12:56,760 --> 00:12:59,279
the python interpreter every single time
328
00:12:59,279 --> 00:13:02,279
time and you run the source code you run
329
00:13:02,279 --> 00:13:04,399
the source code directly on your machine
330
00:13:04,399 --> 00:13:06,440
it's also worth pointing out that part
331
00:13:06,440 --> 00:13:09,199
of the reason that compiling is so much
332
00:13:09,199 --> 00:13:12,040
faster at runtime is that we do all of
333
00:13:12,040 --> 00:13:14,760
this compiling work upfront so when we
334
00:13:14,760 --> 00:13:16,760
go to run the executable we don't have
335
00:13:16,760 --> 00:13:18,760
to do any conversions from Human
336
00:13:18,760 --> 00:13:21,600
readable text to Binary machine code
337
00:13:21,600 --> 00:13:23,519
that's different than how interpreted
338
00:13:23,519 --> 00:13:25,279
languages work with an interpreted
339
00:13:25,279 --> 00:13:28,120
language as we run the program The
340
00:13:28,120 --> 00:13:30,800
Interpreter is reading the human code
341
00:13:30,800 --> 00:13:33,680
and kind of at runtime converting it to
342
00:13:33,680 --> 00:13:36,040
machine code that the CPU can operate on
343
00:13:36,040 --> 00:13:38,680
so you might be wondering where is the
344
00:13:38,680 --> 00:13:41,360
compiling Happening Here on botev well
345
00:13:41,360 --> 00:13:43,320
we actually do the compiling and the
346
00:13:43,320 --> 00:13:45,279
running at the same time for you so when
347
00:13:45,279 --> 00:13:47,079
you click the Run button um we're
348
00:13:47,079 --> 00:13:48,800
actually taking your code shipping it
349
00:13:48,800 --> 00:13:51,519
off to our servers compiling it running
350
00:13:51,519 --> 00:13:54,279
it and giving you the result don't worry
351
00:13:54,279 --> 00:13:56,519
when we get down the road to the actual
352
00:13:56,519 --> 00:13:58,320
project you'll be building and running
353
00:13:58,320 --> 00:14:01,199
your own go code on your own machine but
354
00:14:01,199 --> 00:14:03,320
we can see the difference between a
355
00:14:03,320 --> 00:14:06,040
compiler error and a runtime error even
356
00:14:06,040 --> 00:14:08,720
here on Bev so for example um here in
357
00:14:08,720 --> 00:14:11,320
this code the assignment says to pass
358
00:14:11,320 --> 00:14:13,240
this exercise fix the compiler error in
359
00:14:13,240 --> 00:14:15,519
the code so I'm just going to run it as
360
00:14:15,519 --> 00:14:17,600
is and you'll see we get this nasty
361
00:14:17,600 --> 00:14:20,120
error here and it says main.go right
362
00:14:20,120 --> 00:14:23,079
line six syntax error this is actually a
363
00:14:23,079 --> 00:14:25,440
compile time error so we weren't even
364
00:14:25,440 --> 00:14:28,000
able to compile this code it didn't fail
365
00:14:28,000 --> 00:14:30,519
at runtime it failed compile time right
366
00:14:30,519 --> 00:14:32,000
which again that distinction will become
367
00:14:32,000 --> 00:14:34,560
more clear a little bit later so anyways
368
00:14:34,560 --> 00:14:36,320
um we can fix it by adding that Clos
369
00:14:36,320 --> 00:14:38,839
parentheses that was
370
00:14:38,839 --> 00:14:42,120
missing and now it compiles and runs
371
00:14:42,120 --> 00:14:43,680
just
372
00:14:43,680 --> 00:14:47,959
fine so to review go code like this
373
00:14:47,959 --> 00:14:50,480
little go program here that prints hello
374
00:14:50,480 --> 00:14:53,839
world that's not understood directly by
375
00:14:53,839 --> 00:14:56,360
the hardware on your computer your
376
00:14:56,360 --> 00:14:58,519
computer's processor or your computer's
377
00:14:58,519 --> 00:14:59,839
CPU
378
00:14:59,839 --> 00:15:02,680
understands machine codee so we need to
379
00:15:02,680 --> 00:15:06,120
take our human readable go code run it
380
00:15:06,120 --> 00:15:08,120
through the go compiler to produce the
381
00:15:08,120 --> 00:15:10,800
machine code that we can run directly on
382
00:15:10,800 --> 00:15:13,800
our CPU right the CPU is designed by the
383
00:15:13,800 --> 00:15:18,120
manufacturer to run a specific format of
384
00:15:18,120 --> 00:15:20,480
binary cool so the question for this
385
00:15:20,480 --> 00:15:23,079
exercise is do computer processors
386
00:15:23,079 --> 00:15:25,079
understand English instructions like
387
00:15:25,079 --> 00:15:26,920
open the
388
00:15:26,920 --> 00:15:30,639
browser no processors are not chat GPT
389
00:15:30,639 --> 00:15:32,120
uh they need machine
390
00:15:32,120 --> 00:15:34,920
code now we touched on this very briefly
391
00:15:34,920 --> 00:15:36,839
before but I want to talk about how you
392
00:15:36,839 --> 00:15:39,399
distribute a compiled program versus how
393
00:15:39,399 --> 00:15:40,920
you would distribute an interpreted
394
00:15:40,920 --> 00:15:43,560
program so let's say that you'd written
395
00:15:43,560 --> 00:15:45,519
a script in Python so you've got this
396
00:15:45,519 --> 00:15:49,720
script main.py right this is raw python
397
00:15:49,720 --> 00:15:51,920
code and you want to give it to your
398
00:15:51,920 --> 00:15:54,160
friend so that they can run your script
399
00:15:54,160 --> 00:15:56,040
well all you would do with an
400
00:15:56,040 --> 00:15:59,560
interpreted language is give your friend
401
00:15:59,560 --> 00:16:02,600
the main.py file and then on their
402
00:16:02,600 --> 00:16:06,360
computer they would run the command
403
00:16:06,360 --> 00:16:09,360
Python
404
00:16:09,759 --> 00:16:11,600
main.py and they'd be able to run your
405
00:16:11,600 --> 00:16:14,120
code now there are a couple of downsides
406
00:16:14,120 --> 00:16:16,120
to this approach the first problem is
407
00:16:16,120 --> 00:16:18,839
that your friend needs to have python
408
00:16:18,839 --> 00:16:21,560
installed on their computer so your your
409
00:16:21,560 --> 00:16:24,079
friend being able to use your program is
410
00:16:24,079 --> 00:16:27,160
dependent on them already having python
411
00:16:27,160 --> 00:16:29,160
installed it's even dependent on them
412
00:16:29,160 --> 00:16:30,800
knowing how to use it or knowing how to
413
00:16:30,800 --> 00:16:33,199
use a command line right so Distributing
414
00:16:33,199 --> 00:16:35,120
the programs of interpreted languages
415
00:16:35,120 --> 00:16:37,240
can be tricky because it's really only
416
00:16:37,240 --> 00:16:39,000
useful if you're Distributing to other
417
00:16:39,000 --> 00:16:40,560
developers who know how to use these
418
00:16:40,560 --> 00:16:43,160
tools already the other problem is the
419
00:16:43,160 --> 00:16:46,160
code itself let's say you spent you know
420
00:16:46,160 --> 00:16:48,480
many weeks writing this python script
421
00:16:48,480 --> 00:16:50,199
and it's super useful and you're trying
422
00:16:50,199 --> 00:16:53,120
to sell it to customers if you just give
423
00:16:53,120 --> 00:16:55,279
them your python code I mean they
424
00:16:55,279 --> 00:16:57,120
effectively own it they can change it
425
00:16:57,120 --> 00:16:59,399
even if you didn't intend for it be open
426
00:16:59,399 --> 00:17:02,160
source congratulations it's now open
427
00:17:02,160 --> 00:17:04,880
source the problem is you can't really
428
00:17:04,880 --> 00:17:07,439
allow someone to use your program
429
00:17:07,439 --> 00:17:10,600
without giving them all of the Special
430
00:17:10,600 --> 00:17:12,959
Sauce that makes it work let's review
431
00:17:12,959 --> 00:17:16,240
how this works in a language like go so
432
00:17:16,240 --> 00:17:18,520
in go we'd start the same way right we'd
433
00:17:18,520 --> 00:17:20,600
write some human readable go code in a
434
00:17:20,600 --> 00:17:22,880
file called main.go but instead of
435
00:17:22,880 --> 00:17:24,799
giving that file to our friend we're
436
00:17:24,799 --> 00:17:26,959
going to compile it
437
00:17:26,959 --> 00:17:29,559
first going to compile it
438
00:17:29,559 --> 00:17:31,600
we'd use the go go tool chain so we'd
439
00:17:31,600 --> 00:17:33,520
write something like go build in our
440
00:17:33,520 --> 00:17:36,280
command line and that would produce a
441
00:17:36,280 --> 00:17:38,760
new executable file right so this is
442
00:17:38,760 --> 00:17:42,080
this is machine code here um let's just
443
00:17:42,080 --> 00:17:44,960
say that the name of our program is
444
00:17:44,960 --> 00:17:47,039
Hello World why
445
00:17:47,039 --> 00:17:49,360
not so if we're on Windows it might be
446
00:17:49,360 --> 00:17:51,640
hello world.exe
447
00:17:51,640 --> 00:17:54,360
right so when you go online and you
448
00:17:54,360 --> 00:17:56,600
download a program to use say it's a
449
00:17:56,600 --> 00:17:59,600
video game um it is probably
450
00:17:59,600 --> 00:18:01,760
a bundle of machine code it is a built
451
00:18:01,760 --> 00:18:04,320
binary right in order to run your
452
00:18:04,320 --> 00:18:06,240
favorite video game let's say Starcraft
453
00:18:06,240 --> 00:18:08,600
2 or World of Warcraft you don't need to
454
00:18:08,600 --> 00:18:12,120
install the C++ compiler right you're
455
00:18:12,120 --> 00:18:14,600
just given the built kind of final
456
00:18:14,600 --> 00:18:18,200
product the final executable program and
457
00:18:18,200 --> 00:18:20,880
that's what we're doing in uh the go
458
00:18:20,880 --> 00:18:22,679
programming language as well so now we
459
00:18:22,679 --> 00:18:24,320
can give our friend this
460
00:18:24,320 --> 00:18:26,960
executable they don't need to install go
461
00:18:26,960 --> 00:18:28,960
and they do not need access to the
462
00:18:28,960 --> 00:18:31,240
original source code so generally
463
00:18:31,240 --> 00:18:33,640
speaking Distributing programs that are
464
00:18:33,640 --> 00:18:36,559
natively compiled is much much easier um
465
00:18:36,559 --> 00:18:38,600
than Distributing programs that kind of
466
00:18:38,600 --> 00:18:40,880
have a runtime dependency like an
467
00:18:40,880 --> 00:18:43,200
interpreter so to answer the question
468
00:18:43,200 --> 00:18:46,159
for this exercise do users of compiled
469
00:18:46,159 --> 00:18:49,039
programs need access to the source code
470
00:18:49,039 --> 00:18:51,840
no they don't and a related question
471
00:18:51,840 --> 00:18:53,919
which language is interpreted we've got
472
00:18:53,919 --> 00:19:00,360
go C++ Python and rust and the answer is
473
00:19:00,360 --> 00:19:03,400
python the rest are all compiled so now
474
00:19:03,400 --> 00:19:05,480
the question is why is it generally more
475
00:19:05,480 --> 00:19:08,640
simple to deploy a compiled serers side
476
00:19:08,640 --> 00:19:10,679
program or backend application and the
477
00:19:10,679 --> 00:19:12,640
answers are compiled code is more memory
478
00:19:12,640 --> 00:19:14,960
efficient because Docker exists there
479
00:19:14,960 --> 00:19:17,919
are no runtime language dependencies or
480
00:19:17,919 --> 00:19:20,039
because compiled code is
481
00:19:20,039 --> 00:19:22,360
faster well it's just the same as what
482
00:19:22,360 --> 00:19:24,919
we talked about earlier um when we
483
00:19:24,919 --> 00:19:27,840
deploy to a server say on the cloud uh
484
00:19:27,840 --> 00:19:30,320
we have to have all of the dependencies
485
00:19:30,320 --> 00:19:33,280
uh that our backend application needs in
486
00:19:33,280 --> 00:19:36,320
order to run installed on that server
487
00:19:36,320 --> 00:19:38,840
and if there are no runtime dependencies
488
00:19:38,840 --> 00:19:42,360
if all we need is a compiled binary then
489
00:19:42,360 --> 00:19:44,120
that's arguably the simplest way to do
490
00:19:44,120 --> 00:19:46,919
it right so the answer is it's more
491
00:19:46,919 --> 00:19:48,840
simple to deploy a comp to deploy a
492
00:19:48,840 --> 00:19:51,919
compiled program to a back-end server if
493
00:19:51,919 --> 00:19:54,000
there are no runtime language
494
00:19:54,000 --> 00:19:55,960
dependencies things like the python
495
00:19:55,960 --> 00:19:58,720
interpreter or The nodejs Interpreter
496
00:19:58,720 --> 00:20:02,360
for example go is strongly typed and
497
00:20:02,360 --> 00:20:05,039
statically typed and that's a really
498
00:20:05,039 --> 00:20:06,799
good thing if you've been paying any
499
00:20:06,799 --> 00:20:09,120
attention at all to the JavaScript World
500
00:20:09,120 --> 00:20:10,799
you'll notice that a lot of JavaScript
501
00:20:10,799 --> 00:20:12,880
developers are making the switch to
502
00:20:12,880 --> 00:20:15,919
typescript and that's primarily to get
503
00:20:15,919 --> 00:20:19,720
access to static typing a lot goes into
504
00:20:19,720 --> 00:20:22,440
typing and type systems but one of the
505
00:20:22,440 --> 00:20:25,240
biggest benefits of a static type system
506
00:20:25,240 --> 00:20:27,799
like goes is that when we declare a
507
00:20:27,799 --> 00:20:30,400
string right like say this username
508
00:20:30,400 --> 00:20:33,400
string that I've set equal to wag Lane
509
00:20:33,400 --> 00:20:36,400
we can't later accidentally change it to
510
00:20:36,400 --> 00:20:38,480
an integer a number right like a float
511
00:20:38,480 --> 00:20:42,200
64 um it's going to stay a string the
512
00:20:42,200 --> 00:20:44,280
nice thing about a static type system
513
00:20:44,280 --> 00:20:45,799
like we have with go or that you have
514
00:20:45,799 --> 00:20:47,640
with typescript is that we get feedback
515
00:20:47,640 --> 00:20:50,440
on our errors uh much more quickly right
516
00:20:50,440 --> 00:20:52,320
rather than finding out about a bug when
517
00:20:52,320 --> 00:20:53,960
our code is running in production we
518
00:20:53,960 --> 00:20:55,720
find out about the bug say when we
519
00:20:55,720 --> 00:20:57,520
compile our code let's move on to the
520
00:20:57,520 --> 00:20:59,280
assignment the the assignment says we'll
521
00:20:59,280 --> 00:21:01,120
be using basic authentication for the
522
00:21:01,120 --> 00:21:03,960
text iio API so basic authentication is
523
00:21:03,960 --> 00:21:05,520
is just this format here where you've
524
00:21:05,520 --> 00:21:08,280
got a username and a password um in an
525
00:21:08,280 --> 00:21:11,960
HTTP header it tells the server on each
526
00:21:11,960 --> 00:21:14,320
individual request to the server who you
527
00:21:14,320 --> 00:21:17,080
are right it's kind of like logging in
528
00:21:17,080 --> 00:21:19,400
um or rather it's kind of like being
529
00:21:19,400 --> 00:21:24,159
logged in okay uh so the code on the
530
00:21:24,159 --> 00:21:26,279
right has a type error change the type
531
00:21:26,279 --> 00:21:27,919
of password to a string Okay cool so I'm
532
00:21:27,919 --> 00:21:29,159
just going to run it to see the type
533
00:21:29,159 --> 00:21:31,159
error first so invalid operation
534
00:21:31,159 --> 00:21:33,960
username plus colon plus password has
535
00:21:33,960 --> 00:21:36,039
mismatch types of string and int now
536
00:21:36,039 --> 00:21:37,799
this is a compile time error we we
537
00:21:37,799 --> 00:21:39,440
weren't even able to compile this code
538
00:21:39,440 --> 00:21:42,520
right let alone run it in production um
539
00:21:42,520 --> 00:21:44,159
so we've been instructed in the
540
00:21:44,159 --> 00:21:46,000
assignment change the type of password
541
00:21:46,000 --> 00:21:48,080
to a string but use the same numeric
542
00:21:48,080 --> 00:21:50,080
value so that it can be concatenated
543
00:21:50,080 --> 00:21:52,360
with the username variable Okay cool so
544
00:21:52,360 --> 00:21:53,720
I'm just going to change this to a
545
00:21:53,720 --> 00:21:56,559
string by surrounding in double quotes
546
00:21:56,559 --> 00:21:59,159
that's how you do strings and go
547
00:21:59,159 --> 00:22:00,440
pretty similar to other languages and
548
00:22:00,440 --> 00:22:02,799
then I'm just going to change that type
549
00:22:02,799 --> 00:22:06,240
to a string type and run it again
550
00:22:06,240 --> 00:22:09,679
authorization basic wag Lane colon
551
00:22:09,679 --> 00:22:12,720
number that looks good to
552
00:22:12,720 --> 00:22:14,760
me when we're talking about the
553
00:22:14,760 --> 00:22:16,760
performance of a programming language or
554
00:22:16,760 --> 00:22:19,320
an application we really care about how
555
00:22:19,320 --> 00:22:21,520
it performs across two different axes
556
00:22:21,520 --> 00:22:24,240
one is speed how fast it can do
557
00:22:24,240 --> 00:22:26,080
computations right which is kind of
558
00:22:26,080 --> 00:22:28,880
measured in CPU cycles and then we also
559
00:22:28,880 --> 00:22:31,559
have memory consumption which is just
560
00:22:31,559 --> 00:22:34,000
how bloaty the program is how much data
561
00:22:34,000 --> 00:22:36,679
it has to store in memory to be able to
562
00:22:36,679 --> 00:22:38,840
do those computations every program you
563
00:22:38,840 --> 00:22:41,159
write no matter the language is going to
564
00:22:41,159 --> 00:22:44,080
be using memory every time you create a
565
00:22:44,080 --> 00:22:46,120
new variable it allocates space in
566
00:22:46,120 --> 00:22:48,159
memory where it can store that
567
00:22:48,159 --> 00:22:51,039
variable's data now in languages like
568
00:22:51,039 --> 00:22:53,919
rust or C memory management is
569
00:22:53,919 --> 00:22:56,919
effectively manual now that said Russ
570
00:22:56,919 --> 00:22:59,320
does have some nice tooling that kind of
571
00:22:59,320 --> 00:23:01,080
takes care of it for you at compile time
572
00:23:01,080 --> 00:23:03,640
so it's not quite as error prone um as
573
00:23:03,640 --> 00:23:06,039
as it would be in C or C++ but at the
574
00:23:06,039 --> 00:23:08,000
end of the day your program is
575
00:23:08,000 --> 00:23:10,520
allocating memory right it's saying this
576
00:23:10,520 --> 00:23:12,559
chunk of memory I'm going to use I'm
577
00:23:12,559 --> 00:23:14,679
going to store some variable data here
578
00:23:14,679 --> 00:23:17,279
in this bit of RAM and then later your
579
00:23:17,279 --> 00:23:20,279
program says I'm not using it anymore um
580
00:23:20,279 --> 00:23:22,279
so we can free it up for use by other
581
00:23:22,279 --> 00:23:25,159
programs now let's jump over to Java so
582
00:23:25,159 --> 00:23:27,279
with Java it's a little bit different um
583
00:23:27,279 --> 00:23:29,240
Java is a garbage CL CED language
584
00:23:29,240 --> 00:23:31,200
garbage collection which essentially
585
00:23:31,200 --> 00:23:35,200
means that memory management is
586
00:23:35,200 --> 00:23:37,919
automated and in Java it's done by the
587
00:23:37,919 --> 00:23:40,320
Java virtual machine so every time you
588
00:23:40,320 --> 00:23:42,960
run a Java program you're actually
589
00:23:42,960 --> 00:23:44,400
creating an
590
00:23:44,400 --> 00:23:47,960
entire mini virtual
591
00:23:47,960 --> 00:23:51,400
machine that your Java bite code runs
592
00:23:51,400 --> 00:23:54,840
within so this is the
593
00:23:54,840 --> 00:23:57,520
jvm and then you kind of insert your
594
00:23:57,520 --> 00:23:59,480
code
595
00:23:59,480 --> 00:24:01,440
into the
596
00:24:01,440 --> 00:24:06,080
jvm and you run your code in there and
597
00:24:06,080 --> 00:24:08,919
the jvm is what takes care of allocating
598
00:24:08,919 --> 00:24:11,039
and freeing all of the memory that you
599
00:24:11,039 --> 00:24:14,559
use and this creates overhead basically
600
00:24:14,559 --> 00:24:17,520
at the end of the day Java programs use
601
00:24:17,520 --> 00:24:20,279
quite a bit more memory than rust or C
602
00:24:20,279 --> 00:24:23,480
programs go is in an interesting sort of
603
00:24:23,480 --> 00:24:26,120
in between world where go is a garbage
604
00:24:26,120 --> 00:24:29,600
collected language like Java so it has
605
00:24:29,600 --> 00:24:32,360
automated automated memory management
606
00:24:32,360 --> 00:24:34,960
but it does not have a jvm when you
607
00:24:34,960 --> 00:24:38,000
compile go code rather than having to
608
00:24:38,000 --> 00:24:41,000
run it within a jvm just like with Rus
609
00:24:41,000 --> 00:24:45,120
and C you get one binary or one
610
00:24:45,120 --> 00:24:47,640
executable program the difference is
611
00:24:47,640 --> 00:24:51,240
that go includes a
612
00:24:51,240 --> 00:24:53,600
runtime a
613
00:24:53,600 --> 00:24:57,440
runtime within every single binary
614
00:24:57,440 --> 00:24:59,399
that's built using the go programming
615
00:24:59,399 --> 00:25:02,120
language so we could think of it as
616
00:25:02,120 --> 00:25:03,279
something like this it's kind of like a
617
00:25:03,279 --> 00:25:04,960
little side
618
00:25:04,960 --> 00:25:07,720
car that is compiled
619
00:25:07,720 --> 00:25:12,120
alongside your code so your go program
620
00:25:12,120 --> 00:25:14,360
basically has this this little bit of
621
00:25:14,360 --> 00:25:17,360
extra code that's added to it and that
622
00:25:17,360 --> 00:25:19,679
bit of code is what handles garbage
623
00:25:19,679 --> 00:25:21,440
collection and automated memory
624
00:25:21,440 --> 00:25:23,840
management so it's a little more bloaty
625
00:25:23,840 --> 00:25:25,919
than what you'd get with rust and C
626
00:25:25,919 --> 00:25:28,720
right it is garbage collected um but
627
00:25:28,720 --> 00:25:32,240
it's not nearly as um expensive in terms
628
00:25:32,240 --> 00:25:34,679
of memory overhead as a language like
629
00:25:34,679 --> 00:25:37,600
Java or C let's take a look at what some
630
00:25:37,600 --> 00:25:39,919
actual numbers look like I pulled this
631
00:25:39,919 --> 00:25:42,600
chart from Dexter darwick uh blog and if
632
00:25:42,600 --> 00:25:43,880
you're following Along on botev you can
633
00:25:43,880 --> 00:25:45,880
click the link to go check out the full
634
00:25:45,880 --> 00:25:47,279
the full blog and the description of
635
00:25:47,279 --> 00:25:50,120
this experiment but basically he built a
636
00:25:50,120 --> 00:25:52,360
restful web server in three different
637
00:25:52,360 --> 00:25:54,279
programming languages right in Java go
638
00:25:54,279 --> 00:25:56,840
and rust and then me measured the memory
639
00:25:56,840 --> 00:25:58,880
consumption and when the servers were
640
00:25:58,880 --> 00:26:01,080
just at rest effectively doing nothing
641
00:26:01,080 --> 00:26:04,480
and waiting for requests to come in Rust
642
00:26:04,480 --> 00:26:07,559
used less than half of the memory that
643
00:26:07,559 --> 00:26:12,919
go was using and go used 100 times less
644
00:26:12,919 --> 00:26:15,320
memory right measured in megabytes than
645
00:26:15,320 --> 00:26:18,399
the jvm was using to run the rest
646
00:26:18,399 --> 00:26:20,919
service so to order the three languages
647
00:26:20,919 --> 00:26:22,640
in terms of memory efficiency I would
648
00:26:22,640 --> 00:26:25,279
say Java is the least efficient uh go is
649
00:26:25,279 --> 00:26:27,559
in the middle and rust would be the most
650
00:26:27,559 --> 00:26:29,679
memory efficient and it's also worth
651
00:26:29,679 --> 00:26:31,880
pointing out just really quickly that as
652
00:26:31,880 --> 00:26:34,840
the load on the server increases I would
653
00:26:34,840 --> 00:26:38,679
expect go to have more similar
654
00:26:38,679 --> 00:26:40,200
performance to Java in other words we
655
00:26:40,200 --> 00:26:42,320
wouldn't see as quite a large
656
00:26:42,320 --> 00:26:45,360
discrepancy here right go would likely
657
00:26:45,360 --> 00:26:47,960
still be more memory efficient than Java
658
00:26:47,960 --> 00:26:50,080
almost certainly in fact um but it
659
00:26:50,080 --> 00:26:53,240
probably wouldn't be a 100x discrepancy
660
00:26:53,240 --> 00:26:56,279
we're seeing this huge discrepancy um
661
00:26:56,279 --> 00:26:59,360
mostly because this is an idol uh a test
662
00:26:59,360 --> 00:27:02,520
of an idle program so generally speaking
663
00:27:02,520 --> 00:27:04,679
which language uses more memory that's
664
00:27:04,679 --> 00:27:07,440
going to be Java another question on the
665
00:27:07,440 --> 00:27:09,840
same topic is what's one of the purposes
666
00:27:09,840 --> 00:27:13,720
of the go runtime so to style go code
667
00:27:13,720 --> 00:27:15,440
and make it easier to read that doesn't
668
00:27:15,440 --> 00:27:17,200
make sense that would be like compile
669
00:27:17,200 --> 00:27:20,039
time tooling right not run time tooling
670
00:27:20,039 --> 00:27:22,240
to clean up unused memory to cook fried
671
00:27:22,240 --> 00:27:24,480
chicken or to compile go- code so it's
672
00:27:24,480 --> 00:27:26,000
definitely going to be to clean up
673
00:27:26,000 --> 00:27:28,200
unused memory and if you remember
674
00:27:28,200 --> 00:27:30,000
remember the runtime is just that little
675
00:27:30,000 --> 00:27:31,919
bit of extra code that's included in
676
00:27:31,919 --> 00:27:35,320
every compiled go program that among
677
00:27:35,320 --> 00:27:37,559
other things handles memory
678
00:27:37,559 --> 00:27:39,600
management so we've already talked about
679
00:27:39,600 --> 00:27:42,919
how go has strong and static types but
680
00:27:42,919 --> 00:27:44,360
we haven't yet talked about what those
681
00:27:44,360 --> 00:27:46,360
types are you're probably already
682
00:27:46,360 --> 00:27:49,120
familiar with Boolean values and string
683
00:27:49,120 --> 00:27:51,799
values which are valid go types and also
684
00:27:51,799 --> 00:27:53,080
exist in pretty much every other
685
00:27:53,080 --> 00:27:55,120
programming language um numbers are
686
00:27:55,120 --> 00:27:56,559
where it first starts to get a little
687
00:27:56,559 --> 00:27:59,559
bit different uh if go is your first
688
00:27:59,559 --> 00:28:01,919
compiled programming language generally
689
00:28:01,919 --> 00:28:03,600
speaking numbers fall into four
690
00:28:03,600 --> 00:28:06,240
different buckets we have integers
691
00:28:06,240 --> 00:28:10,320
unsigned integers or uints floats and
692
00:28:10,320 --> 00:28:13,279
complex numbers integers are just whole
693
00:28:13,279 --> 00:28:15,240
numbers they can be positive or negative
694
00:28:15,240 --> 00:28:19,000
right 1 2 3 4 you get the idea unsigned
695
00:28:19,000 --> 00:28:21,320
integers are the same as integers but
696
00:28:21,320 --> 00:28:22,640
they're not signed which basically just
697
00:28:22,640 --> 00:28:24,640
means they don't have a negative
698
00:28:24,640 --> 00:28:26,880
component you can only represent
699
00:28:26,880 --> 00:28:28,840
positive numbers in in an unsigned
700
00:28:28,840 --> 00:28:30,640
integer you probably already familiar
701
00:28:30,640 --> 00:28:32,159
with the idea of floats it's just
702
00:28:32,159 --> 00:28:33,919
fractional numbers right numbers that
703
00:28:33,919 --> 00:28:36,480
have a fractional component things like
704
00:28:36,480 --> 00:28:38,559
1.21 or
705
00:28:38,559 --> 00:28:41,000
3.14 complex numbers are a little funny
706
00:28:41,000 --> 00:28:43,679
they're used to represent the concept of
707
00:28:43,679 --> 00:28:46,360
imaginary numbers if you've gotten to
708
00:28:46,360 --> 00:28:49,080
imaginary numbers in your math studies
709
00:28:49,080 --> 00:28:51,559
I've never actually used complex numbers
710
00:28:51,559 --> 00:28:53,679
um in production I'm sure there are
711
00:28:53,679 --> 00:28:55,440
plenty of use cases for them but we're
712
00:28:55,440 --> 00:28:56,840
not going to go into detail on how they
713
00:28:56,840 --> 00:28:58,480
work here you can certainly go read up
714
00:28:58,480 --> 00:29:00,480
on it if you'd like the only other thing
715
00:29:00,480 --> 00:29:02,519
worth mentioning is that size matters
716
00:29:02,519 --> 00:29:05,720
when it comes to types A uint 8 and a
717
00:29:05,720 --> 00:29:08,600
uint 16 are two different types they
718
00:29:08,600 --> 00:29:11,720
both represent unsigned integers but a u
719
00:29:11,720 --> 00:29:15,279
16 has twice as much room for data
720
00:29:15,279 --> 00:29:18,640
within it it has 16 bits of data whereas
721
00:29:18,640 --> 00:29:21,760
a u 8 only has eight bits for example
722
00:29:21,760 --> 00:29:23,679
the largest number that you can store in
723
00:29:23,679 --> 00:29:27,559
a uint 8 is 255 because that's the
724
00:29:27,559 --> 00:29:29,080
largest number you can represent with
725
00:29:29,080 --> 00:29:31,720
eight 1es and zeros in binary but with a
726
00:29:31,720 --> 00:29:34,480
uint 16 the largest number you can store
727
00:29:34,480 --> 00:29:35,760
is about
728
00:29:35,760 --> 00:29:38,080
65,000 again because that's the biggest
729
00:29:38,080 --> 00:29:40,600
number that can be represented by 16
730
00:29:40,600 --> 00:29:43,159
binary digits just like bigger number
731
00:29:43,159 --> 00:29:45,480
better person uh bigger number in your
732
00:29:45,480 --> 00:29:47,559
types means you can represent more
733
00:29:47,559 --> 00:29:50,679
possible values uh within that type so
734
00:29:50,679 --> 00:29:53,519
float 64 can represent more values than
735
00:29:53,519 --> 00:29:56,600
a float 32 the only reason you wouldn't
736
00:29:56,600 --> 00:29:59,080
use a larger type is if you're trying to
737
00:29:59,080 --> 00:30:01,240
save on memory if you're trying to write
738
00:30:01,240 --> 00:30:03,360
a program that is hyper performant
739
00:30:03,360 --> 00:30:06,000
you'll want to use a smaller size right
740
00:30:06,000 --> 00:30:08,120
if you know that an integer is only ever
741
00:30:08,120 --> 00:30:09,799
going to store three different values
742
00:30:09,799 --> 00:30:11,600
say 1 two or three then you might
743
00:30:11,600 --> 00:30:14,399
consider using a u and 8 the bite type
744
00:30:14,399 --> 00:30:15,799
is an interesting one and it's one that
745
00:30:15,799 --> 00:30:17,799
you'll use a lot especially when you're
746
00:30:17,799 --> 00:30:20,519
say marshalling a Json object um to be
747
00:30:20,519 --> 00:30:22,679
sent across a network connection or
748
00:30:22,679 --> 00:30:24,559
maybe you're reading to and from a file
749
00:30:24,559 --> 00:30:27,399
on disk um but under the hood a bite is
750
00:30:27,399 --> 00:30:30,279
just an Alias for the uint8 type which
751
00:30:30,279 --> 00:30:32,600
makes sense right a bite is just eight
752
00:30:32,600 --> 00:30:35,120
binary digits eight bits and that's all
753
00:30:35,120 --> 00:30:39,080
a uint 8 is a rune is a Unicode code
754
00:30:39,080 --> 00:30:41,399
point which generally speaking you can
755
00:30:41,399 --> 00:30:43,720
think of as one character in a string
756
00:30:43,720 --> 00:30:45,799
and that's usually how it's used under
757
00:30:45,799 --> 00:30:48,799
the hood it's just an alias for the
758
00:30:48,799 --> 00:30:51,440
int32 type moving on to the assignment
759
00:30:51,440 --> 00:30:53,120
it says initialize the given variables
760
00:30:53,120 --> 00:30:55,440
to int float 64 bu and string
761
00:30:55,440 --> 00:30:58,639
respectively with their zero values and
762
00:30:58,639 --> 00:31:00,919
um as we can see here if we just use VAR
763
00:31:00,919 --> 00:31:03,919
the name of the variable and the type
764
00:31:03,919 --> 00:31:05,639
that should do it so we'll initialize
765
00:31:05,639 --> 00:31:08,000
the variables here so
766
00:31:08,000 --> 00:31:13,679
VAR SMS sending limit is an INT VAR cost
767
00:31:13,679 --> 00:31:18,639
per SMS is a float
768
00:31:18,960 --> 00:31:20,720
64
769
00:31:20,720 --> 00:31:24,559
has as permission is
770
00:31:24,559 --> 00:31:26,200
a
771
00:31:26,200 --> 00:31:28,880
and username
772
00:31:28,880 --> 00:31:32,480
is a string okay cool and all so all of
773
00:31:32,480 --> 00:31:34,159
these variables are now instantiated and
774
00:31:34,159 --> 00:31:36,240
should contain their zero value so for
775
00:31:36,240 --> 00:31:40,360
example zero uh 0.0 false and empty
776
00:31:40,360 --> 00:31:42,799
string so let's go ahead and run
777
00:31:42,799 --> 00:31:45,440
that and that looks correct to me I'm
778
00:31:45,440 --> 00:31:47,960
going to go ahead and submit it we've
779
00:31:47,960 --> 00:31:49,919
been declaring variables the hard way
780
00:31:49,919 --> 00:31:51,720
now we're going to do it the easy way
781
00:31:51,720 --> 00:31:54,559
there is an operator in go colon equals
782
00:31:54,559 --> 00:31:56,639
that is the short assignment operator
783
00:31:56,639 --> 00:31:59,200
and it allows us to to declare variables
784
00:31:59,200 --> 00:32:02,720
and have go infer their type so instead
785
00:32:02,720 --> 00:32:05,720
of typing VAR empty string we can just
786
00:32:05,720 --> 00:32:08,679
say empty colon equals the empty string
787
00:32:08,679 --> 00:32:12,440
and go knows that this has to be a
788
00:32:12,440 --> 00:32:15,840
string so it is a string now when we use
789
00:32:15,840 --> 00:32:18,200
this short assignment operator we're not
790
00:32:18,200 --> 00:32:19,880
saying this is a loose type that can
791
00:32:19,880 --> 00:32:21,600
change in the future it's still a static
792
00:32:21,600 --> 00:32:24,200
type empty is a string just like it
793
00:32:24,200 --> 00:32:26,519
would be if we declared it this way in
794
00:32:26,519 --> 00:32:29,480
reality in go you will very rarely see
795
00:32:29,480 --> 00:32:31,559
variables declared like this you will
796
00:32:31,559 --> 00:32:33,760
almost always see them declared using
797
00:32:33,760 --> 00:32:37,039
the short the short assignment operator
798
00:32:37,039 --> 00:32:40,559
for example num Carson equals 10 creates
799
00:32:40,559 --> 00:32:42,440
a new variable called num cars and sets
800
00:32:42,440 --> 00:32:44,480
it equal to 10 and its type will be
801
00:32:44,480 --> 00:32:47,880
inferred to be an INT and the int type
802
00:32:47,880 --> 00:32:51,039
Alias is either int32 or int64 depending
803
00:32:51,039 --> 00:32:52,880
on your computer's architecture if you
804
00:32:52,880 --> 00:32:55,799
want to specify a particular size of
805
00:32:55,799 --> 00:32:57,960
integer then you would declare it using
806
00:32:57,960 --> 00:33:00,600
this kind of lonand syntax so in this
807
00:33:00,600 --> 00:33:02,760
assignment we're just meant to declare a
808
00:33:02,760 --> 00:33:05,320
variable named congrats with the value
809
00:33:05,320 --> 00:33:07,120
happy birthday using a short variable
810
00:33:07,120 --> 00:33:10,440
declaration so as simple as congrats
811
00:33:10,440 --> 00:33:14,399
colon equals the string happy
812
00:33:14,399 --> 00:33:17,320
birthday let me run
813
00:33:17,320 --> 00:33:19,679
that
814
00:33:19,679 --> 00:33:22,120
perfect this next assignment says our
815
00:33:22,120 --> 00:33:24,559
current price to send a text message in
816
00:33:24,559 --> 00:33:27,559
texo is 2 cents however it's likely in
817
00:33:27,559 --> 00:33:29,080
the future that the price will have to
818
00:33:29,080 --> 00:33:31,080
be a fraction of a penny or have a
819
00:33:31,080 --> 00:33:33,399
fractional part to the cost so we should
820
00:33:33,399 --> 00:33:36,000
use a float 64 to store this value edit
821
00:33:36,000 --> 00:33:38,880
the pennies per text declaration so that
822
00:33:38,880 --> 00:33:40,480
it's inferred by the compiler to be a
823
00:33:40,480 --> 00:33:43,360
float 64 Okay cool so
824
00:33:43,360 --> 00:33:46,639
here we're just setting it equal to two
825
00:33:46,639 --> 00:33:49,559
if I run that then I get the type of
826
00:33:49,559 --> 00:33:53,039
pennies per text is int and this percent
827
00:33:53,039 --> 00:33:58,120
T in go um is is a formatting verb that
828
00:33:58,120 --> 00:33:59,880
that tells the go programming language
829
00:33:59,880 --> 00:34:01,720
or or at least the print F function I
830
00:34:01,720 --> 00:34:03,200
should say the formatting package from
831
00:34:03,200 --> 00:34:05,279
the standard Library um that I want to
832
00:34:05,279 --> 00:34:07,440
print the type of this variable rather
833
00:34:07,440 --> 00:34:08,879
than its value so that's why we're
834
00:34:08,879 --> 00:34:11,399
saying int there instead of
835
00:34:11,399 --> 00:34:14,240
two um to get a float all we need to do
836
00:34:14,240 --> 00:34:18,119
is change it from two to 2.0 I believe
837
00:34:18,119 --> 00:34:19,800
64
838
00:34:19,800 --> 00:34:22,720
cool another handy syntactic Quirk of
839
00:34:22,720 --> 00:34:23,960
the go programming language is that we
840
00:34:23,960 --> 00:34:26,280
can declare multiple values on the same
841
00:34:26,280 --> 00:34:28,119
line so in this assignment it says
842
00:34:28,119 --> 00:34:29,919
declare a float called average open rate
843
00:34:29,919 --> 00:34:32,079
and a string called display message on
844
00:34:32,079 --> 00:34:35,320
the same line okay so average open
845
00:34:35,320 --> 00:34:38,200
rate display
846
00:34:38,200 --> 00:34:41,639
message same line the average open rate
847
00:34:41,639 --> 00:34:44,200
um must
848
00:34:45,639 --> 00:34:48,839
be23 and the display message should be
849
00:34:48,839 --> 00:34:49,960
the
850
00:34:49,960 --> 00:34:52,520
string is the average open rate of your
851
00:34:52,520 --> 00:34:57,760
message and then it looks like
852
00:34:58,680 --> 00:34:59,960
this is just going to print them
853
00:34:59,960 --> 00:35:02,040
together so it's going to say 0.23 is
854
00:35:02,040 --> 00:35:03,880
the average open rate okay cool let's go
855
00:35:03,880 --> 00:35:06,040
ahead and run
856
00:35:06,040 --> 00:35:08,359
that 023 is the average open rate of
857
00:35:08,359 --> 00:35:10,320
your messages that looks correct to
858
00:35:10,320 --> 00:35:13,320
me so we've already briefly talked about
859
00:35:13,320 --> 00:35:15,839
the different type sizes in go right so
860
00:35:15,839 --> 00:35:19,200
we have the int type int 8 int 16 int 32
861
00:35:19,200 --> 00:35:21,320
and int 64 and it's important to
862
00:35:21,320 --> 00:35:24,040
understand that the int type just
863
00:35:24,040 --> 00:35:27,880
aliases int32 or int64 um same with the
864
00:35:27,880 --> 00:35:30,560
uint type just depending on your cpu's
865
00:35:30,560 --> 00:35:32,440
architecture so you might be on a 32 or
866
00:35:32,440 --> 00:35:35,000
a 64-bit machine most modern machines
867
00:35:35,000 --> 00:35:37,520
are going to be 64 bits my
868
00:35:37,520 --> 00:35:39,960
recommendation is that unless you have
869
00:35:39,960 --> 00:35:42,640
an explicit reason to care about the
870
00:35:42,640 --> 00:35:45,000
size right so unless you're trying to
871
00:35:45,000 --> 00:35:47,160
kind of hyper optimize for performance
872
00:35:47,160 --> 00:35:48,520
then you should really just stick to
873
00:35:48,520 --> 00:35:52,240
these four types int uint float 64 and
874
00:35:52,240 --> 00:35:53,680
again if you're working with imaginary
875
00:35:53,680 --> 00:35:56,400
numbers then complex 128 but that's
876
00:35:56,400 --> 00:35:58,960
honestly unlikely so so these three
877
00:35:58,960 --> 00:36:01,839
types are going to do the vast majority
878
00:36:01,839 --> 00:36:03,560
of the heavy lifting when it comes to
879
00:36:03,560 --> 00:36:06,000
working with numbers in go we can also
880
00:36:06,000 --> 00:36:08,000
convert numbers between you know
881
00:36:08,000 --> 00:36:10,000
different number types for example we
882
00:36:10,000 --> 00:36:13,760
could take a an integer 88 and convert
883
00:36:13,760 --> 00:36:16,280
it to a float like this so it become
884
00:36:16,280 --> 00:36:18,680
88.0 right um converting the other way
885
00:36:18,680 --> 00:36:20,000
is a little trickier though because say
886
00:36:20,000 --> 00:36:22,440
we had 88.6 if we were to convert it to
887
00:36:22,440 --> 00:36:24,480
an INT we would lose the point 6 we
888
00:36:24,480 --> 00:36:27,760
would truncate it down to just 88 now
889
00:36:27,760 --> 00:36:29,520
this assignment says our text AO
890
00:36:29,520 --> 00:36:31,440
customers want to know how long they've
891
00:36:31,440 --> 00:36:32,920
had accounts with us follow the
892
00:36:32,920 --> 00:36:34,160
instructions in the comment provided you
893
00:36:34,160 --> 00:36:35,400
will create a new variable called
894
00:36:35,400 --> 00:36:37,359
account age int that will be the
895
00:36:37,359 --> 00:36:39,960
truncated integer version of account age
896
00:36:39,960 --> 00:36:42,800
Okay cool so create a new account age
897
00:36:42,800 --> 00:36:45,520
int here should be the result of casting
898
00:36:45,520 --> 00:36:47,480
account age to an integer so we'll just
899
00:36:47,480 --> 00:36:50,160
do int account age and I would expect
900
00:36:50,160 --> 00:36:53,240
that to be two after casting it because
901
00:36:53,240 --> 00:36:55,839
it should truncate the 6 so let's go
902
00:36:55,839 --> 00:36:58,440
ahead and run that your account has
903
00:36:58,440 --> 00:37:00,839
existed for 2 years yeah that looks good
904
00:37:00,839 --> 00:37:01,920
to
905
00:37:01,920 --> 00:37:04,440
me we already briefly touched on this
906
00:37:04,440 --> 00:37:06,280
but it's worth mentioning again I
907
00:37:06,280 --> 00:37:08,240
recommend that you stick to the I call
908
00:37:08,240 --> 00:37:10,760
them the default types so for example we
909
00:37:10,760 --> 00:37:13,400
know there's um you know five or six I
910
00:37:13,400 --> 00:37:14,560
can't think of it off the top of my head
911
00:37:14,560 --> 00:37:17,359
now different types of inss right int
912
00:37:17,359 --> 00:37:21,240
int 8 int 16 in 32 int 64 I'd recommend
913
00:37:21,240 --> 00:37:23,200
sticking to int unless you have a very
914
00:37:23,200 --> 00:37:26,960
good reason to specify a smaller size
915
00:37:26,960 --> 00:37:29,839
like int 8 or in32 and that's simply so
916
00:37:29,839 --> 00:37:32,440
you avoid cluttering your code with tons
917
00:37:32,440 --> 00:37:34,760
of type conversions that can sometimes
918
00:37:34,760 --> 00:37:37,880
even lead to bugs so unless you need a
919
00:37:37,880 --> 00:37:40,240
smaller type for performance reasons
920
00:37:40,240 --> 00:37:44,680
just use these default types okay so the
921
00:37:44,680 --> 00:37:46,319
question for this assignment is when
922
00:37:46,319 --> 00:37:48,960
should you elect to not use a default
923
00:37:48,960 --> 00:37:51,960
type when either a default or a specific
924
00:37:51,960 --> 00:37:54,079
size will work when my system has lots
925
00:37:54,079 --> 00:37:56,160
of extra Hardware that I want to utilize
926
00:37:56,160 --> 00:37:57,640
or when performance and memory are
927
00:37:57,640 --> 00:38:00,400
primary concern so it's going to be
928
00:38:00,400 --> 00:38:02,359
performance if you have performance
929
00:38:02,359 --> 00:38:06,160
concerns that's the time I would maybe
930
00:38:06,160 --> 00:38:08,599
stray away from the default
931
00:38:08,599 --> 00:38:11,560
types the next question is what does the
932
00:38:11,560 --> 00:38:15,079
size of a type indicate so a float 64
933
00:38:15,079 --> 00:38:19,040
what does 64 mean is it bits bites or
934
00:38:19,040 --> 00:38:23,280
nibbles uh the answer is going to be
935
00:38:23,280 --> 00:38:25,760
bits now it is worth pointing out
936
00:38:25,760 --> 00:38:28,520
nibbles is a real thing so a bite is 8
937
00:38:28,520 --> 00:38:31,520
Bits a nibble is actually Four bits if
938
00:38:31,520 --> 00:38:34,680
you didn't know that fun interesting
939
00:38:34,680 --> 00:38:37,599
trivia aside from variables go also
940
00:38:37,599 --> 00:38:40,440
supports constants which are immutable
941
00:38:40,440 --> 00:38:43,119
values um and in go just like in
942
00:38:43,119 --> 00:38:44,560
JavaScript or typescript we use the
943
00:38:44,560 --> 00:38:47,400
const keyword and constants do not
944
00:38:47,400 --> 00:38:50,119
support the short declaration syntax so
945
00:38:50,119 --> 00:38:52,319
we have to kind of write it all
946
00:38:52,319 --> 00:38:54,560
out okay so getting to the assignment
947
00:38:54,560 --> 00:38:56,280
says use two separate constants
948
00:38:56,280 --> 00:38:57,520
something weird is happening in this
949
00:38:57,520 --> 00:38:59,240
code what should be happening is that we
950
00:38:59,240 --> 00:39:01,680
create two separate constants Premium
951
00:39:01,680 --> 00:39:03,960
plan name and basic plan name right now
952
00:39:03,960 --> 00:39:05,280
looks like we're trying to overwrite one
953
00:39:05,280 --> 00:39:07,720
of them okay cool so on line six we've
954
00:39:07,720 --> 00:39:10,160
got Premium plan name and we're setting
955
00:39:10,160 --> 00:39:11,400
it to Premium plan and then we have
956
00:39:11,400 --> 00:39:14,319
Premium plan name again attempting to
957
00:39:14,319 --> 00:39:17,640
override the value and set it to a new
958
00:39:17,640 --> 00:39:19,680
string if we try to run this we actually
959
00:39:19,680 --> 00:39:22,560
get a compile time error so we're not
960
00:39:22,560 --> 00:39:26,240
allowed to mutate constants in go so
961
00:39:26,240 --> 00:39:28,520
what we should be doing is creating a
962
00:39:28,520 --> 00:39:31,160
separate constant and it should be named
963
00:39:31,160 --> 00:39:34,839
basic plan name let's go ahead and run
964
00:39:34,839 --> 00:39:38,680
that plan Premium plan plan basic plan
965
00:39:38,680 --> 00:39:42,359
looks good to me constants in go are not
966
00:39:42,359 --> 00:39:44,839
the same as constants in JavaScript and
967
00:39:44,839 --> 00:39:46,800
in typescript in JavaScript and
968
00:39:46,800 --> 00:39:48,520
typescript the const keyword really just
969
00:39:48,520 --> 00:39:50,680
means you can't reassign to this
970
00:39:50,680 --> 00:39:52,480
variable but you can compute the
971
00:39:52,480 --> 00:39:54,560
variable or the variable's value at
972
00:39:54,560 --> 00:39:57,839
runtime in go every value
973
00:39:57,839 --> 00:40:00,240
that's stored in a constant must be
974
00:40:00,240 --> 00:40:04,000
known or computed at compile time before
975
00:40:04,000 --> 00:40:06,880
the program runs so if we create this
976
00:40:06,880 --> 00:40:09,240
new constant called my int and set it
977
00:40:09,240 --> 00:40:11,960
equal to 15 within the compiled go
978
00:40:11,960 --> 00:40:14,680
binary effectively this symbol my in
979
00:40:14,680 --> 00:40:17,560
just refers to the static number
980
00:40:17,560 --> 00:40:20,560
15 the cool thing is that we can
981
00:40:20,560 --> 00:40:23,160
actually compute constants like we can
982
00:40:23,160 --> 00:40:24,880
make constants that depend on other
983
00:40:24,880 --> 00:40:28,040
constants but that computation will run
984
00:40:28,040 --> 00:40:30,800
when we compile our code not when we run
985
00:40:30,800 --> 00:40:33,880
our code so for example um I can create
986
00:40:33,880 --> 00:40:36,119
this constant first name Lane last name
987
00:40:36,119 --> 00:40:37,440
Wagner and then I can create a new
988
00:40:37,440 --> 00:40:39,359
constant called full name it's first
989
00:40:39,359 --> 00:40:41,920
name plus a space plus and the last name
990
00:40:41,920 --> 00:40:43,520
and that's really convenient in case I
991
00:40:43,520 --> 00:40:45,760
ever want to change first name uh now I
992
00:40:45,760 --> 00:40:47,079
don't have to change it in two places
993
00:40:47,079 --> 00:40:48,560
right full name will automatically
994
00:40:48,560 --> 00:40:51,280
update but this is only valid because
995
00:40:51,280 --> 00:40:53,920
all of the inputs to this full name
996
00:40:53,920 --> 00:40:55,800
constant first name and last name are
997
00:40:55,800 --> 00:40:58,359
known at compile time so the compiler
998
00:40:58,359 --> 00:41:00,640
can still do the thing it wants to do
999
00:41:00,640 --> 00:41:03,319
which is replace full name with a static
1000
00:41:03,319 --> 00:41:05,480
string right lane space
1001
00:41:05,480 --> 00:41:08,720
Wagner so on to the assignment says
1002
00:41:08,720 --> 00:41:10,599
keeping track of time in a message
1003
00:41:10,599 --> 00:41:12,640
sending application like textio is
1004
00:41:12,640 --> 00:41:14,599
critical imagine getting at a point
1005
00:41:14,599 --> 00:41:17,079
reminder an hour after your doctor's
1006
00:41:17,079 --> 00:41:19,680
visit not very helpful right complete
1007
00:41:19,680 --> 00:41:21,280
the code using a computed constant to
1008
00:41:21,280 --> 00:41:24,160
print the number of seconds in an hour
1009
00:41:24,160 --> 00:41:25,880
okay so we've got the number of seconds
1010
00:41:25,880 --> 00:41:28,640
in a minute is 60 the number of minutes
1011
00:41:28,640 --> 00:41:31,079
in an hour is also 60 so how many
1012
00:41:31,079 --> 00:41:33,400
seconds are in an hour cool well we
1013
00:41:33,400 --> 00:41:37,720
could hardcode this as like 60 *
1014
00:41:37,720 --> 00:41:39,960
60 but the cool thing is we can actually
1015
00:41:39,960 --> 00:41:41,599
compute it because we can say well we
1016
00:41:41,599 --> 00:41:43,160
know the minutes the number of minutes
1017
00:41:43,160 --> 00:41:45,160
in an hour and we know the number of
1018
00:41:45,160 --> 00:41:48,000
seconds in a
1019
00:41:48,000 --> 00:41:50,280
minute and if we multiply those two
1020
00:41:50,280 --> 00:41:51,480
together we should get the number of
1021
00:41:51,480 --> 00:41:54,800
seconds in an hour
1022
00:41:55,800 --> 00:41:59,359
right that looks correct to
1023
00:41:59,359 --> 00:42:03,119
me so I'm obviously a huge go fan but
1024
00:42:03,119 --> 00:42:05,400
formatting strings in go is honestly one
1025
00:42:05,400 --> 00:42:07,680
of my least favorite features of the
1026
00:42:07,680 --> 00:42:08,800
language I think it's one of its
1027
00:42:08,800 --> 00:42:10,640
weaknesses at the moment who knows maybe
1028
00:42:10,640 --> 00:42:12,599
it'll improve in the future the way it's
1029
00:42:12,599 --> 00:42:14,520
done well we essentially have two
1030
00:42:14,520 --> 00:42:16,280
different functions provided to us by
1031
00:42:16,280 --> 00:42:18,440
the standard Library we have print F and
1032
00:42:18,440 --> 00:42:22,319
S printf printf prints a formatted
1033
00:42:22,319 --> 00:42:25,040
string directly to standard out and S
1034
00:42:25,040 --> 00:42:27,960
printf just Returns the formatted string
1035
00:42:27,960 --> 00:42:29,960
as a value basically all string
1036
00:42:29,960 --> 00:42:32,200
formatting in go currently works the
1037
00:42:32,200 --> 00:42:35,280
same way we have these formatting verbs
1038
00:42:35,280 --> 00:42:38,160
things like percent V percent s percent
1039
00:42:38,160 --> 00:42:41,920
D and they're replaced in the string
1040
00:42:41,920 --> 00:42:44,200
template with actual values so for
1041
00:42:44,200 --> 00:42:47,880
example I am percent V years old the
1042
00:42:47,880 --> 00:42:51,000
percent V in this case is replaced by 10
1043
00:42:51,000 --> 00:42:53,760
the first parameter uh that comes after
1044
00:42:53,760 --> 00:42:57,640
the template in the print F function
1045
00:42:57,640 --> 00:43:00,000
here we could also replace with a string
1046
00:43:00,000 --> 00:43:02,160
instead of an integer right I am percent
1047
00:43:02,160 --> 00:43:04,880
V years old way too many for I am way
1048
00:43:04,880 --> 00:43:07,760
too many years old percent V is sort of
1049
00:43:07,760 --> 00:43:11,079
the default formatter it's usually what
1050
00:43:11,079 --> 00:43:13,720
you want assume you don't want to print
1051
00:43:13,720 --> 00:43:15,400
in kind of the default standard way
1052
00:43:15,400 --> 00:43:17,640
using percent V then there are a few
1053
00:43:17,640 --> 00:43:19,800
others um percent S interpolates A
1054
00:43:19,800 --> 00:43:22,680
String percent D interpolates an integer
1055
00:43:22,680 --> 00:43:25,440
in decimal form so for example 10
1056
00:43:25,440 --> 00:43:27,480
becomes the number 10 instead of say in
1057
00:43:27,480 --> 00:43:30,640
binary form uh percent s is for floats
1058
00:43:30,640 --> 00:43:34,000
so you can specify the number of kind of
1059
00:43:34,000 --> 00:43:36,440
places after the decimal point uh that
1060
00:43:36,440 --> 00:43:38,640
you want printed out to the console or
1061
00:43:38,640 --> 00:43:40,680
printed out to The Returned string in
1062
00:43:40,680 --> 00:43:44,680
the case of s printf um so I actually do
1063
00:43:44,680 --> 00:43:47,960
end up using percent F fairly regularly
1064
00:43:47,960 --> 00:43:50,400
when I'm working with floats so onto the
1065
00:43:50,400 --> 00:43:52,079
assignment it says create a new variable
1066
00:43:52,079 --> 00:43:55,480
called MSG online 9 MSG stands for
1067
00:43:55,480 --> 00:43:57,400
message of course um it's a string that
1068
00:43:57,400 --> 00:43:59,160
contains the following High name your
1069
00:43:59,160 --> 00:44:01,480
open rate is open rate percent where
1070
00:44:01,480 --> 00:44:03,280
name is the given name and open rate is
1071
00:44:03,280 --> 00:44:05,079
the open rate rounded to the nearest
1072
00:44:05,079 --> 00:44:08,960
10's place okay so the 10's place is the
1073
00:44:08,960 --> 00:44:11,599
number right after the decimal so let's
1074
00:44:11,599 --> 00:44:14,319
get started here message colon equals
1075
00:44:14,319 --> 00:44:18,119
fmt dos printf so we're going to use S
1076
00:44:18,119 --> 00:44:20,599
printf instead of print F because we
1077
00:44:20,599 --> 00:44:21,920
don't want this value going to standard
1078
00:44:21,920 --> 00:44:24,240
out we want it returned from the
1079
00:44:24,240 --> 00:44:26,680
function so we can save it in the MSG
1080
00:44:26,680 --> 00:44:29,040
variable
1081
00:44:29,200 --> 00:44:31,400
let's just grab this
1082
00:44:31,400 --> 00:44:34,880
template so we'll use percent s we could
1083
00:44:34,880 --> 00:44:37,160
use percent s or percent V here because
1084
00:44:37,160 --> 00:44:39,760
we're just uh interpolating a string and
1085
00:44:39,760 --> 00:44:45,800
we'll do percent um .1 F because we
1086
00:44:45,800 --> 00:44:49,599
want to just print the
1087
00:44:49,599 --> 00:44:52,480
first number after the the decimal point
1088
00:44:52,480 --> 00:44:53,960
right the tenth
1089
00:44:53,960 --> 00:44:58,040
place okay and then we just pass the two
1090
00:44:58,040 --> 00:45:00,800
values as the following parameters or as
1091
00:45:00,800 --> 00:45:04,400
the last two parameters so name and open
1092
00:45:04,400 --> 00:45:07,480
rate right so the first value name will
1093
00:45:07,480 --> 00:45:09,400
go into the first verb the second value
1094
00:45:09,400 --> 00:45:11,559
will go into the second verb let's run
1095
00:45:11,559 --> 00:45:14,359
that see what we get hi s Goodman your
1096
00:45:14,359 --> 00:45:15,640
open rate is
1097
00:45:15,640 --> 00:45:18,680
30.5% that looks good to me let's talk
1098
00:45:18,680 --> 00:45:20,880
about conditionals in go so a
1099
00:45:20,880 --> 00:45:22,079
conditional is just where we are
1100
00:45:22,079 --> 00:45:24,319
checking if a condition is true if it is
1101
00:45:24,319 --> 00:45:26,599
we do one thing if it's not we may do
1102
00:45:26,599 --> 00:45:28,960
another so for example uh here's an if
1103
00:45:28,960 --> 00:45:33,079
statement in go and if this expression
1104
00:45:33,079 --> 00:45:36,440
evaluates to true then we'll run the
1105
00:45:36,440 --> 00:45:38,480
stuff within the curly braces the body
1106
00:45:38,480 --> 00:45:40,119
of the estatement if you're familiar
1107
00:45:40,119 --> 00:45:41,319
with other programming languages like
1108
00:45:41,319 --> 00:45:43,559
JavaScript this is um a very very
1109
00:45:43,559 --> 00:45:45,160
similar syntax the only difference is
1110
00:45:45,160 --> 00:45:47,079
we're not surrounding the height is
1111
00:45:47,079 --> 00:45:49,520
greater than four section with um
1112
00:45:49,520 --> 00:45:53,000
parentheses so again to be clear this
1113
00:45:53,000 --> 00:45:56,200
bit between the if keyword and the curly
1114
00:45:56,200 --> 00:45:59,040
brace um will be evaluated and if it
1115
00:45:59,040 --> 00:46:02,200
evaluates to true then the stuff inside
1116
00:46:02,200 --> 00:46:06,319
the curly braces will be executed um so
1117
00:46:06,319 --> 00:46:08,240
in this case we have the variable height
1118
00:46:08,240 --> 00:46:10,640
and we're using the greater than
1119
00:46:10,640 --> 00:46:12,960
operator um to compare it to the number
1120
00:46:12,960 --> 00:46:15,040
four so if height is greater than four
1121
00:46:15,040 --> 00:46:17,359
then we'll print you are tall enough
1122
00:46:17,359 --> 00:46:19,160
sort of listed um some of the different
1123
00:46:19,160 --> 00:46:21,599
comparison operators uh down here at the
1124
00:46:21,599 --> 00:46:23,800
bottom they are basically identical to
1125
00:46:23,800 --> 00:46:24,839
pretty much every other programming
1126
00:46:24,839 --> 00:46:27,599
language you will uh probably have used
1127
00:46:27,599 --> 00:46:30,520
uh up to this point additionally we can
1128
00:46:30,520 --> 00:46:33,520
do different things um if the if
1129
00:46:33,520 --> 00:46:36,160
statement does not evaluate to true so
1130
00:46:36,160 --> 00:46:37,720
this is a perfectly valid if statement
1131
00:46:37,720 --> 00:46:41,440
you do not need an else if or an else
1132
00:46:41,440 --> 00:46:43,559
block they are they're optional
1133
00:46:43,559 --> 00:46:46,559
effectively um but the way it works is
1134
00:46:46,559 --> 00:46:48,920
when we get to this code uh basically
1135
00:46:48,920 --> 00:46:51,280
we'll we'll uh compare height to six
1136
00:46:51,280 --> 00:46:52,720
right and if that expression evaluates
1137
00:46:52,720 --> 00:46:54,720
to true then we'll just print you are
1138
00:46:54,720 --> 00:46:57,520
super tall and we'll be done
1139
00:46:57,520 --> 00:47:00,319
okay otherwise if that expression
1140
00:47:00,319 --> 00:47:02,559
evaluates to false then we'll drop down
1141
00:47:02,559 --> 00:47:05,880
into this next if else or sorry else if
1142
00:47:05,880 --> 00:47:08,000
statement and we'll compare height to
1143
00:47:08,000 --> 00:47:10,680
four if height is greater than four then
1144
00:47:10,680 --> 00:47:13,440
we'll print you are tall enough and
1145
00:47:13,440 --> 00:47:15,559
again we'll be done at that point so if
1146
00:47:15,559 --> 00:47:18,880
this evaluates to true we execute this
1147
00:47:18,880 --> 00:47:20,400
um kind of section of code between the
1148
00:47:20,400 --> 00:47:23,040
curly braces and at that point we'll be
1149
00:47:23,040 --> 00:47:26,160
done otherwise if that's also false so
1150
00:47:26,160 --> 00:47:28,119
if height is not great than six and
1151
00:47:28,119 --> 00:47:30,359
height is not greater than four then the
1152
00:47:30,359 --> 00:47:33,079
else statement executes notice the else
1153
00:47:33,079 --> 00:47:34,400
statement does not have its own
1154
00:47:34,400 --> 00:47:36,400
expression it just kind of always
1155
00:47:36,400 --> 00:47:39,280
executes if all of the if and else if
1156
00:47:39,280 --> 00:47:42,880
statements um turned out to be false so
1157
00:47:42,880 --> 00:47:44,640
let's jump into the assignment it says
1158
00:47:44,640 --> 00:47:47,119
fix the bug on line 12 the if statement
1159
00:47:47,119 --> 00:47:49,960
should print message sent if the message
1160
00:47:49,960 --> 00:47:53,240
length is less than or equal to the max
1161
00:47:53,240 --> 00:47:55,880
message length or message not sent
1162
00:47:55,880 --> 00:47:58,480
otherwise Okay cool so up here we've
1163
00:47:58,480 --> 00:48:00,280
defined two variables uh message length
1164
00:48:00,280 --> 00:48:03,480
is 10 Max message length is 20 um and
1165
00:48:03,480 --> 00:48:04,839
then here we're going to do some
1166
00:48:04,839 --> 00:48:06,319
comparing let me just run the code in
1167
00:48:06,319 --> 00:48:08,119
its current
1168
00:48:08,119 --> 00:48:10,359
state says trying to send a message of
1169
00:48:10,359 --> 00:48:14,400
length 10 and a max length of 20 message
1170
00:48:14,400 --> 00:48:17,040
not sent okay so that seems problematic
1171
00:48:17,040 --> 00:48:18,720
right because with a message length of
1172
00:48:18,720 --> 00:48:21,559
10 and a Max message length of 20 I
1173
00:48:21,559 --> 00:48:24,400
should be able to send that message so
1174
00:48:24,400 --> 00:48:26,440
the Bug Online 12 I think we just need
1175
00:48:26,440 --> 00:48:28,880
to flip this operator to be less than or
1176
00:48:28,880 --> 00:48:32,520
equal to so that now this expression
1177
00:48:32,520 --> 00:48:34,200
right message length less than or equal
1178
00:48:34,200 --> 00:48:37,640
to Max message length should evaluate to
1179
00:48:37,640 --> 00:48:41,040
true because it is message length is in
1180
00:48:41,040 --> 00:48:44,480
fact smaller okay let's run
1181
00:48:46,240 --> 00:48:49,720
that message sent that seems to work
1182
00:48:49,720 --> 00:48:51,520
it's worth pointing out that in go we
1183
00:48:51,520 --> 00:48:53,400
also have kind of an alternate way to
1184
00:48:53,400 --> 00:48:54,400
write if
1185
00:48:54,400 --> 00:48:57,680
statements if the variable that we are
1186
00:48:57,680 --> 00:49:01,319
comparing in an if statement is only
1187
00:49:01,319 --> 00:49:04,040
used in that if statement then this
1188
00:49:04,040 --> 00:49:06,880
syntax can be helpful okay so here's
1189
00:49:06,880 --> 00:49:08,200
kind of the traditional way of doing
1190
00:49:08,200 --> 00:49:09,799
something we would create a variable
1191
00:49:09,799 --> 00:49:11,319
called length let's just assume it's an
1192
00:49:11,319 --> 00:49:13,160
integer you can kind of forget um this
1193
00:49:13,160 --> 00:49:15,400
function Syntax for now we'll talk about
1194
00:49:15,400 --> 00:49:18,480
it um in a future chapter but basically
1195
00:49:18,480 --> 00:49:19,839
the idea here is we have a length
1196
00:49:19,839 --> 00:49:21,839
variable it's an integer right and we're
1197
00:49:21,839 --> 00:49:23,799
initializing it here we're creating the
1198
00:49:23,799 --> 00:49:26,720
variable here um and then we're compar
1199
00:49:26,720 --> 00:49:27,960
pairing it against one right we're
1200
00:49:27,960 --> 00:49:29,240
checking if it's less than one and if it
1201
00:49:29,240 --> 00:49:30,520
is we're doing something in this case
1202
00:49:30,520 --> 00:49:32,799
we're printing that the email is invalid
1203
00:49:32,799 --> 00:49:35,240
well instead of this syntax and by the
1204
00:49:35,240 --> 00:49:36,599
way this works perfectly fine there's
1205
00:49:36,599 --> 00:49:39,000
nothing wrong with doing it this way um
1206
00:49:39,000 --> 00:49:40,480
but we can alternately do it this way
1207
00:49:40,480 --> 00:49:42,920
which is basically to initialize that
1208
00:49:42,920 --> 00:49:46,319
length variable in the if block within
1209
00:49:46,319 --> 00:49:49,200
that first kind of initial statement so
1210
00:49:49,200 --> 00:49:51,119
notice there's two statements here um
1211
00:49:51,119 --> 00:49:52,319
separated by a
1212
00:49:52,319 --> 00:49:54,400
semicolon and in the first one we're
1213
00:49:54,400 --> 00:49:56,760
creating that length variable and then
1214
00:49:56,760 --> 00:50:00,040
then we're moving the comparison itself
1215
00:50:00,040 --> 00:50:02,920
kind of after the semicolon and then if
1216
00:50:02,920 --> 00:50:05,200
that condition obviously evaluates to
1217
00:50:05,200 --> 00:50:07,559
true then we'll um execute the block
1218
00:50:07,559 --> 00:50:09,000
this does kind of two things for us
1219
00:50:09,000 --> 00:50:11,960
first it saves us a line of code um
1220
00:50:11,960 --> 00:50:13,400
which I would argue probably isn't the
1221
00:50:13,400 --> 00:50:15,920
biggest benefit in the world um but more
1222
00:50:15,920 --> 00:50:18,200
importantly uh it makes it so that this
1223
00:50:18,200 --> 00:50:21,880
length variable is only accessible
1224
00:50:21,880 --> 00:50:24,720
within uh kind of the scope of this if
1225
00:50:24,720 --> 00:50:27,400
block so kind of down under Neath this
1226
00:50:27,400 --> 00:50:29,000
code we wouldn't be able to use the
1227
00:50:29,000 --> 00:50:31,000
length uh variable anymore which is kind
1228
00:50:31,000 --> 00:50:33,480
of nice if you never intended to use it
1229
00:50:33,480 --> 00:50:35,960
in the first place you can kind of think
1230
00:50:35,960 --> 00:50:39,359
of this as a clean code hack or like a
1231
00:50:39,359 --> 00:50:43,240
um kind of safety hack um to ensure that
1232
00:50:43,240 --> 00:50:45,920
the length variable is never reused Down
1233
00:50:45,920 --> 00:50:47,920
Below in other code when you never
1234
00:50:47,920 --> 00:50:51,960
intended it to be reused okay so uh the
1235
00:50:51,960 --> 00:50:53,799
question for this assignment is why
1236
00:50:53,799 --> 00:50:56,119
would you use the initial section of an
1237
00:50:56,119 --> 00:50:58,599
if statement uh and the answers are to
1238
00:50:58,599 --> 00:51:00,000
confuse other programmers to keep the
1239
00:51:00,000 --> 00:51:02,200
code concise and the scope limited or to
1240
00:51:02,200 --> 00:51:04,839
speed up your code um the answer is
1241
00:51:04,839 --> 00:51:06,079
going to be to keep the code more
1242
00:51:06,079 --> 00:51:08,799
concise and to again limit the scope
1243
00:51:08,799 --> 00:51:13,280
that that variable um exists within like
1244
00:51:13,280 --> 00:51:15,520
other programming languages go supports
1245
00:51:15,520 --> 00:51:17,079
functions functions are basically just a
1246
00:51:17,079 --> 00:51:19,240
way to break up your code into
1247
00:51:19,240 --> 00:51:21,880
individual units that are easier to
1248
00:51:21,880 --> 00:51:24,119
reason about right a function takes in a
1249
00:51:24,119 --> 00:51:26,319
specified number of inputs and it
1250
00:51:26,319 --> 00:51:28,040
returns ears a specified number of
1251
00:51:28,040 --> 00:51:30,760
outputs for example this subtract
1252
00:51:30,760 --> 00:51:33,960
function here named sub takes two inputs
1253
00:51:33,960 --> 00:51:36,720
X and integer and Y an integer and it
1254
00:51:36,720 --> 00:51:39,359
returns a single integer in this case it
1255
00:51:39,359 --> 00:51:42,000
just performs the simple calculation x -
1256
00:51:42,000 --> 00:51:44,960
Y and then Returns the result to the CER
1257
00:51:44,960 --> 00:51:47,599
now this little bit right here right
1258
00:51:47,599 --> 00:51:51,440
Funk sub X integer y integer returns
1259
00:51:51,440 --> 00:51:54,079
integer is what's known as the function
1260
00:51:54,079 --> 00:51:55,720
signature if you've never heard that
1261
00:51:55,720 --> 00:51:57,799
term before it's basically just a
1262
00:51:57,799 --> 00:52:01,280
description of what the function does in
1263
00:52:01,280 --> 00:52:03,000
terms of its types in terms of its
1264
00:52:03,000 --> 00:52:05,599
inputs and its outputs and what types
1265
00:52:05,599 --> 00:52:08,000
they are right this basically says this
1266
00:52:08,000 --> 00:52:10,160
is a function called sub it takes an
1267
00:52:10,160 --> 00:52:13,000
integer X and an integer Y and returns
1268
00:52:13,000 --> 00:52:15,319
another integer function signatures are
1269
00:52:15,319 --> 00:52:16,920
great because they tell us how we can
1270
00:52:16,920 --> 00:52:18,880
use the functions really at the end of
1271
00:52:18,880 --> 00:52:20,559
the day if we're the person calling the
1272
00:52:20,559 --> 00:52:22,000
function or the person using the
1273
00:52:22,000 --> 00:52:24,640
function really all we care about is
1274
00:52:24,640 --> 00:52:26,240
what we need to give the function as
1275
00:52:26,240 --> 00:52:28,200
input and what we get out of the
1276
00:52:28,200 --> 00:52:30,359
function in terms of its outputs so a
1277
00:52:30,359 --> 00:52:32,079
function signature basically tells us
1278
00:52:32,079 --> 00:52:34,000
all we need to know about a function to
1279
00:52:34,000 --> 00:52:36,559
be able to use it it omits all of the
1280
00:52:36,559 --> 00:52:38,680
implementation details the stuff with
1281
00:52:38,680 --> 00:52:40,520
within the curly brackets or within the
1282
00:52:40,520 --> 00:52:43,440
body of the function so let's get on to
1283
00:52:43,440 --> 00:52:45,520
the assignment assignment says we often
1284
00:52:45,520 --> 00:52:46,960
need to manipulate strings in our
1285
00:52:46,960 --> 00:52:48,359
messaging app that makes sense right
1286
00:52:48,359 --> 00:52:50,760
we're working with SMS and email uh
1287
00:52:50,760 --> 00:52:52,440
messages within textio so we're doing a
1288
00:52:52,440 --> 00:52:55,880
lot of textual data manipulation the
1289
00:52:55,880 --> 00:52:58,400
concat function should take two strings
1290
00:52:58,400 --> 00:53:00,839
as inputs and smash them together right
1291
00:53:00,839 --> 00:53:02,839
so returning a new string that is a
1292
00:53:02,839 --> 00:53:04,880
concatenation of the inputs for example
1293
00:53:04,880 --> 00:53:08,839
hello Plus World equals hello world so
1294
00:53:08,839 --> 00:53:12,240
we'd expect to return this concatenated
1295
00:53:12,240 --> 00:53:14,760
string from our concat function over
1296
00:53:14,760 --> 00:53:17,559
here fix the function the function
1297
00:53:17,559 --> 00:53:19,480
signature of concat to reflect its
1298
00:53:19,480 --> 00:53:21,240
Behavior Okay cool so let me try running
1299
00:53:21,240 --> 00:53:23,640
this and just see what happens looks
1300
00:53:23,640 --> 00:53:25,440
like undefined
1301
00:53:25,440 --> 00:53:28,480
S1 undefined S2 undefined S1 okay so
1302
00:53:28,480 --> 00:53:29,359
these are
1303
00:53:29,359 --> 00:53:31,000
undefined
1304
00:53:31,000 --> 00:53:33,599
and so S1 and S2 that kind of stands for
1305
00:53:33,599 --> 00:53:35,480
string one string two that makes sense
1306
00:53:35,480 --> 00:53:37,839
the problem here is that we're
1307
00:53:37,839 --> 00:53:40,799
not we're not telling
1308
00:53:40,799 --> 00:53:44,280
go what the types of the inputs should
1309
00:53:44,280 --> 00:53:47,040
be and this plus operator when operating
1310
00:53:47,040 --> 00:53:49,240
on strings just concatenates so that
1311
00:53:49,240 --> 00:53:53,040
should work let's go ahead and run
1312
00:53:54,000 --> 00:53:56,680
that yeah this looks good to me I want
1313
00:53:56,680 --> 00:53:59,319
to just make one more point about
1314
00:53:59,319 --> 00:54:01,319
function signatures in go you'll notice
1315
00:54:01,319 --> 00:54:03,599
that the type comes
1316
00:54:03,599 --> 00:54:06,640
after the name of the variable so S1 is
1317
00:54:06,640 --> 00:54:09,359
a string S2 is a string and that's just
1318
00:54:09,359 --> 00:54:10,839
to make it a little easier to read the
1319
00:54:10,839 --> 00:54:12,440
authors of the go programming language
1320
00:54:12,440 --> 00:54:15,480
kind of built on uh a lot of the ideas
1321
00:54:15,480 --> 00:54:17,720
from C and in C it was the reverse it
1322
00:54:17,720 --> 00:54:21,319
was string S1 string S2 and that just
1323
00:54:21,319 --> 00:54:23,680
kind of reads a little clunky if you're
1324
00:54:23,680 --> 00:54:25,400
used to kind of speaking in plain
1325
00:54:25,400 --> 00:54:27,559
English makes more sense for the type to
1326
00:54:27,559 --> 00:54:30,559
kind of come after um what it describes
1327
00:54:30,559 --> 00:54:32,400
go provides another bit of interesting
1328
00:54:32,400 --> 00:54:33,599
syntactic sugar when it comes to
1329
00:54:33,599 --> 00:54:35,680
function signatures when multiple
1330
00:54:35,680 --> 00:54:37,400
arguments are of the same type in this
1331
00:54:37,400 --> 00:54:39,680
case X and Y the inputs to the add
1332
00:54:39,680 --> 00:54:42,520
function are both integers um the type
1333
00:54:42,520 --> 00:54:44,960
only needs to be declared on the last
1334
00:54:44,960 --> 00:54:46,920
one assuming that they're in order right
1335
00:54:46,920 --> 00:54:49,400
so in this case this is valid go code
1336
00:54:49,400 --> 00:54:52,400
and X and Y are both integers because
1337
00:54:52,400 --> 00:54:54,599
they follow one another we can put the
1338
00:54:54,599 --> 00:54:57,240
integer um just after the y if we were
1339
00:54:57,240 --> 00:54:59,319
going to add say a string as a third
1340
00:54:59,319 --> 00:55:01,240
parameter uh to this function then we
1341
00:55:01,240 --> 00:55:03,599
would just add a comma here after int
1342
00:55:03,599 --> 00:55:05,799
and put you know name String or or
1343
00:55:05,799 --> 00:55:07,440
whatever um this is just a bit of
1344
00:55:07,440 --> 00:55:09,559
syntactic sugar uh it makes our code a
1345
00:55:09,559 --> 00:55:11,760
little less verbose you don't need to do
1346
00:55:11,760 --> 00:55:13,760
this you can explicitly put the type on
1347
00:55:13,760 --> 00:55:15,520
every input and output but you will
1348
00:55:15,520 --> 00:55:17,440
often see code like this it's a
1349
00:55:17,440 --> 00:55:19,799
convenient shorthand so we've got these
1350
00:55:19,799 --> 00:55:23,640
two um example Snippets of code Funk
1351
00:55:23,640 --> 00:55:25,599
create user first name String last name
1352
00:55:25,599 --> 00:55:28,240
String age in and Funk create user first
1353
00:55:28,240 --> 00:55:31,039
name last name String agent so which of
1354
00:55:31,039 --> 00:55:32,799
the following is the most succinct way
1355
00:55:32,799 --> 00:55:34,520
to write a function signature Su synct
1356
00:55:34,520 --> 00:55:37,000
is just another word for kind of it's I
1357
00:55:37,000 --> 00:55:38,920
guess it's the opposite of verbose right
1358
00:55:38,920 --> 00:55:40,880
fewer fewer
1359
00:55:40,880 --> 00:55:43,240
words um it's going to be the one that
1360
00:55:43,240 --> 00:55:45,920
uses the syntactic sugar which is this
1361
00:55:45,920 --> 00:55:47,839
one because we're omitting the string
1362
00:55:47,839 --> 00:55:50,520
keyword after first name so we already
1363
00:55:50,520 --> 00:55:52,839
talked about this briefly the idea that
1364
00:55:52,839 --> 00:55:56,760
in go we specify the type of of a
1365
00:55:56,760 --> 00:55:59,079
variable after the variable name and
1366
00:55:59,079 --> 00:56:01,039
this is you know different from kind of
1367
00:56:01,039 --> 00:56:02,839
the C style way of doing things which if
1368
00:56:02,839 --> 00:56:05,000
you were to declare a variable Y and C
1369
00:56:05,000 --> 00:56:07,720
you would say int Y and really the
1370
00:56:07,720 --> 00:56:09,400
authors of the go programming language
1371
00:56:09,400 --> 00:56:10,839
just felt that that didn't flow
1372
00:56:10,839 --> 00:56:12,799
naturally from English it's not the way
1373
00:56:12,799 --> 00:56:16,680
we talk right we say x is an integer not
1374
00:56:16,680 --> 00:56:20,000
integer is X if you want to read up on
1375
00:56:20,000 --> 00:56:21,960
that decision and why they ended up uh
1376
00:56:21,960 --> 00:56:23,720
choosing that style then you can follow
1377
00:56:23,720 --> 00:56:25,039
this link here assuming you're following
1378
00:56:25,039 --> 00:56:27,680
Along on botev so the question is what
1379
00:56:27,680 --> 00:56:29,480
are we talking about when we discuss
1380
00:56:29,480 --> 00:56:32,200
this declaration syntax right this this
1381
00:56:32,200 --> 00:56:35,920
swapping of the name and the type um and
1382
00:56:35,920 --> 00:56:38,039
here are options the decision about
1383
00:56:38,039 --> 00:56:40,520
Campbell case versus snake case um the
1384
00:56:40,520 --> 00:56:42,200
style of language used to create new
1385
00:56:42,200 --> 00:56:44,599
variables types and functions guard
1386
00:56:44,599 --> 00:56:46,760
Clauses versus if else no the ever
1387
00:56:46,760 --> 00:56:49,119
important question of tabs versus spaces
1388
00:56:49,119 --> 00:56:50,280
no it's going to be the style of
1389
00:56:50,280 --> 00:56:52,079
language used to create new variables
1390
00:56:52,079 --> 00:56:54,359
types and functions related question is
1391
00:56:54,359 --> 00:56:56,839
Which languages declaration syntax reads
1392
00:56:56,839 --> 00:56:59,599
like English from right to left C or go
1393
00:56:59,599 --> 00:57:01,799
the answer is going to be go go supports
1394
00:57:01,799 --> 00:57:04,680
functions as data or basically the idea
1395
00:57:04,680 --> 00:57:06,520
that you can pass functions around your
1396
00:57:06,520 --> 00:57:08,920
program uh to be called in different
1397
00:57:08,920 --> 00:57:10,760
places callbacks right if you're
1398
00:57:10,760 --> 00:57:12,359
familiar with JavaScript then you're
1399
00:57:12,359 --> 00:57:14,240
probably familiar with the idea of a
1400
00:57:14,240 --> 00:57:15,839
callback it's a function that you could
1401
00:57:15,839 --> 00:57:17,880
pass to another function to be called
1402
00:57:17,880 --> 00:57:21,119
later this question deals with that idea
1403
00:57:21,119 --> 00:57:24,480
whenever we pass a call back in go the
1404
00:57:24,480 --> 00:57:27,000
type of the function Chang based on what
1405
00:57:27,000 --> 00:57:29,079
its inputs and outputs are so for
1406
00:57:29,079 --> 00:57:34,160
example here funk in in int is a
1407
00:57:34,160 --> 00:57:36,119
function that takes two integers as an
1408
00:57:36,119 --> 00:57:38,440
input and returns an integer and that's
1409
00:57:38,440 --> 00:57:41,680
going to be a different type than a
1410
00:57:41,680 --> 00:57:44,000
function that say took three integers as
1411
00:57:44,000 --> 00:57:46,599
input and returned an integer and if you
1412
00:57:46,599 --> 00:57:48,319
think about it it makes sense right if
1413
00:57:48,319 --> 00:57:50,359
I'm going to pass a function to another
1414
00:57:50,359 --> 00:57:52,599
function so that it can call it later it
1415
00:57:52,599 --> 00:57:54,720
kind of needs to know how many inputs
1416
00:57:54,720 --> 00:57:56,880
how many parameters it can pass into
1417
00:57:56,880 --> 00:57:58,839
that function if it's a function that
1418
00:57:58,839 --> 00:58:01,240
takes two inputs versus three inputs
1419
00:58:01,240 --> 00:58:02,839
then the caller is going to have to
1420
00:58:02,839 --> 00:58:05,400
write the code differently so we have to
1421
00:58:05,400 --> 00:58:08,000
treat every function signature as its
1422
00:58:08,000 --> 00:58:10,920
own unique type so this question is a
1423
00:58:10,920 --> 00:58:12,920
bit of a doozy I encourage you to pause
1424
00:58:12,920 --> 00:58:14,319
the video and try to work this one out
1425
00:58:14,319 --> 00:58:16,520
on your own um but basically it says
1426
00:58:16,520 --> 00:58:20,720
what is this hairy beast here right F
1427
00:58:20,720 --> 00:58:23,720
Funk Funk int int int int
1428
00:58:23,720 --> 00:58:27,559
int all right potential answers are a
1429
00:58:27,559 --> 00:58:30,599
function named F that takes as int takes
1430
00:58:30,599 --> 00:58:33,200
an INT as the argument and returns an
1431
00:58:33,200 --> 00:58:36,559
INT uh no it is not nearly that simple
1432
00:58:36,559 --> 00:58:39,480
right a function named F that takes a
1433
00:58:39,480 --> 00:58:42,599
function and an INT as arguments and
1434
00:58:42,599 --> 00:58:44,799
returns a function let's
1435
00:58:44,799 --> 00:58:48,039
see uh that right there is a full
1436
00:58:48,039 --> 00:58:51,400
function and an INT as arguments and
1437
00:58:51,400 --> 00:58:53,960
returns a function no this returns an
1438
00:58:53,960 --> 00:58:56,559
INT okay a function named f that takes a
1439
00:58:56,559 --> 00:58:58,200
function and an INT as arguments and
1440
00:58:58,200 --> 00:59:00,039
returns an INT that's what I believe it
1441
00:59:00,039 --> 00:59:02,559
will be function named F that takes a
1442
00:59:02,559 --> 00:59:04,559
function as the argument and returns an
1443
00:59:04,559 --> 00:59:08,799
INT yep that's not it so ju to be clear
1444
00:59:08,799 --> 00:59:12,400
f is a function it takes two
1445
00:59:12,400 --> 00:59:14,200
parameters a
1446
00:59:14,200 --> 00:59:16,480
function right a function of a specific
1447
00:59:16,480 --> 00:59:18,960
type a function that takes two ins and
1448
00:59:18,960 --> 00:59:21,640
returns an INT and as its second
1449
00:59:21,640 --> 00:59:25,359
parameter an INT and then F returns an
1450
00:59:25,359 --> 00:59:26,599
INT
1451
00:59:26,599 --> 00:59:28,280
hopefully that makes sense again feel
1452
00:59:28,280 --> 00:59:30,319
free to pause the video and and stare at
1453
00:59:30,319 --> 00:59:32,760
that for a second let's talk a little
1454
00:59:32,760 --> 00:59:36,079
bit about memory and how data that we
1455
00:59:36,079 --> 00:59:38,799
create in our program using variables is
1456
00:59:38,799 --> 00:59:42,720
stored in memory so over here I'll keep
1457
00:59:42,720 --> 00:59:45,079
track of the memory of our program and
1458
00:59:45,079 --> 00:59:47,599
over here I'll write some
1459
00:59:47,599 --> 00:59:52,799
code so let's say in our code we write X
1460
00:59:52,799 --> 00:59:55,559
colon equals 5 right so we're creating a
1461
00:59:55,559 --> 00:59:58,440
new variable called X and we are giving
1462
00:59:58,440 --> 01:00:01,079
it the value the integer value of five
1463
01:00:01,079 --> 01:00:04,160
and then we're placing the value
1464
01:00:04,160 --> 01:00:07,559
five in that memory right stored as
1465
01:00:07,559 --> 01:00:11,000
binary data within Ram now in our
1466
01:00:11,000 --> 01:00:14,440
program X the symbol is essentially just
1467
01:00:14,440 --> 01:00:16,000
a
1468
01:00:16,000 --> 01:00:19,640
pointer it points to this location in
1469
01:00:19,640 --> 01:00:22,319
memory so let's say on the next line of
1470
01:00:22,319 --> 01:00:26,039
code we update X and we say x equal 2 so
1471
01:00:26,039 --> 01:00:28,680
now we're reassigning the value of x to
1472
01:00:28,680 --> 01:00:31,280
two now let's try something different
1473
01:00:31,280 --> 01:00:34,400
what if we create a new variable called
1474
01:00:34,400 --> 01:00:37,559
Y and we initialize it to the current
1475
01:00:37,559 --> 01:00:40,200
value of x which in this case happens to
1476
01:00:40,200 --> 01:00:43,240
be two well in this
1477
01:00:43,240 --> 01:00:46,000
case we're actually going to allocate a
1478
01:00:46,000 --> 01:00:48,799
new section of memory to store the value
1479
01:00:48,799 --> 01:00:51,680
of y and we'll initialize it to the
1480
01:00:51,680 --> 01:00:56,359
current value of x which is two
1481
01:00:56,799 --> 01:00:58,880
and the symbol
1482
01:00:58,880 --> 01:01:03,799
y now has its own location in memory so
1483
01:01:03,799 --> 01:01:07,880
we basically created a copy of X now
1484
01:01:07,880 --> 01:01:10,520
this idea is really important to
1485
01:01:10,520 --> 01:01:12,480
understand because sometimes in
1486
01:01:12,480 --> 01:01:14,640
programming we'll have multiple
1487
01:01:14,640 --> 01:01:16,720
variables that actually point to the
1488
01:01:16,720 --> 01:01:18,799
same location in memory they can
1489
01:01:18,799 --> 01:01:21,359
overwrite each other and sometimes we
1490
01:01:21,359 --> 01:01:24,680
don't sometimes we have copies of data
1491
01:01:24,680 --> 01:01:26,680
right so now for example if I were to
1492
01:01:26,680 --> 01:01:31,440
update y let's say I made y equal 1 at
1493
01:01:31,440 --> 01:01:34,359
this point x would be unaffected X would
1494
01:01:34,359 --> 01:01:38,680
remain two but y now becomes one right
1495
01:01:38,680 --> 01:01:41,119
because we have a copy these two
1496
01:01:41,119 --> 01:01:43,680
variables X and Y reference different
1497
01:01:43,680 --> 01:01:46,160
locations in memory so why does all of
1498
01:01:46,160 --> 01:01:48,599
this matter well in go variables are
1499
01:01:48,599 --> 01:01:51,520
passed by value not by reference so
1500
01:01:51,520 --> 01:01:53,880
let's take a look at this code snippet
1501
01:01:53,880 --> 01:01:56,559
here top of main we deare a new variable
1502
01:01:56,559 --> 01:01:58,520
called X we set it equal to 5 and then
1503
01:01:58,520 --> 01:02:01,079
we pass X into a function called
1504
01:02:01,079 --> 01:02:03,440
increment the increment function just
1505
01:02:03,440 --> 01:02:07,119
adds one to X right making it six after
1506
01:02:07,119 --> 01:02:10,799
that we print X and the weird thing is
1507
01:02:10,799 --> 01:02:13,160
that when we print X here we still get
1508
01:02:13,160 --> 01:02:17,000
five and the reason for that is the
1509
01:02:17,000 --> 01:02:19,200
increment function was operating on a
1510
01:02:19,200 --> 01:02:22,839
copy of X when we pass X in here to
1511
01:02:22,839 --> 01:02:25,440
increment increment gets a new copy of X
1512
01:02:25,440 --> 01:02:28,960
still equal to 5 it increments that X to
1513
01:02:28,960 --> 01:02:31,359
6 and then because we are not returning
1514
01:02:31,359 --> 01:02:33,680
it it essentially just gets thrown away
1515
01:02:33,680 --> 01:02:35,599
and then back in main we still have this
1516
01:02:35,599 --> 01:02:38,079
same X that's still equal to five the
1517
01:02:38,079 --> 01:02:40,079
correct thing to do here would be to
1518
01:02:40,079 --> 01:02:42,839
have the increment function return X
1519
01:02:42,839 --> 01:02:46,160
after making its modification and up in
1520
01:02:46,160 --> 01:02:49,880
main we would write x equals increment X
1521
01:02:49,880 --> 01:02:51,720
so that we could capture the return
1522
01:02:51,720 --> 01:02:53,839
value from the increment function so
1523
01:02:53,839 --> 01:02:55,440
moving on to the assignment it says it's
1524
01:02:55,440 --> 01:02:58,000
critical in texo that we keep track of
1525
01:02:58,000 --> 01:03:00,240
how many SMS messages we have sent on
1526
01:03:00,240 --> 01:03:02,480
behalf of our clients fix the bug to
1527
01:03:02,480 --> 01:03:04,200
accurately track the number of SMS
1528
01:03:04,200 --> 01:03:06,520
messages sent okay let me just try
1529
01:03:06,520 --> 01:03:08,520
running this in its current
1530
01:03:08,520 --> 01:03:11,000
state and we're missing a
1531
01:03:11,000 --> 01:03:14,200
return okay I'm going to remove
1532
01:03:14,200 --> 01:03:17,720
this this uh type return there and see
1533
01:03:17,720 --> 01:03:21,480
what happens sent 430
1534
01:03:21,480 --> 01:03:23,559
messages and it looks like here we have
1535
01:03:23,559 --> 01:03:27,680
sends so far sends to add increment S is
1536
01:03:27,680 --> 01:03:31,640
doing nothing because s so far is still
1537
01:03:31,640 --> 01:03:34,160
printing as
1538
01:03:34,160 --> 01:03:36,680
430 okay I think I'm understanding so
1539
01:03:36,680 --> 01:03:39,319
let me put that back in the assignment
1540
01:03:39,319 --> 01:03:41,880
says alter increment sends so that it
1541
01:03:41,880 --> 01:03:43,520
Returns the result after incrementing
1542
01:03:43,520 --> 01:03:44,760
sends so
1543
01:03:44,760 --> 01:03:47,319
far alter the main function to capture
1544
01:03:47,319 --> 01:03:49,200
the return value from increment sends
1545
01:03:49,200 --> 01:03:51,640
and overwrite the previous sends so far
1546
01:03:51,640 --> 01:03:53,319
value Okay cool so this is pretty
1547
01:03:53,319 --> 01:03:55,880
similar to the code snippet here
1548
01:03:55,880 --> 01:03:57,920
basically we need to return an INT so
1549
01:03:57,920 --> 01:03:59,240
we're going to
1550
01:03:59,240 --> 01:04:01,760
return send so
1551
01:04:01,760 --> 01:04:05,839
far and then here we need to reassign
1552
01:04:05,839 --> 01:04:09,319
sense so far into the result of
1553
01:04:09,319 --> 01:04:13,079
increment sense cool
1554
01:04:13,079 --> 01:04:15,799
so again here we'll still be operating
1555
01:04:15,799 --> 01:04:18,480
on copies but because we're going to
1556
01:04:18,480 --> 01:04:20,480
return the copy and save it back into
1557
01:04:20,480 --> 01:04:22,359
the original variable we should be good
1558
01:04:22,359 --> 01:04:24,160
to go let me run
1559
01:04:24,160 --> 01:04:27,760
that yep you've sent 455 messages that
1560
01:04:27,760 --> 01:04:30,319
looks correct functions in go can have
1561
01:04:30,319 --> 01:04:32,839
multiple return values and when they do
1562
01:04:32,839 --> 01:04:35,359
have multiple return values the Syntax
1563
01:04:35,359 --> 01:04:37,359
for specifying that is just to wrap the
1564
01:04:37,359 --> 01:04:40,720
return values in parentheses as well so
1565
01:04:40,720 --> 01:04:42,799
when there's just a single return value
1566
01:04:42,799 --> 01:04:44,799
we do not wrap that return value in
1567
01:04:44,799 --> 01:04:47,119
parenthesis but when there are multiples
1568
01:04:47,119 --> 01:04:49,480
we do wrap them in parenthesis one thing
1569
01:04:49,480 --> 01:04:51,920
I really like about go is that it does
1570
01:04:51,920 --> 01:04:55,480
not allow you to have unused variables
1571
01:04:55,480 --> 01:04:57,240
and because it doesn't allow you to have
1572
01:04:57,240 --> 01:04:59,599
unused variables and because it allows
1573
01:04:59,599 --> 01:05:01,359
you to have multiple return values from
1574
01:05:01,359 --> 01:05:03,279
a function we kind of need a way to
1575
01:05:03,279 --> 01:05:05,279
ignore some of the return values because
1576
01:05:05,279 --> 01:05:07,200
there are definitely instances where a
1577
01:05:07,200 --> 01:05:09,279
function returns two things but maybe we
1578
01:05:09,279 --> 01:05:11,359
only care about one of those things for
1579
01:05:11,359 --> 01:05:13,760
example a point on a graph can be
1580
01:05:13,760 --> 01:05:16,680
described by its XY coordinates but
1581
01:05:16,680 --> 01:05:18,559
maybe all we care about is the x
1582
01:05:18,559 --> 01:05:20,760
coordinate so here we can call the get
1583
01:05:20,760 --> 01:05:23,880
Point function and ignore the Y value by
1584
01:05:23,880 --> 01:05:25,920
using an underscore and it's important
1585
01:05:25,920 --> 01:05:27,920
to understand that the underscore is not
1586
01:05:27,920 --> 01:05:30,160
just like a conventional name that we're
1587
01:05:30,160 --> 01:05:32,279
going to ignore it's actually ignored
1588
01:05:32,279 --> 01:05:33,079
the
1589
01:05:33,079 --> 01:05:35,599
compiler completely removes it from our
1590
01:05:35,599 --> 01:05:38,400
code so moving on to the assignment here
1591
01:05:38,400 --> 01:05:40,599
in texo we have obviously first names
1592
01:05:40,599 --> 01:05:42,559
and last names for all of the users that
1593
01:05:42,559 --> 01:05:44,920
we're able to send messages to well when
1594
01:05:44,920 --> 01:05:47,920
we welcome someone to texo we don't need
1595
01:05:47,920 --> 01:05:50,119
their last name so let me go ahead and
1596
01:05:50,119 --> 01:05:52,319
try to run this code and you'll see
1597
01:05:52,319 --> 01:05:53,680
we'll actually get a compiler error that
1598
01:05:53,680 --> 01:05:55,680
says last name declared and not used
1599
01:05:55,680 --> 01:05:58,839
used like I said go does not allow us to
1600
01:05:58,839 --> 01:06:01,520
have unused variables which I think is
1601
01:06:01,520 --> 01:06:03,880
kind of an awesome uh little bit of the
1602
01:06:03,880 --> 01:06:05,559
tooling it helps keep our code very
1603
01:06:05,559 --> 01:06:08,839
clean and concise easy to understand um
1604
01:06:08,839 --> 01:06:12,160
so we need to explicitly ignore that
1605
01:06:12,160 --> 01:06:13,680
last name with an underscore if we're
1606
01:06:13,680 --> 01:06:15,559
not going to use it let me try running
1607
01:06:15,559 --> 01:06:19,400
that again and that looks good to me in
1608
01:06:19,400 --> 01:06:22,599
go we can name our return values and if
1609
01:06:22,599 --> 01:06:25,160
we do it actually Alters the behavior of
1610
01:06:25,160 --> 01:06:26,079
the function
1611
01:06:26,079 --> 01:06:28,039
just a little bit let's take a look at
1612
01:06:28,039 --> 01:06:30,079
this function get chords or get
1613
01:06:30,079 --> 01:06:32,920
coordinates it returns two integers and
1614
01:06:32,920 --> 01:06:36,680
we've named the integers X and Y and by
1615
01:06:36,680 --> 01:06:39,039
naming them we've actually initialized
1616
01:06:39,039 --> 01:06:41,680
at the top of the function the the
1617
01:06:41,680 --> 01:06:43,680
variables X and Y and they're
1618
01:06:43,680 --> 01:06:45,839
initialized with their zero values so in
1619
01:06:45,839 --> 01:06:47,680
the case of an integer literally just
1620
01:06:47,680 --> 01:06:50,039
the number zero for both of them the
1621
01:06:50,039 --> 01:06:52,359
other interesting thing about naming our
1622
01:06:52,359 --> 01:06:55,839
return values is that if we use a naked
1623
01:06:55,839 --> 01:06:58,440
return statement a return statement that
1624
01:06:58,440 --> 01:07:01,039
doesn't explicitly say for example
1625
01:07:01,039 --> 01:07:06,279
return 0 comma 5 then the values of X
1626
01:07:06,279 --> 01:07:09,079
and Y are automatically returned from
1627
01:07:09,079 --> 01:07:10,880
the function
1628
01:07:10,880 --> 01:07:14,400
so this version of get coordinates is
1629
01:07:14,400 --> 01:07:17,279
actually the exact same as this kind of
1630
01:07:17,279 --> 01:07:20,279
more verbose version of get coordinates
1631
01:07:20,279 --> 01:07:22,480
right here we have not given the return
1632
01:07:22,480 --> 01:07:24,559
values the names X and Y and instead
1633
01:07:24,559 --> 01:07:26,960
we've initialized X and Y to their zero
1634
01:07:26,960 --> 01:07:30,240
values and then returned them explicitly
1635
01:07:30,240 --> 01:07:32,400
now a couple of recommendations I would
1636
01:07:32,400 --> 01:07:35,839
recommend using named returns when you
1637
01:07:35,839 --> 01:07:38,520
want to document kind of what the
1638
01:07:38,520 --> 01:07:42,240
intended purpose of each return value is
1639
01:07:42,240 --> 01:07:43,920
so for example if you have a function
1640
01:07:43,920 --> 01:07:46,079
that just returns three integers that
1641
01:07:46,079 --> 01:07:47,799
function signature could be pretty
1642
01:07:47,799 --> 01:07:49,559
confusing but if you have a function
1643
01:07:49,559 --> 01:07:51,319
signature that says it returns three
1644
01:07:51,319 --> 01:07:53,799
integers and they're named width height
1645
01:07:53,799 --> 01:07:56,520
and length that's a lot more interesting
1646
01:07:56,520 --> 01:07:58,319
to the caller of the function they
1647
01:07:58,319 --> 01:07:59,920
understand the purpose of each
1648
01:07:59,920 --> 01:08:02,680
individual return value much better so I
1649
01:08:02,680 --> 01:08:05,119
like to think of named return values as
1650
01:08:05,119 --> 01:08:07,520
basically a built-in way of documenting
1651
01:08:07,520 --> 01:08:09,559
what the purpose of all of your return
1652
01:08:09,559 --> 01:08:11,160
values are and you should generally just
1653
01:08:11,160 --> 01:08:14,160
use them on the other hand this implicit
1654
01:08:14,160 --> 01:08:17,359
or automatic return that you get along
1655
01:08:17,359 --> 01:08:20,040
with um named return values I would
1656
01:08:20,040 --> 01:08:22,199
typically advise against you'd only want
1657
01:08:22,199 --> 01:08:24,239
to use this in like very short very
1658
01:08:24,239 --> 01:08:27,000
simple functions um because it harms
1659
01:08:27,000 --> 01:08:28,560
readability right and I'm pulling this
1660
01:08:28,560 --> 01:08:30,560
directly from the tour of go they also
1661
01:08:30,560 --> 01:08:34,080
agree with me um implicit returns or
1662
01:08:34,080 --> 01:08:36,759
naked return statements um generally a
1663
01:08:36,759 --> 01:08:38,839
little bit harder to understand so the
1664
01:08:38,839 --> 01:08:40,080
way I would write this function
1665
01:08:40,080 --> 01:08:42,880
personally would be get chords XY in and
1666
01:08:42,880 --> 01:08:46,159
then I would explicitly return X and Y
1667
01:08:46,159 --> 01:08:48,319
so let's jump down into the assignment
1668
01:08:48,319 --> 01:08:49,920
it says one of our clients likes us to
1669
01:08:49,920 --> 01:08:51,920
send text messages reminding users of
1670
01:08:51,920 --> 01:08:54,319
Life events coming up fix the bug by
1671
01:08:54,319 --> 01:08:55,960
using named return values in the
1672
01:08:55,960 --> 01:08:57,520
function signature so the code will
1673
01:08:57,520 --> 01:09:00,719
compile and run as intended Okay cool so
1674
01:09:00,719 --> 01:09:02,440
this is the function we are interested
1675
01:09:02,440 --> 01:09:05,600
in fixing years until events looks like
1676
01:09:05,600 --> 01:09:08,679
it takes a user's age as input and then
1677
01:09:08,679 --> 01:09:11,120
returns or should return kind of the
1678
01:09:11,120 --> 01:09:13,199
number of years until they're an adult
1679
01:09:13,199 --> 01:09:15,040
which is 18 the number of years until
1680
01:09:15,040 --> 01:09:17,080
they can drink at least in the US which
1681
01:09:17,080 --> 01:09:19,319
is 21 and the number of years until they
1682
01:09:19,319 --> 01:09:23,319
can rent a car which apparently is 25 um
1683
01:09:23,319 --> 01:09:25,799
and it looks like we never want a
1684
01:09:25,799 --> 01:09:29,640
negative number so if if any of these
1685
01:09:29,640 --> 01:09:31,159
are less than zero we just set them
1686
01:09:31,159 --> 01:09:33,799
equal to zero that makes sense once
1687
01:09:33,799 --> 01:09:36,920
you're over 18 your years until you're
1688
01:09:36,920 --> 01:09:38,640
an adult are just zero right you're
1689
01:09:38,640 --> 01:09:41,040
already an adult okay let me try running
1690
01:09:41,040 --> 01:09:42,920
this see what we get okay undefined
1691
01:09:42,920 --> 01:09:45,560
years until adult all right this makes
1692
01:09:45,560 --> 01:09:48,239
sense right because there's no colon
1693
01:09:48,239 --> 01:09:49,480
here so we're not defining a new
1694
01:09:49,480 --> 01:09:52,000
variable and the assignment said to use
1695
01:09:52,000 --> 01:09:53,640
named return values so let's go ahead
1696
01:09:53,640 --> 01:09:57,320
and do that so here's until adult years
1697
01:09:57,320 --> 01:10:00,800
until drinking I'm going to format this
1698
01:10:00,800 --> 01:10:03,239
a little
1699
01:10:03,440 --> 01:10:07,120
better and we'll do years until car
1700
01:10:07,120 --> 01:10:10,000
rental so again this will declare all of
1701
01:10:10,000 --> 01:10:11,600
these values with their zero value at
1702
01:10:11,600 --> 01:10:13,679
the top and then this naked return
1703
01:10:13,679 --> 01:10:16,679
statement should return them in
1704
01:10:16,679 --> 01:10:19,360
order and just to make sure adult
1705
01:10:19,360 --> 01:10:21,000
drinking car
1706
01:10:21,000 --> 01:10:23,239
rental adult drinking car rental okay
1707
01:10:23,239 --> 01:10:27,320
we're in the right order let me run that
1708
01:10:29,239 --> 01:10:31,640
first test so four years old they'll be
1709
01:10:31,640 --> 01:10:34,239
an adult in 18 years can drink in 17 can
1710
01:10:34,239 --> 01:10:37,280
the current 21 that all looks good 10
1711
01:10:37,280 --> 01:10:39,360
it's going down
1712
01:10:39,360 --> 01:10:42,400
22 Yep this looks good to me so as I
1713
01:10:42,400 --> 01:10:45,000
mentioned before explicit returns are
1714
01:10:45,000 --> 01:10:47,600
probably better than implicit returns in
1715
01:10:47,600 --> 01:10:49,880
most scenarios um it just makes a lot
1716
01:10:49,880 --> 01:10:52,239
more sense right so here in this
1717
01:10:52,239 --> 01:10:54,520
function get chords XY in so we're using
1718
01:10:54,520 --> 01:10:55,760
named return
1719
01:10:55,760 --> 01:10:58,480
but we're still explicitly returning X
1720
01:10:58,480 --> 01:11:01,199
and Y this is how I would recommend
1721
01:11:01,199 --> 01:11:04,360
writing most of your go code
1722
01:11:04,360 --> 01:11:07,560
um this this function here is doing the
1723
01:11:07,560 --> 01:11:10,040
same thing um it's explicitly returning
1724
01:11:10,040 --> 01:11:12,400
hardcoded values though instead of the
1725
01:11:12,400 --> 01:11:14,880
variables X and Y and it's just
1726
01:11:14,880 --> 01:11:16,040
important to understand that this
1727
01:11:16,040 --> 01:11:18,600
effectively overrides the implicit
1728
01:11:18,600 --> 01:11:21,040
return of X and Y so in this case five
1729
01:11:21,040 --> 01:11:23,480
and six will be returned again that's
1730
01:11:23,480 --> 01:11:24,880
why I recommend doing it explicitly
1731
01:11:24,880 --> 01:11:26,600
because when you see a return statement
1732
01:11:26,600 --> 01:11:29,719
that has explicit values being returned
1733
01:11:29,719 --> 01:11:30,920
those are the ones that are returned you
1734
01:11:30,920 --> 01:11:32,120
don't have to do any guess work you
1735
01:11:32,120 --> 01:11:33,360
don't have to scroll back to the top of
1736
01:11:33,360 --> 01:11:34,920
the function to see which values are
1737
01:11:34,920 --> 01:11:36,880
being returned so now we're going to
1738
01:11:36,880 --> 01:11:39,159
break that advice just for practice's
1739
01:11:39,159 --> 01:11:41,520
sake um the assignment says fix the
1740
01:11:41,520 --> 01:11:43,520
function to return the named values
1741
01:11:43,520 --> 01:11:45,520
implicitly okay so here we have a
1742
01:11:45,520 --> 01:11:47,199
problem in our code where we are
1743
01:11:47,199 --> 01:11:50,480
basically explicitly returning zeros
1744
01:11:50,480 --> 01:11:52,800
which as we talked about overrides the
1745
01:11:52,800 --> 01:11:54,639
implicit return so my guess is if we
1746
01:11:54,639 --> 01:11:56,040
look at all of these
1747
01:11:56,040 --> 01:11:59,600
yep every test is returning zeros if we
1748
01:11:59,600 --> 01:12:03,760
just remove that implicit return and run
1749
01:12:03,760 --> 01:12:08,199
that then it should work as intended yep
1750
01:12:08,199 --> 01:12:09,679
and then just to show you what I mean
1751
01:12:09,679 --> 01:12:13,840
like what I would recommend doing is
1752
01:12:16,239 --> 01:12:18,880
this it's
1753
01:12:18,880 --> 01:12:21,120
bigger like that that's how I'm going to
1754
01:12:21,120 --> 01:12:23,120
recommend doing it and in fact because
1755
01:12:23,120 --> 01:12:25,960
Boot Dev just checks the output this
1756
01:12:25,960 --> 01:12:28,120
should work just fine with our test so
1757
01:12:28,120 --> 01:12:31,320
I'm going to submit it like
1758
01:12:31,320 --> 01:12:34,199
this moving on to some questions about
1759
01:12:34,199 --> 01:12:36,440
named returns so it says when should
1760
01:12:36,440 --> 01:12:40,080
naked returns be used and the answers
1761
01:12:40,080 --> 01:12:41,679
are for large functions for small
1762
01:12:41,679 --> 01:12:44,440
functions or for complex functions and I
1763
01:12:44,440 --> 01:12:46,440
would argue if you're going to use naked
1764
01:12:46,440 --> 01:12:47,920
returns at all which honestly I'd kind
1765
01:12:47,920 --> 01:12:49,320
of just recommend against then you
1766
01:12:49,320 --> 01:12:51,920
should only use them for small functions
1767
01:12:51,920 --> 01:12:53,400
the more complex and large your
1768
01:12:53,400 --> 01:12:54,920
functions get the more important it is
1769
01:12:54,920 --> 01:12:57,920
to be explicit and readable and document
1770
01:12:57,920 --> 01:12:59,600
your returns with named returns and
1771
01:12:59,600 --> 01:13:01,600
things like that the next question is
1772
01:13:01,600 --> 01:13:04,560
when should named returns be used so
1773
01:13:04,560 --> 01:13:06,080
when there are many values being
1774
01:13:06,080 --> 01:13:08,360
returned when the function is simple or
1775
01:13:08,360 --> 01:13:10,280
when there are few parameters being
1776
01:13:10,280 --> 01:13:13,360
returned I would argue it's never really
1777
01:13:13,360 --> 01:13:16,320
a problem to name your return values but
1778
01:13:16,320 --> 01:13:18,080
it's really important when there are
1779
01:13:18,080 --> 01:13:20,000
many values being returned especially if
1780
01:13:20,000 --> 01:13:22,440
there are many values of the same type
1781
01:13:22,440 --> 01:13:24,520
being returned because then you can you
1782
01:13:24,520 --> 01:13:26,400
know essentially tell the collar of your
1783
01:13:26,400 --> 01:13:28,360
function through your function signature
1784
01:13:28,360 --> 01:13:30,159
what they should expect each value to
1785
01:13:30,159 --> 01:13:31,920
represent let's talk about one of my
1786
01:13:31,920 --> 01:13:34,120
favorite programming patterns or
1787
01:13:34,120 --> 01:13:36,320
programming Styles um that is early
1788
01:13:36,320 --> 01:13:38,199
returns or um what they're also
1789
01:13:38,199 --> 01:13:40,600
sometimes called as guard Clauses so an
1790
01:13:40,600 --> 01:13:42,920
early return or a guard Clause is
1791
01:13:42,920 --> 01:13:44,480
exactly what it sounds like it's just
1792
01:13:44,480 --> 01:13:47,520
when we return early from a function so
1793
01:13:47,520 --> 01:13:50,159
this function divide if it's past a
1794
01:13:50,159 --> 01:13:53,639
divisor of zero then it returns early
1795
01:13:53,639 --> 01:13:56,040
with an error other wise it goes ahead
1796
01:13:56,040 --> 01:13:58,480
and does kind of the division and
1797
01:13:58,480 --> 01:14:01,360
returns uh the results and a nil error
1798
01:14:01,360 --> 01:14:03,440
now we're going to talk about errors
1799
01:14:03,440 --> 01:14:05,000
soon you don't have to worry too much
1800
01:14:05,000 --> 01:14:07,639
about how they work for now um just
1801
01:14:07,639 --> 01:14:09,480
understand that a nil error effectively
1802
01:14:09,480 --> 01:14:12,199
means no error so when we're looking at
1803
01:14:12,199 --> 01:14:13,960
this divide function we can understand
1804
01:14:13,960 --> 01:14:16,360
that if the divisor is zero we're going
1805
01:14:16,360 --> 01:14:18,719
to return early and and basically say we
1806
01:14:18,719 --> 01:14:20,159
can't do this division because we can't
1807
01:14:20,159 --> 01:14:22,719
divide by zero um otherwise we'll take
1808
01:14:22,719 --> 01:14:25,320
the happy path towards the end of the
1809
01:14:25,320 --> 01:14:28,480
function best practices when it comes to
1810
01:14:28,480 --> 01:14:30,080
software engineering and how we write
1811
01:14:30,080 --> 01:14:33,040
code change all the time right there's
1812
01:14:33,040 --> 01:14:34,360
millions of developers all around the
1813
01:14:34,360 --> 01:14:36,120
world writing code and we all have
1814
01:14:36,120 --> 01:14:39,120
different opinions and kind of the the
1815
01:14:39,120 --> 01:14:41,239
common opinion about a certain style
1816
01:14:41,239 --> 01:14:43,320
tends to change over time um the
1817
01:14:43,320 --> 01:14:45,000
interesting thing is I think that these
1818
01:14:45,000 --> 01:14:47,840
days um guard Clauses and early returns
1819
01:14:47,840 --> 01:14:49,719
are kind of looked at as a good thing um
1820
01:14:49,719 --> 01:14:51,600
this is clean code right this is a good
1821
01:14:51,600 --> 01:14:53,800
way to write code certainly most go
1822
01:14:53,800 --> 01:14:55,960
programmers think this way way um but it
1823
01:14:55,960 --> 01:14:58,080
wasn't always that way um there used to
1824
01:14:58,080 --> 01:15:00,719
kind of be a heuristic that uh
1825
01:15:00,719 --> 01:15:02,639
developers used which was you shouldn't
1826
01:15:02,639 --> 01:15:05,000
ever return from a function in more than
1827
01:15:05,000 --> 01:15:08,159
one place so back when that was kind of
1828
01:15:08,159 --> 01:15:09,480
the more popular way of doing things
1829
01:15:09,480 --> 01:15:12,960
you'd get kind of nasty if else nested
1830
01:15:12,960 --> 01:15:15,000
statements like this um if you look at
1831
01:15:15,000 --> 01:15:17,679
this function get insurance amount
1832
01:15:17,679 --> 01:15:20,040
basically takes a status as input it
1833
01:15:20,040 --> 01:15:23,440
returns an integer and it only has one
1834
01:15:23,440 --> 01:15:25,320
return statement so it only returns from
1835
01:15:25,320 --> 01:15:27,440
one place but I would argue that doesn't
1836
01:15:27,440 --> 01:15:29,320
necessarily make this function all that
1837
01:15:29,320 --> 01:15:31,480
much easier to understand right we're
1838
01:15:31,480 --> 01:15:33,400
initializing a variable up at the top
1839
01:15:33,400 --> 01:15:36,040
amount and then just in this big nasty
1840
01:15:36,040 --> 01:15:38,679
nested if else chain we're kind of
1841
01:15:38,679 --> 01:15:41,679
reassigning the value of amount uh based
1842
01:15:41,679 --> 01:15:44,320
on some conditional logic now compare
1843
01:15:44,320 --> 01:15:46,760
that with guard Clauses right so with
1844
01:15:46,760 --> 01:15:49,679
guard Clauses instead of overwriting the
1845
01:15:49,679 --> 01:15:51,480
variable amount and then returning it at
1846
01:15:51,480 --> 01:15:52,880
the end of the function we're just
1847
01:15:52,880 --> 01:15:55,480
returning early with the proper amount
1848
01:15:55,480 --> 01:15:57,159
at each step of the way now both of
1849
01:15:57,159 --> 01:15:59,280
these functions do the exact same thing
1850
01:15:59,280 --> 01:16:01,920
they have the same behavior um but I
1851
01:16:01,920 --> 01:16:03,960
would argue that the one with the guard
1852
01:16:03,960 --> 01:16:07,440
Clauses is much easier to understand so
1853
01:16:07,440 --> 01:16:09,440
the question for this exercise is which
1854
01:16:09,440 --> 01:16:12,760
is true guard Clauses are unreadable
1855
01:16:12,760 --> 01:16:14,760
guard Clauses are generally worse than
1856
01:16:14,760 --> 01:16:17,080
nested IFL statements or guard Clauses
1857
01:16:17,080 --> 01:16:20,560
provide a linear approach to logic trees
1858
01:16:20,560 --> 01:16:23,120
okay so it's definitely not um these two
1859
01:16:23,120 --> 01:16:24,480
right so I'm I'm going to go with
1860
01:16:24,480 --> 01:16:26,280
provide a linear approach to logic trees
1861
01:16:26,280 --> 01:16:28,760
and really all that means is rather than
1862
01:16:28,760 --> 01:16:30,560
having to follow kind of a tree
1863
01:16:30,560 --> 01:16:33,040
structure to look at conditional logic
1864
01:16:33,040 --> 01:16:35,080
we can just follow a straight line right
1865
01:16:35,080 --> 01:16:37,920
is it this no we move on is it this no
1866
01:16:37,920 --> 01:16:40,000
we can move on right it it allows us to
1867
01:16:40,000 --> 01:16:41,880
break up kind of the cognitive load when
1868
01:16:41,880 --> 01:16:43,760
we're when we're reading code so
1869
01:16:43,760 --> 01:16:46,639
definitely a linear approach there the
1870
01:16:46,639 --> 01:16:48,639
next question is what is a guard Clause
1871
01:16:48,639 --> 01:16:50,880
so a bit wise or operation an and
1872
01:16:50,880 --> 01:16:52,880
operation in Boolean logic or an early
1873
01:16:52,880 --> 01:16:54,080
return from a function when a given
1874
01:16:54,080 --> 01:16:56,840
condition is met and it is an early
1875
01:16:56,840 --> 01:16:59,560
return let's talk about structs so
1876
01:16:59,560 --> 01:17:01,280
structs are the first collection type
1877
01:17:01,280 --> 01:17:02,239
that we're going to talk about in this
1878
01:17:02,239 --> 01:17:04,480
course a collection type is just a type
1879
01:17:04,480 --> 01:17:07,480
that contains other types in the case of
1880
01:17:07,480 --> 01:17:09,600
a struct a struct is just a collection
1881
01:17:09,600 --> 01:17:11,719
of key value pairs if you're familiar
1882
01:17:11,719 --> 01:17:14,199
with python dictionaries or JavaScript
1883
01:17:14,199 --> 01:17:15,920
object literals this is basically the
1884
01:17:15,920 --> 01:17:19,000
same idea so for example we can define a
1885
01:17:19,000 --> 01:17:21,560
car struct and we can say a car has a
1886
01:17:21,560 --> 01:17:24,440
make a model a height and a width and
1887
01:17:24,440 --> 01:17:26,199
each of those feels has its own
1888
01:17:26,199 --> 01:17:28,679
Associated type so let's move on to the
1889
01:17:28,679 --> 01:17:30,199
assignment I think looking at the code
1890
01:17:30,199 --> 01:17:31,600
is going to be the easiest way to
1891
01:17:31,600 --> 01:17:34,440
understand structs okay complete the
1892
01:17:34,440 --> 01:17:36,400
message to send struct definition it
1893
01:17:36,400 --> 01:17:38,520
needs two Fields phone number an integer
1894
01:17:38,520 --> 01:17:41,760
and message a string and um on these
1895
01:17:41,760 --> 01:17:43,199
exercise I always recommend kind of
1896
01:17:43,199 --> 01:17:44,800
going and looking at the test weite this
1897
01:17:44,800 --> 01:17:46,600
is all the code the way boot Dev works
1898
01:17:46,600 --> 01:17:49,199
like all the code is here um and we're
1899
01:17:49,199 --> 01:17:50,840
really just testing standard output to
1900
01:17:50,840 --> 01:17:52,159
see if you got the right answer so you
1901
01:17:52,159 --> 01:17:54,159
can see literally everything that's
1902
01:17:54,159 --> 01:17:55,440
going on
1903
01:17:55,440 --> 01:17:57,560
um so here you can see where a message
1904
01:17:57,560 --> 01:17:59,320
to send is going to be instantiated with
1905
01:17:59,320 --> 01:18:00,960
phone numbers and messages and here you
1906
01:18:00,960 --> 01:18:04,520
can see where um it's the uh fields are
1907
01:18:04,520 --> 01:18:06,159
going to be accessed with the dot
1908
01:18:06,159 --> 01:18:07,880
operator so let me go ahead and run it
1909
01:18:07,880 --> 01:18:09,760
in its current state um we should get
1910
01:18:09,760 --> 01:18:11,719
yep a compile time error where it's
1911
01:18:11,719 --> 01:18:13,320
saying message is undefined phone number
1912
01:18:13,320 --> 01:18:15,600
is undefined right so we need to add
1913
01:18:15,600 --> 01:18:17,520
those to the
1914
01:18:17,520 --> 01:18:19,960
definition all right phone
1915
01:18:19,960 --> 01:18:22,600
number
1916
01:18:22,600 --> 01:18:26,280
integer message
1917
01:18:26,280 --> 01:18:28,679
string let's go ahead and run
1918
01:18:28,679 --> 01:18:31,280
that and sending message love to have
1919
01:18:31,280 --> 01:18:33,880
you aboard to that big number okay that
1920
01:18:33,880 --> 01:18:37,639
looks good to me struct keys can hold
1921
01:18:37,639 --> 01:18:40,400
any type uh not just primitive types
1922
01:18:40,400 --> 01:18:43,040
like integers strings and booleans um
1923
01:18:43,040 --> 01:18:45,199
here you can see we've actually nested
1924
01:18:45,199 --> 01:18:48,320
the wheel struct within the car struct
1925
01:18:48,320 --> 01:18:50,000
right so we have the car struct from the
1926
01:18:50,000 --> 01:18:51,520
last example and we've added a front
1927
01:18:51,520 --> 01:18:54,159
wheel and a back wheel and they are each
1928
01:18:54,159 --> 01:18:57,159
of type wheel right and a wheel has a
1929
01:18:57,159 --> 01:18:59,719
radius and a material so we can actually
1930
01:18:59,719 --> 01:19:02,120
Nest structs within other structs and
1931
01:19:02,120 --> 01:19:04,080
then we also saw this just a little bit
1932
01:19:04,080 --> 01:19:06,719
in the last assignment but this is how
1933
01:19:06,719 --> 01:19:09,280
we can instantiate a new instance of a
1934
01:19:09,280 --> 01:19:12,440
struct right so this is the struct
1935
01:19:12,440 --> 01:19:14,360
definition we're saying this is what a
1936
01:19:14,360 --> 01:19:16,600
car looks like and then here we've
1937
01:19:16,600 --> 01:19:20,320
created a new empty car called my car
1938
01:19:20,320 --> 01:19:22,040
and when you create it kind of with
1939
01:19:22,040 --> 01:19:26,280
those empty uh those empty brackets all
1940
01:19:26,280 --> 01:19:28,679
of the fields inside of the struct will
1941
01:19:28,679 --> 01:19:30,280
just be initialized to their default
1942
01:19:30,280 --> 01:19:32,679
values their zero values right so
1943
01:19:32,679 --> 01:19:34,840
strings will be empty strings ins will
1944
01:19:34,840 --> 01:19:37,880
be zero and then here we're using the
1945
01:19:37,880 --> 01:19:41,199
dot operator to access Fields right so
1946
01:19:41,199 --> 01:19:43,520
my car. front wheeel right so we're
1947
01:19:43,520 --> 01:19:45,600
accessing the front wheel key and then
1948
01:19:45,600 --> 01:19:48,000
radius to access access the radius
1949
01:19:48,000 --> 01:19:49,880
within the front wheel and we're setting
1950
01:19:49,880 --> 01:19:52,719
it equal to five again with this syntax
1951
01:19:52,719 --> 01:19:54,199
stuff it's just best to get Hands-On
1952
01:19:54,199 --> 01:19:56,560
keyboard and jump right into it so let's
1953
01:19:56,560 --> 01:19:58,440
get to the assignment says textio has a
1954
01:19:58,440 --> 01:20:00,280
bug we've been sending texts with
1955
01:20:00,280 --> 01:20:02,679
information missing before we send text
1956
01:20:02,679 --> 01:20:04,280
messages in texo we should check to make
1957
01:20:04,280 --> 01:20:06,960
sure the required Fields have nonzero
1958
01:20:06,960 --> 01:20:09,480
values notice that both the user struct
1959
01:20:09,480 --> 01:20:12,320
so that's this here is a nested struct
1960
01:20:12,320 --> 01:20:13,840
or notice that the user struct is a
1961
01:20:13,840 --> 01:20:15,560
nested struct within message to send
1962
01:20:15,560 --> 01:20:17,480
okay so message to send has a message
1963
01:20:17,480 --> 01:20:19,920
which is a string and then a sender and
1964
01:20:19,920 --> 01:20:22,400
a recipient and both of those are of
1965
01:20:22,400 --> 01:20:25,320
type user okay that makes sense a user
1966
01:20:25,320 --> 01:20:27,040
is the sender a user is the recipient
1967
01:20:27,040 --> 01:20:29,000
and then there is a message cool
1968
01:20:29,000 --> 01:20:31,880
complete the send the can send message
1969
01:20:31,880 --> 01:20:33,560
function
1970
01:20:33,560 --> 01:20:36,400
okay it should only return true if the
1971
01:20:36,400 --> 01:20:39,080
sender and recipient Fields each contain
1972
01:20:39,080 --> 01:20:41,800
a name and a number if any of the
1973
01:20:41,800 --> 01:20:43,880
default zero values are present return
1974
01:20:43,880 --> 01:20:47,360
false instead Okay cool so can send
1975
01:20:47,360 --> 01:20:48,600
message this is essentially a function
1976
01:20:48,600 --> 01:20:50,560
that's going to validate a message to
1977
01:20:50,560 --> 01:20:53,639
send to see if it actually has data
1978
01:20:53,639 --> 01:20:57,360
inside of it so so um if I run the code
1979
01:20:57,360 --> 01:21:00,920
right now it's always returning true
1980
01:21:00,920 --> 01:21:02,880
right so you have an appointment
1981
01:21:02,880 --> 01:21:05,120
tomorrow you have an event
1982
01:21:05,120 --> 01:21:08,600
tomorrow from Susie Saul ah see there's
1983
01:21:08,600 --> 01:21:10,080
a phone number missing there that's a
1984
01:21:10,080 --> 01:21:11,840
problem looks like there's a phone
1985
01:21:11,840 --> 01:21:14,199
number missing there that's a problem
1986
01:21:14,199 --> 01:21:18,800
okay let's see so sender and recipients
1987
01:21:18,800 --> 01:21:23,440
contain a name and a number so if M to
1988
01:21:23,440 --> 01:21:26,440
send
1989
01:21:27,560 --> 01:21:31,280
dot sender and recipi sender contain
1990
01:21:31,280 --> 01:21:34,159
name dot name
1991
01:21:34,159 --> 01:21:37,159
is
1992
01:21:37,360 --> 01:21:40,199
empty
1993
01:21:40,199 --> 01:21:41,880
false
1994
01:21:41,880 --> 01:21:46,159
right and then if m dot is going to be
1995
01:21:46,159 --> 01:21:48,639
recipient is empty also return FSE so
1996
01:21:48,639 --> 01:21:49,520
we're just going to do some guard
1997
01:21:49,520 --> 01:21:50,560
Clauses
1998
01:21:50,560 --> 01:21:52,920
here and then sender and recipient and
1999
01:21:52,920 --> 01:21:55,199
now we're interested in the number
2000
01:21:55,199 --> 01:21:58,719
number is an integer so if it's
2001
01:21:58,719 --> 01:22:00,639
zero cool so we're just we're just
2002
01:22:00,639 --> 01:22:02,719
basically doing a a very simple
2003
01:22:02,719 --> 01:22:05,320
validation to make sure um that names
2004
01:22:05,320 --> 01:22:07,679
aren't blank and numbers are not blank
2005
01:22:07,679 --> 01:22:10,400
so let me run
2006
01:22:11,040 --> 01:22:13,480
that okay so this one has all the
2007
01:22:13,480 --> 01:22:15,800
information there and it's sent now this
2008
01:22:15,800 --> 01:22:17,520
one has a number missing can't send
2009
01:22:17,520 --> 01:22:19,120
message that looks
2010
01:22:19,120 --> 01:22:22,880
correct okay this is looking good to
2011
01:22:22,880 --> 01:22:25,679
me all right next up we have Anonymous
2012
01:22:25,679 --> 01:22:28,920
strs so Anonymous strs are just struct
2013
01:22:28,920 --> 01:22:32,880
instances that don't have a name so
2014
01:22:32,880 --> 01:22:34,960
whenever you create a new Anonymous
2015
01:22:34,960 --> 01:22:37,920
struct in go you're you're immediately
2016
01:22:37,920 --> 01:22:40,880
instantiating a struct of a given type
2017
01:22:40,880 --> 01:22:42,960
right the type of the struct doesn't
2018
01:22:42,960 --> 01:22:45,320
have a name so for example here we have
2019
01:22:45,320 --> 01:22:46,159
a
2020
01:22:46,159 --> 01:22:49,520
struct with a make and a model now in
2021
01:22:49,520 --> 01:22:51,159
the exercise previous we remember we
2022
01:22:51,159 --> 01:22:53,800
actually had this same exact struct but
2023
01:22:53,800 --> 01:22:56,080
we'd given it name the name was car
2024
01:22:56,080 --> 01:22:58,239
right here we haven't created a new
2025
01:22:58,239 --> 01:23:00,040
struct definition we haven't created a
2026
01:23:00,040 --> 01:23:01,960
new struct definition called car instead
2027
01:23:01,960 --> 01:23:04,639
we're immediately instantiating a new
2028
01:23:04,639 --> 01:23:07,520
instance of a struct called my car this
2029
01:23:07,520 --> 01:23:09,920
could be named anything right and it
2030
01:23:09,920 --> 01:23:13,440
just has a make and a model field on it
2031
01:23:13,440 --> 01:23:15,600
so the only reason you would use an
2032
01:23:15,600 --> 01:23:18,239
anonymous struct is if you have no
2033
01:23:18,239 --> 01:23:22,159
reason to create more than one instance
2034
01:23:22,159 --> 01:23:24,840
of the struct so to be clear what's
2035
01:23:24,840 --> 01:23:26,120
happening here we're creating a new
2036
01:23:26,120 --> 01:23:28,600
variable called my car and it has two
2037
01:23:28,600 --> 01:23:30,760
Fields it's a struct with two Fields
2038
01:23:30,760 --> 01:23:33,360
make and model and we're immediately
2039
01:23:33,360 --> 01:23:38,920
giving it a value of make Tesla Model 3
2040
01:23:38,920 --> 01:23:41,600
and this type this specific struct type
2041
01:23:41,600 --> 01:23:42,960
doesn't exist anywhere else within our
2042
01:23:42,960 --> 01:23:44,719
program this is kind of a type that's
2043
01:23:44,719 --> 01:23:47,239
just unique to this one instance um
2044
01:23:47,239 --> 01:23:49,760
called my car it's not very common that
2045
01:23:49,760 --> 01:23:52,159
you'll see kind of top level um
2046
01:23:52,159 --> 01:23:54,520
Anonymous structs like this more often
2047
01:23:54,520 --> 01:23:57,440
you'll see nested Anonymous structs
2048
01:23:57,440 --> 01:24:00,120
right so rather than creating wheel as a
2049
01:24:00,120 --> 01:24:02,719
separate struct type we've just said
2050
01:24:02,719 --> 01:24:04,520
well Wheels kind of always exist within
2051
01:24:04,520 --> 01:24:06,760
cars I know that's not really true but
2052
01:24:06,760 --> 01:24:08,719
maybe within our program it's true um so
2053
01:24:08,719 --> 01:24:11,480
we just create a little Anonymous struct
2054
01:24:11,480 --> 01:24:14,639
um within the greater car struct now as
2055
01:24:14,639 --> 01:24:16,920
far as best practices in writing clean
2056
01:24:16,920 --> 01:24:19,320
code my opinion is that you should
2057
01:24:19,320 --> 01:24:22,600
generally favor um named structs you
2058
01:24:22,600 --> 01:24:23,960
avoid Anonymous structs unless you have
2059
01:24:23,960 --> 01:24:26,719
a really good reason to use them uh
2060
01:24:26,719 --> 01:24:29,040
you'll really never go wrong with naming
2061
01:24:29,040 --> 01:24:31,960
your structs okay so the question on
2062
01:24:31,960 --> 01:24:33,719
this assignment is what is a good reason
2063
01:24:33,719 --> 01:24:35,639
to use an anonymous struct you're
2064
01:24:35,639 --> 01:24:36,960
worried about security you need your
2065
01:24:36,960 --> 01:24:38,360
code to be faster you're worried about
2066
01:24:38,360 --> 01:24:41,600
user privacy or it is only being used
2067
01:24:41,600 --> 01:24:44,080
once well the only thing even remotely
2068
01:24:44,080 --> 01:24:46,520
related to how Anonymous trucks work um
2069
01:24:46,520 --> 01:24:48,480
is that it's only being used once so if
2070
01:24:48,480 --> 01:24:50,199
you're certain that you only want this
2071
01:24:50,199 --> 01:24:52,440
type to be used one time maybe you don't
2072
01:24:52,440 --> 01:24:54,800
want someone accidentally reusing a type
2073
01:24:54,800 --> 01:24:56,560
um then you might want to use an
2074
01:24:56,560 --> 01:24:57,520
anonymous
2075
01:24:57,520 --> 01:25:00,000
struct next question is what's one
2076
01:25:00,000 --> 01:25:02,360
advantage of using an anonymous struct
2077
01:25:02,360 --> 01:25:03,679
anonymous trucks make your code run
2078
01:25:03,679 --> 01:25:05,360
faster Anonymous strs prevent you from
2079
01:25:05,360 --> 01:25:07,159
reusing a struct definition you never
2080
01:25:07,159 --> 01:25:09,520
intended to reuse or Anonymous TRS can
2081
01:25:09,520 --> 01:25:12,320
be compiled more quickly um it's this
2082
01:25:12,320 --> 01:25:15,480
reuse one um one place that I have used
2083
01:25:15,480 --> 01:25:17,560
Anonymous kind of top level structs from
2084
01:25:17,560 --> 01:25:19,840
time to time is in HTTP handlers so if I
2085
01:25:19,840 --> 01:25:23,000
know that a given HTTP endpoint will
2086
01:25:23,000 --> 01:25:26,480
always return a a specific Json payload
2087
01:25:26,480 --> 01:25:28,560
then I'll use an anonymous struct to
2088
01:25:28,560 --> 01:25:31,639
define the shape of that Json payload we
2089
01:25:31,639 --> 01:25:33,560
haven't really talked about Json in go
2090
01:25:33,560 --> 01:25:35,840
yet but kind of spoiler alert structs
2091
01:25:35,840 --> 01:25:38,880
are how we structure Json data
2092
01:25:38,880 --> 01:25:42,000
typically next we have embedded structs
2093
01:25:42,000 --> 01:25:44,159
and embedded structs are not the same
2094
01:25:44,159 --> 01:25:47,159
thing as nested structs an embedded
2095
01:25:47,159 --> 01:25:48,800
struct is basically where would take all
2096
01:25:48,800 --> 01:25:51,679
the fields from one struct and kind of
2097
01:25:51,679 --> 01:25:54,480
shove them into another one uh let me
2098
01:25:54,480 --> 01:25:57,360
show you what I mean so here's our car
2099
01:25:57,360 --> 01:25:59,199
struct that we've been using for our
2100
01:25:59,199 --> 01:26:01,440
examples um it's got to make in a model
2101
01:26:01,440 --> 01:26:05,040
great here's our truck struct now you'll
2102
01:26:05,040 --> 01:26:09,320
notice we've embedded the car type here
2103
01:26:09,320 --> 01:26:12,840
but the car is missing kind of a name a
2104
01:26:12,840 --> 01:26:15,960
key in the truck struct bed size is the
2105
01:26:15,960 --> 01:26:18,280
key int is the type here we just have
2106
01:26:18,280 --> 01:26:21,360
the type which is car so what does this
2107
01:26:21,360 --> 01:26:22,960
do and how does it differ from a nested
2108
01:26:22,960 --> 01:26:25,880
struct well in the embedded struct if we
2109
01:26:25,880 --> 01:26:30,480
want to access the field model from a an
2110
01:26:30,480 --> 01:26:32,719
instance of a truck rather than doing
2111
01:26:32,719 --> 01:26:36,280
truck. car. model we would just do
2112
01:26:36,280 --> 01:26:39,880
truck. model because these fields of the
2113
01:26:39,880 --> 01:26:43,000
car type are becoming kind of top level
2114
01:26:43,000 --> 01:26:45,480
fields of the truck type we're
2115
01:26:45,480 --> 01:26:47,920
inheriting all of those fields from the
2116
01:26:47,920 --> 01:26:50,280
car type now I have to be careful with
2117
01:26:50,280 --> 01:26:52,119
the word inherit even though it is kind
2118
01:26:52,119 --> 01:26:53,920
of a pretty good descriptive term for
2119
01:26:53,920 --> 01:26:56,840
what's happening go is not an
2120
01:26:56,840 --> 01:26:58,880
objectoriented language because it
2121
01:26:58,880 --> 01:27:01,560
doesn't support classes or inheritance
2122
01:27:01,560 --> 01:27:03,520
in the class-based sense so if you're
2123
01:27:03,520 --> 01:27:04,840
familiar with the idea of
2124
01:27:04,840 --> 01:27:06,480
object-oriented programming just know
2125
01:27:06,480 --> 01:27:08,639
that classes and inheritance aren't
2126
01:27:08,639 --> 01:27:11,040
really what's going on here uh this is
2127
01:27:11,040 --> 01:27:12,320
you can almost just think of this as a
2128
01:27:12,320 --> 01:27:15,600
shorthand for kind of retyping this make
2129
01:27:15,600 --> 01:27:18,159
and model into the truck struct it's
2130
01:27:18,159 --> 01:27:20,920
it's almost just a syntactic sugar um so
2131
01:27:20,920 --> 01:27:23,760
that we don't have to retype all of
2132
01:27:23,760 --> 01:27:26,159
these Fields so let's take a look at
2133
01:27:26,159 --> 01:27:29,080
some code um and how we would use this
2134
01:27:29,080 --> 01:27:32,000
truck struct so I've created this new um
2135
01:27:32,000 --> 01:27:33,760
instance of a truck called it Lane's
2136
01:27:33,760 --> 01:27:36,280
truck has a bed size which is an integer
2137
01:27:36,280 --> 01:27:40,040
right and it has a car here now you
2138
01:27:40,040 --> 01:27:41,280
might look at that and say that looks an
2139
01:27:41,280 --> 01:27:43,920
awful lot like a nested struct and the
2140
01:27:43,920 --> 01:27:47,440
Syntax for creating a new instance of an
2141
01:27:47,440 --> 01:27:51,199
embedded struct is very similar to uh
2142
01:27:51,199 --> 01:27:53,199
the Syntax for a nested struct
2143
01:27:53,199 --> 01:27:54,639
essentially the key
2144
01:27:54,639 --> 01:27:57,639
is just the same name as the type this
2145
01:27:57,639 --> 01:28:00,840
just kind of a quirky thing about um
2146
01:28:00,840 --> 01:28:03,159
composite literals uh the embedded stuff
2147
01:28:03,159 --> 01:28:05,600
looks like the nested stuff however when
2148
01:28:05,600 --> 01:28:08,679
we are accessing the individual fields
2149
01:28:08,679 --> 01:28:12,560
on um Lanes truck using the dot operator
2150
01:28:12,560 --> 01:28:14,679
you'll see they're all accessed at the
2151
01:28:14,679 --> 01:28:18,040
top level it's not Lan truck uh doar
2152
01:28:18,040 --> 01:28:21,719
doake it's Lan truck. make right it's
2153
01:28:21,719 --> 01:28:23,719
not lanest truck. car. model it's just
2154
01:28:23,719 --> 01:28:26,119
LAN truck. model so those fields are
2155
01:28:26,119 --> 01:28:29,360
being brought up into the top level it's
2156
01:28:29,360 --> 01:28:31,199
just when we kind of instantiate the
2157
01:28:31,199 --> 01:28:33,159
truck the first time that we need to do
2158
01:28:33,159 --> 01:28:36,040
this sort of nested syntax so let's hop
2159
01:28:36,040 --> 01:28:38,560
into the assignment it says at texo a
2160
01:28:38,560 --> 01:28:41,000
user which is a struct represents an
2161
01:28:41,000 --> 01:28:43,280
account holder and a sender is just a
2162
01:28:43,280 --> 01:28:45,119
user with some additional sender
2163
01:28:45,119 --> 01:28:47,360
specific data a sender is a user that
2164
01:28:47,360 --> 01:28:49,000
has a rate limit field that tells us how
2165
01:28:49,000 --> 01:28:50,880
many messages they are allowed to send
2166
01:28:50,880 --> 01:28:52,520
fix the system by using an embedded
2167
01:28:52,520 --> 01:28:55,080
struct as expected by the Tex test code
2168
01:28:55,080 --> 01:28:56,119
okay so let's go ahead and take a look
2169
01:28:56,119 --> 01:28:57,560
at the test
2170
01:28:57,560 --> 01:28:59,880
code so it looks like the test code is
2171
01:28:59,880 --> 01:29:02,000
creating some
2172
01:29:02,000 --> 01:29:05,639
senders and it's expecting that a sender
2173
01:29:05,639 --> 01:29:08,760
has a rate limit and that it has a user
2174
01:29:08,760 --> 01:29:10,360
right and this is looking like an
2175
01:29:10,360 --> 01:29:11,280
embedded
2176
01:29:11,280 --> 01:29:14,639
struct and up here you can see s is a
2177
01:29:14,639 --> 01:29:17,080
sender and we're directly accessing name
2178
01:29:17,080 --> 01:29:19,400
number and rate limit all the top
2179
01:29:19,400 --> 01:29:22,000
level so I think all I need to do here
2180
01:29:22,000 --> 01:29:24,480
is embed the user structure in fact
2181
01:29:24,480 --> 01:29:26,679
let's run this without without that see
2182
01:29:26,679 --> 01:29:28,520
what happens yep we're getting some
2183
01:29:28,520 --> 01:29:29,760
undefined
2184
01:29:29,760 --> 01:29:34,400
Fields we'll embed the user type in
2185
01:29:34,400 --> 01:29:38,040
there and that's looking pretty good to
2186
01:29:38,040 --> 01:29:41,040
me I will mention just to give you an
2187
01:29:41,040 --> 01:29:42,440
idea of like when you use this in the
2188
01:29:42,440 --> 01:29:44,400
real world one place that I use it
2189
01:29:44,400 --> 01:29:47,040
actively on boot Dev is users have kind
2190
01:29:47,040 --> 01:29:49,440
of public fields on boot Dev and private
2191
01:29:49,440 --> 01:29:52,560
Fields so public fields are um stuff
2192
01:29:52,560 --> 01:29:54,159
that we show on the leaderboard things
2193
01:29:54,159 --> 01:29:55,800
that kind of anyone can see about your
2194
01:29:55,800 --> 01:29:57,800
profile maybe your bio or your profile
2195
01:29:57,800 --> 01:30:00,320
picture um but users also have private
2196
01:30:00,320 --> 01:30:03,119
Fields things like um your hashed
2197
01:30:03,119 --> 01:30:04,719
password right the password we store in
2198
01:30:04,719 --> 01:30:06,800
the database and I've actually
2199
01:30:06,800 --> 01:30:10,520
embedded the private Fields within the
2200
01:30:10,520 --> 01:30:13,719
public user so that I can easily nullify
2201
01:30:13,719 --> 01:30:16,239
them when I don't want to send private
2202
01:30:16,239 --> 01:30:19,719
data uh to a given web page all right
2203
01:30:19,719 --> 01:30:25,040
let's go ahead and run this code
2204
01:30:25,040 --> 01:30:27,360
let's talk about methods on structs or
2205
01:30:27,360 --> 01:30:30,440
just methods in general in go um I know
2206
01:30:30,440 --> 01:30:32,560
I told you go is not object oriented and
2207
01:30:32,560 --> 01:30:35,199
it's not but if you squint really hard
2208
01:30:35,199 --> 01:30:38,480
structs in go kind of look like classes
2209
01:30:38,480 --> 01:30:41,360
in a language like Java JavaScript or
2210
01:30:41,360 --> 01:30:44,199
python so methods in go are just
2211
01:30:44,199 --> 01:30:46,920
Behavior or functions that we can Define
2212
01:30:46,920 --> 01:30:49,199
on a type and more often than not we end
2213
01:30:49,199 --> 01:30:51,400
up defining methods on structs although
2214
01:30:51,400 --> 01:30:54,080
we could Define methods on any type so
2215
01:30:54,080 --> 01:30:56,440
let's take a look at the Syntax for this
2216
01:30:56,440 --> 01:30:58,199
so here we have a simple rectangle
2217
01:30:58,199 --> 01:31:01,400
struct it has a width and a height right
2218
01:31:01,400 --> 01:31:04,840
and here we've defined an area method on
2219
01:31:04,840 --> 01:31:07,840
the rectangle struct so this is just a
2220
01:31:07,840 --> 01:31:09,480
function right we're familiar with
2221
01:31:09,480 --> 01:31:11,560
functions already the only difference is
2222
01:31:11,560 --> 01:31:13,560
that we've added this special parameter
2223
01:31:13,560 --> 01:31:16,719
before the name of the function which is
2224
01:31:16,719 --> 01:31:18,520
again just a parameter that comes into
2225
01:31:18,520 --> 01:31:20,560
the function just it's just a special
2226
01:31:20,560 --> 01:31:23,520
parameter um and in this case it is of
2227
01:31:23,520 --> 01:31:25,719
type rect which is just a struct and
2228
01:31:25,719 --> 01:31:28,520
we've named it R and then this function
2229
01:31:28,520 --> 01:31:31,880
just returns r. width * r. height right
2230
01:31:31,880 --> 01:31:34,840
so it Returns the area of the rectangle
2231
01:31:34,840 --> 01:31:38,080
so why would we use a method on a struct
2232
01:31:38,080 --> 01:31:39,960
well there are reasons that we'll get to
2233
01:31:39,960 --> 01:31:42,280
later when we talk about interfaces um
2234
01:31:42,280 --> 01:31:44,440
but for now it's mostly a syntactic
2235
01:31:44,440 --> 01:31:47,239
thing a syntactic sugar thing if we have
2236
01:31:47,239 --> 01:31:49,600
behavior that we want to Define on a
2237
01:31:49,600 --> 01:31:52,199
given type then strs can be a really
2238
01:31:52,199 --> 01:31:53,960
good choice they give us this nice
2239
01:31:53,960 --> 01:31:55,280
tactic sugar right we create this new
2240
01:31:55,280 --> 01:31:57,600
rectangle called R and now we can just
2241
01:31:57,600 --> 01:32:00,760
call r. area to get the area of the
2242
01:32:00,760 --> 01:32:03,480
rectangle it's kind of a nice way to do
2243
01:32:03,480 --> 01:32:06,639
computed properties on a type right so
2244
01:32:06,639 --> 01:32:09,520
we could have stored area as a separate
2245
01:32:09,520 --> 01:32:12,760
number within the wct struct the problem
2246
01:32:12,760 --> 01:32:15,199
with that is now we lose kind of a
2247
01:32:15,199 --> 01:32:17,199
single source of Truth when it comes to
2248
01:32:17,199 --> 01:32:19,880
the area right if we store the area as
2249
01:32:19,880 --> 01:32:22,960
say 50 and the width and height as 5 and
2250
01:32:22,960 --> 01:32:25,320
10 but then we update the height and
2251
01:32:25,320 --> 01:32:27,560
forget to update the area right now we
2252
01:32:27,560 --> 01:32:29,560
have a bug in our code so this is a
2253
01:32:29,560 --> 01:32:33,480
great way to kind of have a oneline
2254
01:32:33,480 --> 01:32:36,239
accessor to get the area of a rectangle
2255
01:32:36,239 --> 01:32:37,960
but we don't have to actually store that
2256
01:32:37,960 --> 01:32:40,679
area in our struct as kind of duplicate
2257
01:32:40,679 --> 01:32:43,040
data so let's get down to the assignment
2258
01:32:43,040 --> 01:32:45,440
says let's clean up texo authentication
2259
01:32:45,440 --> 01:32:47,760
logic we store our users authentication
2260
01:32:47,760 --> 01:32:49,880
data inside an authentication info
2261
01:32:49,880 --> 01:32:51,639
struct okay so that's here it's got a
2262
01:32:51,639 --> 01:32:53,679
username and a password we need a method
2263
01:32:53,679 --> 01:32:55,360
that can take that data and return a
2264
01:32:55,360 --> 01:32:57,679
basic authorization string the format of
2265
01:32:57,679 --> 01:32:59,679
the string should be authorization basic
2266
01:32:59,679 --> 01:33:01,719
username colon password right so this is
2267
01:33:01,719 --> 01:33:03,840
the kind of standard basic authorization
2268
01:33:03,840 --> 01:33:06,280
that's used in HTTP requests the
2269
01:33:06,280 --> 01:33:07,719
assignment says create a method on
2270
01:33:07,719 --> 01:33:10,520
authentication info called get basic off
2271
01:33:10,520 --> 01:33:13,360
that Returns the formatted string Okay
2272
01:33:13,360 --> 01:33:18,080
cool so let's create a
2273
01:33:18,080 --> 01:33:20,880
new a new method and we can kind of
2274
01:33:20,880 --> 01:33:23,360
reference this syntax over here so it's
2275
01:33:23,360 --> 01:33:26,199
funk and we want the receiver to be an
2276
01:33:26,199 --> 01:33:27,719
authentication info struct so I'll just
2277
01:33:27,719 --> 01:33:29,520
call it AI oh that's that's actually
2278
01:33:29,520 --> 01:33:33,480
confusing let's do off aui
2279
01:33:33,480 --> 01:33:36,080
authentication
2280
01:33:36,080 --> 01:33:39,600
info and we wanted the name of the
2281
01:33:39,600 --> 01:33:41,639
method to be called get basic
2282
01:33:41,639 --> 01:33:45,199
off and it returns a
2283
01:33:45,199 --> 01:33:49,280
string okay and then we want to return
2284
01:33:49,280 --> 01:33:51,199
this format
2285
01:33:51,199 --> 01:33:54,360
here so if you remember we can use the
2286
01:33:54,360 --> 01:33:56,159
format package to do that so we'll
2287
01:33:56,159 --> 01:33:59,360
return fmts
2288
01:33:59,360 --> 01:34:02,119
printf remember s printf Returns the
2289
01:34:02,119 --> 01:34:03,400
string rather than printing it to
2290
01:34:03,400 --> 01:34:08,639
standard out or to the console and we'll
2291
01:34:09,199 --> 01:34:11,760
use that
2292
01:34:11,760 --> 01:34:14,600
template username and password are both
2293
01:34:14,600 --> 01:34:17,119
just strings so we'll use percent s for
2294
01:34:17,119 --> 01:34:19,760
our formatting verbs and then we can do
2295
01:34:19,760 --> 01:34:24,480
off I dot username first
2296
01:34:24,480 --> 01:34:27,520
and ai.
2297
01:34:27,520 --> 01:34:30,239
password next okay cool that looks
2298
01:34:30,239 --> 01:34:34,480
correct to me let's run
2299
01:34:35,080 --> 01:34:39,040
it perfect let's talk about interfaces
2300
01:34:39,040 --> 01:34:40,800
so an interface in go is just a
2301
01:34:40,800 --> 01:34:43,840
collection of method signatures for
2302
01:34:43,840 --> 01:34:45,520
example take a look at this shape
2303
01:34:45,520 --> 01:34:47,320
interface so we have an interface it's
2304
01:34:47,320 --> 01:34:50,000
named shape and it specifies two
2305
01:34:50,000 --> 01:34:52,360
different method signatures so area is a
2306
01:34:52,360 --> 01:34:55,679
method that takes no parameters and
2307
01:34:55,679 --> 01:34:58,239
returns a float 64 perimeter is another
2308
01:34:58,239 --> 01:34:59,880
method that takes no parameters and
2309
01:34:59,880 --> 01:35:02,920
returns a float 64 now any type that
2310
01:35:02,920 --> 01:35:05,800
implements both of these methods and and
2311
01:35:05,800 --> 01:35:08,480
matches their method signatures will
2312
01:35:08,480 --> 01:35:10,480
implement the shape interface which
2313
01:35:10,480 --> 01:35:11,760
really just means that we can think of
2314
01:35:11,760 --> 01:35:14,560
it and treat it as a shape so for
2315
01:35:14,560 --> 01:35:16,000
example let's take a look at this
2316
01:35:16,000 --> 01:35:19,880
rectangle struct so erect has a width
2317
01:35:19,880 --> 01:35:22,000
and a height uh both of which are float
2318
01:35:22,000 --> 01:35:24,520
64s and again this is just a this is
2319
01:35:24,520 --> 01:35:27,719
just a kind of standard struct and it
2320
01:35:27,719 --> 01:35:31,119
has two methods on it uh one is the area
2321
01:35:31,119 --> 01:35:32,760
method that takes no parameters returns
2322
01:35:32,760 --> 01:35:35,239
a float 64 um one is the perimeter that
2323
01:35:35,239 --> 01:35:37,600
takes no parameters and returns a float
2324
01:35:37,600 --> 01:35:40,320
64 and because a rectangle implements
2325
01:35:40,320 --> 01:35:42,600
both of these methods we can think of a
2326
01:35:42,600 --> 01:35:46,159
rectangle as a shape a shape is just
2327
01:35:46,159 --> 01:35:48,520
anything where we can kind of calculate
2328
01:35:48,520 --> 01:35:51,239
its area and calculate its perimeter and
2329
01:35:51,239 --> 01:35:53,320
multiple types can implement the same
2330
01:35:53,320 --> 01:35:54,159
interface
2331
01:35:54,159 --> 01:35:58,040
so for example this circle struct it has
2332
01:35:58,040 --> 01:35:59,800
different underlying data right rather
2333
01:35:59,800 --> 01:36:01,119
than a width and a height we can
2334
01:36:01,119 --> 01:36:03,960
represent a circle with just a radius um
2335
01:36:03,960 --> 01:36:05,360
but to calculate its area and its
2336
01:36:05,360 --> 01:36:07,440
perimeter the calculation is a little
2337
01:36:07,440 --> 01:36:09,199
bit different right we're using pi for
2338
01:36:09,199 --> 01:36:11,880
example um but the method signature is
2339
01:36:11,880 --> 01:36:13,600
identical right we don't pass anything
2340
01:36:13,600 --> 01:36:15,159
in because we have all the data we need
2341
01:36:15,159 --> 01:36:17,520
on the circle struct and we just return
2342
01:36:17,520 --> 01:36:20,440
a float 64 so both circles and
2343
01:36:20,440 --> 01:36:23,159
rectangles because they implement the
2344
01:36:23,159 --> 01:36:25,679
required methods can be thought of as
2345
01:36:25,679 --> 01:36:27,800
shapes or we could say they implement
2346
01:36:27,800 --> 01:36:30,159
the shape interface let's get into the
2347
01:36:30,159 --> 01:36:31,480
assignment I think it'll all start to
2348
01:36:31,480 --> 01:36:32,880
make a little more sense so the
2349
01:36:32,880 --> 01:36:34,719
assignment says the birthday message and
2350
01:36:34,719 --> 01:36:36,400
sending report strs have already
2351
01:36:36,400 --> 01:36:39,800
implemented the get message method so
2352
01:36:39,800 --> 01:36:42,080
let's take a look at that so uh birthday
2353
01:36:42,080 --> 01:36:44,360
message is this struct here sending
2354
01:36:44,360 --> 01:36:45,760
report is this struct here they both
2355
01:36:45,760 --> 01:36:48,199
have this get message method that
2356
01:36:48,199 --> 01:36:51,000
returns a string and they're just it
2357
01:36:51,000 --> 01:36:52,400
looks like the strings that they return
2358
01:36:52,400 --> 01:36:53,360
are just a little bit different right
2359
01:36:53,360 --> 01:36:56,000
the birthday messages get message uh
2360
01:36:56,000 --> 01:36:58,800
function returns this like hi blank it
2361
01:36:58,800 --> 01:37:01,239
is your birthday on blank and a sending
2362
01:37:01,239 --> 01:37:04,040
report says your blank report is ready
2363
01:37:04,040 --> 01:37:05,440
right so they just they just format a
2364
01:37:05,440 --> 01:37:06,639
little little
2365
01:37:06,639 --> 01:37:09,000
differently okay so assignment says
2366
01:37:09,000 --> 01:37:11,159
first add the get message method as a
2367
01:37:11,159 --> 01:37:14,040
requirement on the method interface okay
2368
01:37:14,040 --> 01:37:16,679
so we need to finish the message
2369
01:37:16,679 --> 01:37:20,600
interface and add a get message
2370
01:37:20,600 --> 01:37:24,159
method that returns a string
2371
01:37:24,159 --> 01:37:27,600
Okay cool so now this message interface
2372
01:37:27,600 --> 01:37:30,159
because birthday message and sending
2373
01:37:30,159 --> 01:37:33,840
report both implement this method we can
2374
01:37:33,840 --> 01:37:37,400
think of both of those as messages next
2375
01:37:37,400 --> 01:37:39,880
it says complete the send message
2376
01:37:39,880 --> 01:37:41,960
function it should print a messages
2377
01:37:41,960 --> 01:37:43,360
message which it obtains through the
2378
01:37:43,360 --> 01:37:46,440
interface meth method Okay cool so the a
2379
01:37:46,440 --> 01:37:49,760
message is an interface so inside of the
2380
01:37:49,760 --> 01:37:51,639
send message function we don't actually
2381
01:37:51,639 --> 01:37:53,639
know if we're dealing with say a
2382
01:37:53,639 --> 01:37:55,719
birthday message or a sending report we
2383
01:37:55,719 --> 01:37:57,119
just know that we have access to a
2384
01:37:57,119 --> 01:37:58,599
message so really the only thing we can
2385
01:37:58,599 --> 01:38:02,599
do with it is call get message which we
2386
01:38:02,599 --> 01:38:04,840
know will return a string and it says it
2387
01:38:04,840 --> 01:38:08,000
should print a message so we'll do ft.
2388
01:38:08,000 --> 01:38:12,520
print line just print out the message
2389
01:38:12,520 --> 01:38:15,440
cool okay now this is powerful right
2390
01:38:15,440 --> 01:38:17,920
let's go take a look at how this code is
2391
01:38:17,920 --> 01:38:19,960
actually called so we have this test
2392
01:38:19,960 --> 01:38:22,119
function that also just takes a method a
2393
01:38:22,119 --> 01:38:24,119
message and it
2394
01:38:24,119 --> 01:38:25,440
sends that message right it's just
2395
01:38:25,440 --> 01:38:28,000
calling our send message function
2396
01:38:28,000 --> 01:38:30,520
here but down here and this is where
2397
01:38:30,520 --> 01:38:33,560
it's most interesting the test function
2398
01:38:33,560 --> 01:38:37,760
is not past like interface literals
2399
01:38:37,760 --> 01:38:39,800
that's not even like a real thing right
2400
01:38:39,800 --> 01:38:41,719
an interface is like abstract type that
2401
01:38:41,719 --> 01:38:44,679
represents other types instead because
2402
01:38:44,679 --> 01:38:47,560
the test function takes an interface we
2403
01:38:47,560 --> 01:38:49,760
can pass into it any struct that
2404
01:38:49,760 --> 01:38:52,480
implements that interface so for example
2405
01:38:52,480 --> 01:38:54,360
here on line 42 we're passing in a
2406
01:38:54,360 --> 01:38:56,719
sending report and then on line 46 we're
2407
01:38:56,719 --> 01:38:58,520
passing in a birthday message those are
2408
01:38:58,520 --> 01:39:00,880
two different types in a strongly typed
2409
01:39:00,880 --> 01:39:02,800
language being passed in as the first
2410
01:39:02,800 --> 01:39:04,960
parameter to a single function but the
2411
01:39:04,960 --> 01:39:08,599
reason it works is because we're using
2412
01:39:08,599 --> 01:39:10,520
interfaces okay let's go ahead and run
2413
01:39:10,520 --> 01:39:13,360
this see what
2414
01:39:13,520 --> 01:39:15,719
happens your first report report is
2415
01:39:15,719 --> 01:39:17,760
ready you've sent 10 messages hi Dondo
2416
01:39:17,760 --> 01:39:19,320
it is your
2417
01:39:19,320 --> 01:39:22,760
birthday this looks great this looks
2418
01:39:22,760 --> 01:39:25,040
great to me
2419
01:39:25,040 --> 01:39:28,119
in go interfaces are implemented
2420
01:39:28,119 --> 01:39:30,199
implicitly and what that means is when
2421
01:39:30,199 --> 01:39:32,360
we have a type like in our last example
2422
01:39:32,360 --> 01:39:34,040
we had the rectangle type that
2423
01:39:34,040 --> 01:39:36,760
implemented the shape interface we never
2424
01:39:36,760 --> 01:39:40,199
had to explicitly write anywhere on the
2425
01:39:40,199 --> 01:39:44,159
rectangle struct that it was intended to
2426
01:39:44,159 --> 01:39:47,360
implement the shape interface because it
2427
01:39:47,360 --> 01:39:49,000
satisfied all the requirements of the
2428
01:39:49,000 --> 01:39:50,880
shape interface it just kind of
2429
01:39:50,880 --> 01:39:53,440
automatically implemented it and that's
2430
01:39:53,440 --> 01:39:55,520
fairly unique to go in a language like
2431
01:39:55,520 --> 01:39:56,760
Java we might have to write something
2432
01:39:56,760 --> 01:39:58,560
like this um we could take a look at
2433
01:39:58,560 --> 01:40:00,400
this little example here we've got this
2434
01:40:00,400 --> 01:40:02,480
employee interface and a contractor
2435
01:40:02,480 --> 01:40:05,040
struct if we wanted the contractor to
2436
01:40:05,040 --> 01:40:07,280
implement the employee we would need it
2437
01:40:07,280 --> 01:40:09,360
to still fulfill the interface right by
2438
01:40:09,360 --> 01:40:10,440
implementing all the methods but we
2439
01:40:10,440 --> 01:40:12,400
might need to also explicitly type
2440
01:40:12,400 --> 01:40:13,960
something like
2441
01:40:13,960 --> 01:40:15,520
implements
2442
01:40:15,520 --> 01:40:18,480
employee right we explicitly say that we
2443
01:40:18,480 --> 01:40:21,000
intend to implement that interface in go
2444
01:40:21,000 --> 01:40:23,040
it's done automatically let's hop into
2445
01:40:23,040 --> 01:40:25,040
the ass assignment it says at texo we
2446
01:40:25,040 --> 01:40:26,920
have full-time employees and contract
2447
01:40:26,920 --> 01:40:28,599
employees we've been tasked with making
2448
01:40:28,599 --> 01:40:31,400
a more General employee interface so
2449
01:40:31,400 --> 01:40:32,920
that dealing with different employee
2450
01:40:32,920 --> 01:40:35,360
types is a little simpler add the
2451
01:40:35,360 --> 01:40:37,440
missing get salary method to the
2452
01:40:37,440 --> 01:40:39,760
contractor type so that it fulfills the
2453
01:40:39,760 --> 01:40:42,560
employee interface Okay cool so we have
2454
01:40:42,560 --> 01:40:44,080
the employee interface we have the
2455
01:40:44,080 --> 01:40:45,599
contractor
2456
01:40:45,599 --> 01:40:47,440
struct um and if we look at the
2457
01:40:47,440 --> 01:40:48,800
full-time struct it looks like it
2458
01:40:48,800 --> 01:40:49,880
already
2459
01:40:49,880 --> 01:40:53,119
implements the employee interface so we
2460
01:40:53,119 --> 01:40:56,119
just need to add the Missing Method
2461
01:40:56,119 --> 01:40:58,960
because right now a contractor has a get
2462
01:40:58,960 --> 01:41:01,080
name but does not have a get salary Okay
2463
01:41:01,080 --> 01:41:03,239
cool so let's go ahead and do that we'll
2464
01:41:03,239 --> 01:41:04,800
do
2465
01:41:04,800 --> 01:41:07,960
employee get salary it returns an
2466
01:41:07,960 --> 01:41:11,199
INT and a contractor's salary is their
2467
01:41:11,199 --> 01:41:13,719
hourly pay multiplied by how many hours
2468
01:41:13,719 --> 01:41:18,679
they work per year okay so be something
2469
01:41:18,679 --> 01:41:20,679
like
2470
01:41:20,679 --> 01:41:27,679
c. hourly pay multiplied by c. hours
2471
01:41:27,679 --> 01:41:29,639
per
2472
01:41:29,639 --> 01:41:32,400
year okay and just because I'm curious I
2473
01:41:32,400 --> 01:41:33,880
want to go look at how a full-time
2474
01:41:33,880 --> 01:41:37,159
salary uh employee works yeah so you can
2475
01:41:37,159 --> 01:41:39,840
see the the way that a full-time
2476
01:41:39,840 --> 01:41:42,280
employee their salary is calculated is
2477
01:41:42,280 --> 01:41:43,679
is totally different like their their
2478
01:41:43,679 --> 01:41:45,719
salary is actually just stored probably
2479
01:41:45,719 --> 01:41:46,840
because the way we think of full-time
2480
01:41:46,840 --> 01:41:48,000
employees is like you know you make
2481
01:41:48,000 --> 01:41:50,520
$60,000 a year you make $70,000 a year
2482
01:41:50,520 --> 01:41:52,760
whereas contractors often get paid by
2483
01:41:52,760 --> 01:41:54,119
the hour so it make sense that they have
2484
01:41:54,119 --> 01:41:56,960
a different calculation um and then down
2485
01:41:56,960 --> 01:41:59,320
here in the test Suite um this looks
2486
01:41:59,320 --> 01:42:00,920
very similar to the last assignment
2487
01:42:00,920 --> 01:42:03,599
where the test function is able to take
2488
01:42:03,599 --> 01:42:06,480
as inputs any type of employee right so
2489
01:42:06,480 --> 01:42:08,080
we can pass in both full-time and
2490
01:42:08,080 --> 01:42:09,840
contractors here uh let's go ahead and
2491
01:42:09,840 --> 01:42:12,080
run
2492
01:42:13,719 --> 01:42:17,199
that Jack Bob and Jill we can see all of
2493
01:42:17,199 --> 01:42:21,159
their salaries even
2494
01:42:21,239 --> 01:42:24,119
though Jack is full-time and Bob and
2495
01:42:24,119 --> 01:42:26,320
Jill are both contractors so that looks
2496
01:42:26,320 --> 01:42:29,920
good to me in go types Implement
2497
01:42:29,920 --> 01:42:31,840
interfaces implicitly because it kind of
2498
01:42:31,840 --> 01:42:33,560
decouples the definition of the
2499
01:42:33,560 --> 01:42:35,679
interface from the definition of the
2500
01:42:35,679 --> 01:42:37,480
type the type doesn't even really need
2501
01:42:37,480 --> 01:42:40,199
to know that it implements a certain
2502
01:42:40,199 --> 01:42:42,960
interface and that's really really cool
2503
01:42:42,960 --> 01:42:45,080
because it means it's easy for a type to
2504
01:42:45,080 --> 01:42:47,760
inter to implement lots of different
2505
01:42:47,760 --> 01:42:50,199
interfaces so the quiz question here is
2506
01:42:50,199 --> 01:42:52,719
how is an interface fulfilled answers
2507
01:42:52,719 --> 01:42:55,119
are type has all the required interfaces
2508
01:42:55,119 --> 01:42:58,360
methods defined on it or a struct embeds
2509
01:42:58,360 --> 01:43:00,800
the interface in its definition and the
2510
01:43:00,800 --> 01:43:02,560
answer is going to be it has all the
2511
01:43:02,560 --> 01:43:05,040
methods defined the next question is can
2512
01:43:05,040 --> 01:43:08,119
a Type fulfill multiple interfaces or
2513
01:43:08,119 --> 01:43:11,119
Implement multiple interfaces and yes
2514
01:43:11,119 --> 01:43:13,800
why not another quiz question go uses
2515
01:43:13,800 --> 01:43:16,199
the blank keyword to show that a type
2516
01:43:16,199 --> 01:43:18,480
implements an interface and the answers
2517
01:43:18,480 --> 01:43:20,400
are fulfills implements inherits and
2518
01:43:20,400 --> 01:43:22,719
there is no keyword in go and the answer
2519
01:43:22,719 --> 01:43:24,760
is that there there is no keyword in go
2520
01:43:24,760 --> 01:43:28,280
interfaces are implemented
2521
01:43:31,280 --> 01:43:33,639
implicitly in the next question it says
2522
01:43:33,639 --> 01:43:36,280
in the example given the blank type
2523
01:43:36,280 --> 01:43:38,679
implements the blank interface let's
2524
01:43:38,679 --> 01:43:41,800
take a look so example here we've got
2525
01:43:41,800 --> 01:43:45,199
the shape interface circle
2526
01:43:45,199 --> 01:43:48,040
struct circle has an area method so it
2527
01:43:48,040 --> 01:43:50,560
looks like the circle type implements
2528
01:43:50,560 --> 01:43:52,800
the shape interface like we talked about
2529
01:43:52,800 --> 01:43:55,239
before or a type can Implement multiple
2530
01:43:55,239 --> 01:43:57,119
interfaces it just needs to have all the
2531
01:43:57,119 --> 01:43:58,440
methods for all of the different
2532
01:43:58,440 --> 01:44:00,639
interfaces for example the empty
2533
01:44:00,639 --> 01:44:02,960
interface so that's this this definition
2534
01:44:02,960 --> 01:44:05,520
right here this is an interface with no
2535
01:44:05,520 --> 01:44:08,639
methods required is actually always
2536
01:44:08,639 --> 01:44:11,560
implemented by every single type in the
2537
01:44:11,560 --> 01:44:13,679
go programming language now it's often
2538
01:44:13,679 --> 01:44:15,760
not a very useful interface because you
2539
01:44:15,760 --> 01:44:17,480
can't really do anything with an empty
2540
01:44:17,480 --> 01:44:19,880
interface you have no methods to call
2541
01:44:19,880 --> 01:44:21,880
let's jump down into the assignment it
2542
01:44:21,880 --> 01:44:23,719
says add the required methods the email
2543
01:44:23,719 --> 01:44:25,920
typee implements both the expense and
2544
01:44:25,920 --> 01:44:28,040
printer interfaces Okay cool so we got
2545
01:44:28,040 --> 01:44:31,320
these expense and printer interfaces two
2546
01:44:31,320 --> 01:44:33,520
different methods we need to implement
2547
01:44:33,520 --> 01:44:35,480
and we have this email type with an is
2548
01:44:35,480 --> 01:44:39,520
subscribed Boolean and body string cool
2549
01:44:39,520 --> 01:44:40,800
all right cost
2550
01:44:40,800 --> 01:44:43,760
method if the email is not subscribed so
2551
01:44:43,760 --> 01:44:47,440
if not e do is subscribed I believe is
2552
01:44:47,440 --> 01:44:51,080
what the field was then the cost is
2553
01:44:51,080 --> 01:44:54,320
0.05 times
2554
01:44:54,320 --> 01:44:57,760
uh the length for each character in the
2555
01:44:57,760 --> 01:45:01,560
body so the length e do body now
2556
01:45:01,560 --> 01:45:03,960
remember go is strongly typed and we
2557
01:45:03,960 --> 01:45:06,320
can't multiply an INT by a float
2558
01:45:06,320 --> 01:45:08,760
directly so we need to cast this integer
2559
01:45:08,760 --> 01:45:11,560
sorry I think I highlighted those
2560
01:45:11,560 --> 01:45:13,639
backwards the length of the body is an
2561
01:45:13,639 --> 01:45:16,199
integer this is a float so we need to
2562
01:45:16,199 --> 01:45:18,520
cast the length of the body to a float
2563
01:45:18,520 --> 01:45:20,960
so we can we can multiply a float by a
2564
01:45:20,960 --> 01:45:24,159
float um otherwise we'll
2565
01:45:24,159 --> 01:45:27,760
turn uh it's
2566
01:45:28,440 --> 01:45:31,560
0.01 times that same thing the length of
2567
01:45:31,560 --> 01:45:34,639
the body cool uh the print function
2568
01:45:34,639 --> 01:45:35,920
should just print to standard out the
2569
01:45:35,920 --> 01:45:39,560
emails body text easy enough fm.
2570
01:45:39,560 --> 01:45:42,880
printline e.
2571
01:45:42,880 --> 01:45:47,159
body okay so now our email struct
2572
01:45:47,159 --> 01:45:49,639
implements both of these interfaces and
2573
01:45:49,639 --> 01:45:54,400
if we come down here to look at the test
2574
01:45:54,400 --> 01:45:56,599
function this is interesting the test
2575
01:45:56,599 --> 01:45:59,520
function takes an expense and a
2576
01:45:59,520 --> 01:46:01,560
printer right so we can use both of
2577
01:46:01,560 --> 01:46:03,119
those uh methods
2578
01:46:03,119 --> 01:46:07,480
there and actually the email struct so
2579
01:46:07,480 --> 01:46:09,760
we're creating instances of emails here
2580
01:46:09,760 --> 01:46:12,440
we're actually passing it into test as
2581
01:46:12,440 --> 01:46:15,480
both the expense and the printer right
2582
01:46:15,480 --> 01:46:17,080
because it makes sense it implements
2583
01:46:17,080 --> 01:46:19,520
both cool let me run
2584
01:46:19,520 --> 01:46:23,080
that oh what did I screw up 05 time FL 6
2585
01:46:23,080 --> 01:46:27,800
4 length value of type float 64 is not
2586
01:46:28,040 --> 01:46:30,760
used let's
2587
01:46:30,760 --> 01:46:36,719
see 0.05 time float 64 length of e body
2588
01:46:36,719 --> 01:46:39,119
what did I screw up value of type float
2589
01:46:39,119 --> 01:46:42,239
64 is not
2590
01:46:42,280 --> 01:46:45,760
used I forgot my return cool let's try
2591
01:46:45,760 --> 01:46:47,960
that
2592
01:46:49,360 --> 01:46:51,840
again okay
2593
01:46:51,840 --> 01:46:54,840
so printing with cost 11 cents hello
2594
01:46:54,840 --> 01:46:56,920
there printing with cost $1 I want my
2595
01:46:56,920 --> 01:46:58,920
money back yeah that looks that looks
2596
01:46:58,920 --> 01:47:01,760
pretty good let's submit
2597
01:47:01,760 --> 01:47:03,960
it up until this point we haven't really
2598
01:47:03,960 --> 01:47:06,480
been naming the arguments of our
2599
01:47:06,480 --> 01:47:09,280
interfaces method signatures um but we
2600
01:47:09,280 --> 01:47:11,119
totally could so if we take a look at
2601
01:47:11,119 --> 01:47:14,360
this this is The copier interface it's a
2602
01:47:14,360 --> 01:47:16,239
uh copy method that it requires which
2603
01:47:16,239 --> 01:47:19,000
takes two strings and returns an INT um
2604
01:47:19,000 --> 01:47:20,360
the interesting thing is when you look
2605
01:47:20,360 --> 01:47:22,360
at this method signature it's kind of
2606
01:47:22,360 --> 01:47:25,159
hard to tell what the intention behind
2607
01:47:25,159 --> 01:47:26,920
the interface is it's like great it
2608
01:47:26,920 --> 01:47:28,760
takes two strings but what are those
2609
01:47:28,760 --> 01:47:31,719
strings supposed to represent right so
2610
01:47:31,719 --> 01:47:34,239
here we can take a look at what I would
2611
01:47:34,239 --> 01:47:36,920
consider a better interface definition
2612
01:47:36,920 --> 01:47:38,960
where The copier interface actually has
2613
01:47:38,960 --> 01:47:41,360
a copy method that specifies the source
2614
01:47:41,360 --> 01:47:43,920
file is kind of the name of the first
2615
01:47:43,920 --> 01:47:46,560
parameter and the destination file is
2616
01:47:46,560 --> 01:47:48,560
the name of the second parameter and
2617
01:47:48,560 --> 01:47:51,560
then byes copied is the integer that's
2618
01:47:51,560 --> 01:47:54,800
returned so you know the functionality
2619
01:47:54,800 --> 01:47:57,199
here is identical but now we have much
2620
01:47:57,199 --> 01:47:59,920
better I I mean I would consider it
2621
01:47:59,920 --> 01:48:02,080
documentation of what the intention
2622
01:48:02,080 --> 01:48:05,199
behind this interface is so the question
2623
01:48:05,199 --> 01:48:06,840
is are you required to name the
2624
01:48:06,840 --> 01:48:08,280
arguments of an interface in order for
2625
01:48:08,280 --> 01:48:11,679
your code to compile properly uh no no
2626
01:48:11,679 --> 01:48:14,400
it'll work fine either way next question
2627
01:48:14,400 --> 01:48:16,560
is why would you name your interfaces
2628
01:48:16,560 --> 01:48:18,400
methods parameters right like we don't
2629
01:48:18,400 --> 01:48:20,599
need to why would we do it um execution
2630
01:48:20,599 --> 01:48:22,760
speed memory savings or readability and
2631
01:48:22,760 --> 01:48:24,360
Clarity uh it's going to be for
2632
01:48:24,360 --> 01:48:27,599
readability and Clarity type assertions
2633
01:48:27,599 --> 01:48:30,159
so type assertions are something you'll
2634
01:48:30,159 --> 01:48:31,880
see every once in a while I would argue
2635
01:48:31,880 --> 01:48:33,480
they're probably not super common but
2636
01:48:33,480 --> 01:48:35,639
you will come across them um and the
2637
01:48:35,639 --> 01:48:37,119
whole purpose of a type assertion is so
2638
01:48:37,119 --> 01:48:39,239
that you can take an interface and kind
2639
01:48:39,239 --> 01:48:42,880
of cast it back into its underlying type
2640
01:48:42,880 --> 01:48:45,320
so in this code sample here we can kind
2641
01:48:45,320 --> 01:48:48,280
of assume that s is an instance of a
2642
01:48:48,280 --> 01:48:50,360
shape interface and at this point in the
2643
01:48:50,360 --> 01:48:51,920
code because it's just an interface we
2644
01:48:51,920 --> 01:48:54,280
don't know NE neily if it's a circle or
2645
01:48:54,280 --> 01:48:56,440
maybe a square or maybe some other type
2646
01:48:56,440 --> 01:49:00,040
so what we do is we do a type assertion
2647
01:49:00,040 --> 01:49:03,599
to cast it to the circle struct and
2648
01:49:03,599 --> 01:49:05,599
basically what happens here is on the
2649
01:49:05,599 --> 01:49:10,159
left hand side of the um this uh short
2650
01:49:10,159 --> 01:49:12,719
declaration operator here we get back
2651
01:49:12,719 --> 01:49:14,760
the instance of the circle so this is
2652
01:49:14,760 --> 01:49:17,040
going to be an instance of the circle
2653
01:49:17,040 --> 01:49:19,599
struct again the underlying struct um
2654
01:49:19,599 --> 01:49:23,480
behind the shape interface if it was a
2655
01:49:23,480 --> 01:49:25,760
circle right because we we can't be sure
2656
01:49:25,760 --> 01:49:27,080
if we had a shape we're not sure if it
2657
01:49:27,080 --> 01:49:28,920
was a circle or maybe something else but
2658
01:49:28,920 --> 01:49:32,119
this okay variable this is going to be a
2659
01:49:32,119 --> 01:49:36,400
Boolean and if it's true then it was a
2660
01:49:36,400 --> 01:49:38,040
circle and we should have a valid kind
2661
01:49:38,040 --> 01:49:41,800
of filled out Circle struct if okay is
2662
01:49:41,800 --> 01:49:43,599
false then we kind of have to discard
2663
01:49:43,599 --> 01:49:46,119
the circle um because we we weren't able
2664
01:49:46,119 --> 01:49:49,080
to parse out um the shape as a circle
2665
01:49:49,080 --> 01:49:52,119
because it wasn't a circle so let's move
2666
01:49:52,119 --> 01:49:53,840
on to the assign it's an email then it
2667
01:49:53,840 --> 01:49:55,280
should return the email's two address
2668
01:49:55,280 --> 01:49:57,080
and the cost of the email if the expense
2669
01:49:57,080 --> 01:49:58,560
is an SMS then it should return the
2670
01:49:58,560 --> 01:50:01,239
sms's phone number and cost if the
2671
01:50:01,239 --> 01:50:02,800
expense is any other underlying type
2672
01:50:02,800 --> 01:50:05,000
just return an empty string and a 0.0
2673
01:50:05,000 --> 01:50:07,080
for the cost Okay cool so we've got this
2674
01:50:07,080 --> 01:50:09,880
get expense report that takes an expense
2675
01:50:09,880 --> 01:50:13,320
as input and my guess is yep expense is
2676
01:50:13,320 --> 01:50:16,679
this interface so our job is to kind of
2677
01:50:16,679 --> 01:50:19,239
try to cast it into the potential
2678
01:50:19,239 --> 01:50:23,239
underlying types email and SMS
2679
01:50:23,239 --> 01:50:28,639
so first we do um email
2680
01:50:28,639 --> 01:50:32,880
okay uh expense Dot and we'll cast it to
2681
01:50:32,880 --> 01:50:36,520
an email type if
2682
01:50:36,520 --> 01:50:39,119
okay so if it's an email return the
2683
01:50:39,119 --> 01:50:46,880
emails to address so uh return email. to
2684
01:50:47,800 --> 01:50:52,840
address as that string there and also so
2685
01:50:52,840 --> 01:50:56,159
it's cost so email dot looks like cost
2686
01:50:56,159 --> 01:51:00,480
is a method email. cost
2687
01:51:00,480 --> 01:51:06,000
okay uh next we can do s
2688
01:51:06,000 --> 01:51:10,800
okay uh e do cast to an SMS so if it's
2689
01:51:10,800 --> 01:51:13,520
an SMS we can
2690
01:51:13,520 --> 01:51:19,840
return sms's to phone number to phone
2691
01:51:19,840 --> 01:51:23,639
number and the SMS Dot cost I believe
2692
01:51:23,639 --> 01:51:26,639
that's also just yep just a
2693
01:51:26,639 --> 01:51:29,920
method okay and it says otherwise if it
2694
01:51:29,920 --> 01:51:33,719
has a different underlying type return
2695
01:51:33,719 --> 01:51:35,000
empty
2696
01:51:35,000 --> 01:51:40,400
string and 0.0 for the cost okay cool
2697
01:51:40,400 --> 01:51:42,599
that
2698
01:51:42,599 --> 01:51:44,800
feels at least like we followed the
2699
01:51:44,800 --> 01:51:47,040
instructions let's see what we
2700
01:51:47,040 --> 01:51:50,440
get not enough arguments in call to sms.
2701
01:51:50,440 --> 01:51:53,920
cost let's take a look at sms. cost
2702
01:51:53,920 --> 01:51:56,239
cost
2703
01:51:56,239 --> 01:51:58,239
H have
2704
01:51:58,239 --> 01:52:02,760
want what did I screw up
2705
01:52:03,440 --> 01:52:07,560
here ah should be s. cost I I named I
2706
01:52:07,560 --> 01:52:09,800
named this truck the struct S all right
2707
01:52:09,800 --> 01:52:12,360
let's try that
2708
01:52:12,560 --> 01:52:15,040
again report the email going to John do
2709
01:52:15,040 --> 01:52:20,159
will cost 11 email the sms okay cool and
2710
01:52:20,159 --> 01:52:22,800
invalid expense perfect that I mean that
2711
01:52:22,800 --> 01:52:24,159
feels right I can come down here and
2712
01:52:24,159 --> 01:52:27,440
check the test Suite yeah invalid okay
2713
01:52:27,440 --> 01:52:29,920
cool let's submit that when we want to
2714
01:52:29,920 --> 01:52:32,239
do a lot of successive type assertions
2715
01:52:32,239 --> 01:52:34,199
in a row there's actually a better way
2716
01:52:34,199 --> 01:52:36,679
and that's with type switches so here's
2717
01:52:36,679 --> 01:52:39,440
a Syntax for a type switch uh basically
2718
01:52:39,440 --> 01:52:43,040
we have an interface and we cast it um
2719
01:52:43,040 --> 01:52:44,560
at the very top of the switch and then
2720
01:52:44,560 --> 01:52:46,000
we can actually check and kind of
2721
01:52:46,000 --> 01:52:49,360
pattern match against different possible
2722
01:52:49,360 --> 01:52:52,000
types if none of the types that we've
2723
01:52:52,000 --> 01:52:54,280
specified are the matching underlying
2724
01:52:54,280 --> 01:52:56,679
type then it will kind of fall down to
2725
01:52:56,679 --> 01:52:59,159
the default case so let's write some
2726
01:52:59,159 --> 01:53:01,239
code and see how it works um down in the
2727
01:53:01,239 --> 01:53:02,840
assignment it says after submitting our
2728
01:53:02,840 --> 01:53:04,560
last snippet of code for review a more
2729
01:53:04,560 --> 01:53:07,560
experienced gopher or term for a go
2730
01:53:07,560 --> 01:53:09,320
developer uh told us to use a type
2731
01:53:09,320 --> 01:53:11,920
switch instead of successive assertions
2732
01:53:11,920 --> 01:53:13,920
let's make that Improvement implement
2733
01:53:13,920 --> 01:53:16,119
the get expense report function using a
2734
01:53:16,119 --> 01:53:19,520
type switch Okay cool so kind of the
2735
01:53:19,520 --> 01:53:21,920
same thing though if it's an email
2736
01:53:21,920 --> 01:53:23,520
return a to address and a cost if it's
2737
01:53:23,520 --> 01:53:25,040
an SMS then we should return a phone
2738
01:53:25,040 --> 01:53:27,440
number and a cost blah blah blah right
2739
01:53:27,440 --> 01:53:28,560
the difference is we're going to use a
2740
01:53:28,560 --> 01:53:31,079
different syntax this time okay so we're
2741
01:53:31,079 --> 01:53:36,239
going to be using this switch syntax so
2742
01:53:36,599 --> 01:53:42,520
switch value colon equals e.type
2743
01:53:42,520 --> 01:53:46,840
okay Open brackets case um we are
2744
01:53:46,840 --> 01:53:50,079
interested in if the expense is an
2745
01:53:50,079 --> 01:53:52,480
email so case email now the the
2746
01:53:52,480 --> 01:53:53,960
interesting thing is with now within
2747
01:53:53,960 --> 01:53:57,719
this case block V is an email so I can
2748
01:53:57,719 --> 01:53:59,239
treat it like an email so I can do
2749
01:53:59,239 --> 01:54:01,639
return V
2750
01:54:01,639 --> 01:54:04,880
Dot oh what was it two address I think
2751
01:54:04,880 --> 01:54:07,679
yeah two
2752
01:54:07,679 --> 01:54:11,239
address b.
2753
01:54:11,239 --> 01:54:14,719
cost a
2754
01:54:14,719 --> 01:54:19,639
SMS return B do two phone number I think
2755
01:54:19,639 --> 01:54:24,480
it was two phone number b.
2756
01:54:24,480 --> 01:54:27,199
cost and
2757
01:54:27,199 --> 01:54:29,159
default
2758
01:54:29,159 --> 01:54:31,719
return uh I think it was empty string
2759
01:54:31,719 --> 01:54:34,960
just zero values right empty string and
2760
01:54:34,960 --> 01:54:38,199
0.0 okay cool let's see what
2761
01:54:38,199 --> 01:54:40,920
happens with that oh am I forgetting
2762
01:54:40,920 --> 01:54:41,920
nope I've
2763
01:54:41,920 --> 01:54:44,520
got oh I'm indenting a little
2764
01:54:44,520 --> 01:54:48,639
weird there we go let's run
2765
01:54:48,639 --> 01:54:52,119
that cool the MS SMS is going to be is
2766
01:54:52,119 --> 01:54:54,199
going to this number with this
2767
01:54:54,199 --> 01:54:57,079
cost got some emails and costs okay
2768
01:54:57,079 --> 01:54:58,920
that's looking good to me now that we've
2769
01:54:58,920 --> 01:55:01,280
learned what interfaces are and how we
2770
01:55:01,280 --> 01:55:03,199
use them let's talk about how we can use
2771
01:55:03,199 --> 01:55:05,480
them more effective and in a sort of
2772
01:55:05,480 --> 01:55:08,960
idiomatic and clean way if you forget
2773
01:55:08,960 --> 01:55:10,880
all of the other advice that we're going
2774
01:55:10,880 --> 01:55:12,719
to go over when it comes to writing
2775
01:55:12,719 --> 01:55:15,119
clean interfaces don't forget this one
2776
01:55:15,119 --> 01:55:17,719
and that is to keep interfaces as small
2777
01:55:17,719 --> 01:55:20,719
as you can the best the cleanest and the
2778
01:55:20,719 --> 01:55:22,840
most useful interfaces typically just
2779
01:55:22,840 --> 01:55:25,920
have one or two methods defined on them
2780
01:55:25,920 --> 01:55:29,000
imagine a simple Stringer interface it
2781
01:55:29,000 --> 01:55:30,760
has one method defined on it called
2782
01:55:30,760 --> 01:55:33,280
string that simply returns a string you
2783
01:55:33,280 --> 01:55:36,159
can take that interface and implement it
2784
01:55:36,159 --> 01:55:38,480
on basically any type and now you have a
2785
01:55:38,480 --> 01:55:41,199
super useful interface for logging out
2786
01:55:41,199 --> 01:55:43,079
string representations of different
2787
01:55:43,079 --> 01:55:45,719
types there isn't a hard and fast rule
2788
01:55:45,719 --> 01:55:47,560
about exactly how many methods you
2789
01:55:47,560 --> 01:55:49,639
should be defining on your interfaces
2790
01:55:49,639 --> 01:55:51,440
but what you really should be doing is
2791
01:55:51,440 --> 01:55:54,560
looking for kind of the minimal Behavior
2792
01:55:54,560 --> 01:55:56,679
necessary to accurately represent an
2793
01:55:56,679 --> 01:55:59,360
idea or concept right so for example
2794
01:55:59,360 --> 01:56:02,360
here's a slightly larger interface from
2795
01:56:02,360 --> 01:56:04,159
the standard Library again normally
2796
01:56:04,159 --> 01:56:05,520
we'll see interfaces in the standard
2797
01:56:05,520 --> 01:56:07,760
library with maybe just one or two or
2798
01:56:07,760 --> 01:56:11,239
three uh methods this one has five but
2799
01:56:11,239 --> 01:56:14,480
this is kind of still the minimum um
2800
01:56:14,480 --> 01:56:16,920
amount or or the the the minimal
2801
01:56:16,920 --> 01:56:18,960
necessary behavior that we need to
2802
01:56:18,960 --> 01:56:21,599
describe a file like a file in your file
2803
01:56:21,599 --> 01:56:23,520
system right we need a way to close the
2804
01:56:23,520 --> 01:56:25,520
file we need a way to read it we need a
2805
01:56:25,520 --> 01:56:28,480
way to seek to individual uh kind of
2806
01:56:28,480 --> 01:56:32,320
sections of the file um so this is an
2807
01:56:32,320 --> 01:56:34,360
example of a slightly larger interface
2808
01:56:34,360 --> 01:56:35,880
right I would say five methods is
2809
01:56:35,880 --> 01:56:38,840
definitely a on the larger end um but
2810
01:56:38,840 --> 01:56:41,840
it's still a good interface because it's
2811
01:56:41,840 --> 01:56:44,360
using as as little Behavior as it
2812
01:56:44,360 --> 01:56:47,040
possibly can to describe an operating
2813
01:56:47,040 --> 01:56:49,280
system file so the question that goes
2814
01:56:49,280 --> 01:56:51,520
along with this is interfaces should
2815
01:56:51,520 --> 01:56:54,400
have as blank methods as possible and
2816
01:56:54,400 --> 01:56:56,639
the answers are complex few and many and
2817
01:56:56,639 --> 01:56:59,800
the answer is going to be few the next
2818
01:56:59,800 --> 01:57:02,079
mistake that I've seen new go developers
2819
01:57:02,079 --> 01:57:04,719
make is when they write an interface
2820
01:57:04,719 --> 01:57:08,119
that sort of knows about the types that
2821
01:57:08,119 --> 01:57:11,199
they've intended to satisfy it so for
2822
01:57:11,199 --> 01:57:14,079
example if you have a car interface and
2823
01:57:14,079 --> 01:57:17,280
you've defined an is fire truck method
2824
01:57:17,280 --> 01:57:19,760
on the car interface that returns a buou
2825
01:57:19,760 --> 01:57:21,119
you know whether or not it's a fire
2826
01:57:21,119 --> 01:57:23,119
truck that's probably a mistake you
2827
01:57:23,119 --> 01:57:25,119
would actually just want to use a type
2828
01:57:25,119 --> 01:57:27,040
assertion or a type switch if you really
2829
01:57:27,040 --> 01:57:29,840
needed to figure out the underlying type
2830
01:57:29,840 --> 01:57:31,920
you should not make your interfaces
2831
01:57:31,920 --> 01:57:34,079
aware of the underlying types this also
2832
01:57:34,079 --> 01:57:35,800
breaks rule number one right because
2833
01:57:35,800 --> 01:57:37,960
rule number one we don't need to know if
2834
01:57:37,960 --> 01:57:40,639
a car is a firetr for like the minimal
2835
01:57:40,639 --> 01:57:43,800
behavior of a car I mean you can see how
2836
01:57:43,800 --> 01:57:45,760
this sort of design pattern would get
2837
01:57:45,760 --> 01:57:47,679
out of hand very quickly because we
2838
01:57:47,679 --> 01:57:49,840
might need to also Define other booleans
2839
01:57:49,840 --> 01:57:53,280
like is pickup is sedan is tank right if
2840
01:57:53,280 --> 01:57:55,079
you start catering to all of the
2841
01:57:55,079 --> 01:57:57,280
underlying types of a given interface
2842
01:57:57,280 --> 01:57:58,599
your interface is going to be really
2843
01:57:58,599 --> 01:58:01,040
bloated and become very very large so
2844
01:58:01,040 --> 01:58:02,760
the question here is actually the
2845
01:58:02,760 --> 01:58:05,560
reverse it says it's okay for types to
2846
01:58:05,560 --> 01:58:07,639
be aware of the interfaces that they
2847
01:58:07,639 --> 01:58:09,960
satisfy if it were flipped around the
2848
01:58:09,960 --> 01:58:11,800
answer would definitely be false but
2849
01:58:11,800 --> 01:58:12,960
because we're talking about the types
2850
01:58:12,960 --> 01:58:14,520
being aware of the interfaces they
2851
01:58:14,520 --> 01:58:16,400
satisfy I don't think that's necessarily
2852
01:58:16,400 --> 01:58:18,760
a problem um they don't need to be aware
2853
01:58:18,760 --> 01:58:22,119
of them right because again in go uh
2854
01:58:22,119 --> 01:58:24,119
interfaces are satisfied implicitly but
2855
01:58:24,119 --> 01:58:26,119
I would argue to some extent they are
2856
01:58:26,119 --> 01:58:28,040
aware of them because the developer had
2857
01:58:28,040 --> 01:58:31,599
to go in some cases out of their way to
2858
01:58:31,599 --> 01:58:33,280
satisfy the implementation of an
2859
01:58:33,280 --> 01:58:35,079
interface so I'm going to go with true
2860
01:58:35,079 --> 01:58:37,639
on this one so now this is the reverse
2861
01:58:37,639 --> 01:58:38,880
question it says it's okay for
2862
01:58:38,880 --> 01:58:40,599
interfaces to be aware of the types that
2863
01:58:40,599 --> 01:58:43,599
satisfy them no they should not be aware
2864
01:58:43,599 --> 01:58:45,280
finally I just want to talk about how
2865
01:58:45,280 --> 01:58:47,840
interfaces are not classes sometimes
2866
01:58:47,840 --> 01:58:49,239
this can get mixed up especially if
2867
01:58:49,239 --> 01:58:50,760
you're coming from an object-oriented
2868
01:58:50,760 --> 01:58:53,119
background um inter Es are just a very
2869
01:58:53,119 --> 01:58:55,199
different idea interfaces are not
2870
01:58:55,199 --> 01:58:57,000
classes they are much Slimmer right
2871
01:58:57,000 --> 01:58:58,599
classes have a lot of functionality
2872
01:58:58,599 --> 01:59:00,960
going on inheritance is a fairly complex
2873
01:59:00,960 --> 01:59:04,679
topic um interfaces are honestly just a
2874
01:59:04,679 --> 01:59:07,760
simpler idea um interfaces don't have
2875
01:59:07,760 --> 01:59:09,560
Constructors or deconstructors that
2876
01:59:09,560 --> 01:59:11,199
require that data is created or
2877
01:59:11,199 --> 01:59:12,679
destroyed right so that's another way
2878
01:59:12,679 --> 01:59:14,760
that they differ from classes that have
2879
01:59:14,760 --> 01:59:17,800
kind of this in inherent setup and tear
2880
01:59:17,800 --> 01:59:20,920
down uh situation interfaces are not
2881
01:59:20,920 --> 01:59:23,760
hierarchical right there's there's no uh
2882
01:59:23,760 --> 01:59:25,800
hierarchical inheritance tree when it
2883
01:59:25,800 --> 01:59:28,040
comes to interfaces and the most
2884
01:59:28,040 --> 01:59:30,320
interesting one is that interfaces
2885
01:59:30,320 --> 01:59:33,000
Define functions signatures but not
2886
01:59:33,000 --> 01:59:35,360
underlying Behavior right so this is
2887
01:59:35,360 --> 01:59:37,639
actually a big difference between
2888
01:59:37,639 --> 01:59:41,400
interfaces in classes in a class A Child
2889
01:59:41,400 --> 01:59:44,199
class can inherit behavior from a parent
2890
01:59:44,199 --> 01:59:46,360
class which can kind of dry up your code
2891
01:59:46,360 --> 01:59:49,000
right don't repeat yourself in go that's
2892
01:59:49,000 --> 01:59:50,520
not the case at all an interface doesn't
2893
01:59:50,520 --> 01:59:52,400
dry up your code you still have to go
2894
01:59:52,400 --> 01:59:54,280
Implement all of the methods on all of
2895
01:59:54,280 --> 01:59:56,480
the different types individually
2896
01:59:56,480 --> 01:59:58,639
interfaces just allow us to use all of
2897
01:59:58,639 --> 02:00:01,760
those types kind of in the same places
2898
02:00:01,760 --> 02:00:03,920
later in this course we'll get to talk
2899
02:00:03,920 --> 02:00:07,400
about generics which is a way to kind of
2900
02:00:07,400 --> 02:00:10,119
dry up your code and funny enough kind
2901
02:00:10,119 --> 02:00:13,320
of uses interfaces um under the hood or
2902
02:00:13,320 --> 02:00:16,679
kind of as a part of the generic system
2903
02:00:16,679 --> 02:00:19,400
to make that happen so finally the
2904
02:00:19,400 --> 02:00:21,239
question is interfaces allow you to
2905
02:00:21,239 --> 02:00:23,599
define a method's Behavior once and use
2906
02:00:23,599 --> 02:00:26,800
it for many different types uh that's
2907
02:00:26,800 --> 02:00:29,960
false go has a very unique way of
2908
02:00:29,960 --> 02:00:32,400
handling errors really quickly let's
2909
02:00:32,400 --> 02:00:35,000
review how JavaScript handles errors and
2910
02:00:35,000 --> 02:00:36,320
the way JavaScript handles errors is
2911
02:00:36,320 --> 02:00:38,920
very similar to python or Java it uses a
2912
02:00:38,920 --> 02:00:41,199
TR catch Paradigm um and let's contrast
2913
02:00:41,199 --> 02:00:43,679
that with how go handles errors in its
2914
02:00:43,679 --> 02:00:45,760
sort of unique way let's pretend that we
2915
02:00:45,760 --> 02:00:48,520
have a function called get user um and
2916
02:00:48,520 --> 02:00:50,360
we'll start with JavaScript so we have a
2917
02:00:50,360 --> 02:00:52,679
function called get user
2918
02:00:52,679 --> 02:00:56,239
whoa and it Returns the user so we'll do
2919
02:00:56,239 --> 02:00:59,560
const user equals get user and we have
2920
02:00:59,560 --> 02:01:01,960
to wrap the get user function the call
2921
02:01:01,960 --> 02:01:04,199
to the get user function and a tri block
2922
02:01:04,199 --> 02:01:05,840
because we know that the get user
2923
02:01:05,840 --> 02:01:07,239
function can throw because let's just
2924
02:01:07,239 --> 02:01:09,679
say for example uh maybe the user
2925
02:01:09,679 --> 02:01:12,520
doesn't exist Okay cool so if something
2926
02:01:12,520 --> 02:01:16,280
goes wrong we add a catch block and if
2927
02:01:16,280 --> 02:01:18,679
this function throws execution will stop
2928
02:01:18,679 --> 02:01:20,119
we'll enter the catch block and do
2929
02:01:20,119 --> 02:01:22,199
whatever is in here for now we can just
2930
02:01:22,199 --> 02:01:23,800
uh console.
2931
02:01:23,800 --> 02:01:26,560
log the error now let's take a look at
2932
02:01:26,560 --> 02:01:29,239
what this function looks like in go we
2933
02:01:29,239 --> 02:01:32,719
do something like this we do user air
2934
02:01:32,719 --> 02:01:36,239
colon equals get
2935
02:01:38,199 --> 02:01:42,320
user if Air does not equal
2936
02:01:42,320 --> 02:01:45,599
nil then we could print out the error
2937
02:01:45,599 --> 02:01:48,719
and return so that we don't continue and
2938
02:01:48,719 --> 02:01:51,199
then down here we could you know deal
2939
02:01:51,199 --> 02:01:55,719
with the user object so uh use user here
2940
02:01:55,719 --> 02:01:57,800
and for consistency sake we could say
2941
02:01:57,800 --> 02:02:00,679
use user here um after the user object
2942
02:02:00,679 --> 02:02:03,119
is created in JavaScript okay so what's
2943
02:02:03,119 --> 02:02:04,760
the difference well let's talk about the
2944
02:02:04,760 --> 02:02:07,159
first reason why I prefer goes error
2945
02:02:07,159 --> 02:02:09,960
handling to javascript's error handling
2946
02:02:09,960 --> 02:02:11,920
let's pretend we need to go get some
2947
02:02:11,920 --> 02:02:15,119
data for the user after we've already
2948
02:02:15,119 --> 02:02:17,199
kind of retrieved the user successfully
2949
02:02:17,199 --> 02:02:18,400
so let's say we need to go get the
2950
02:02:18,400 --> 02:02:21,400
user's profile picture well in go all we
2951
02:02:21,400 --> 02:02:22,960
would do
2952
02:02:22,960 --> 02:02:24,920
is call the next dangerous function
2953
02:02:24,920 --> 02:02:28,880
let's say get user Pro profile and maybe
2954
02:02:28,880 --> 02:02:32,760
it takes a user. ID as input right so we
2955
02:02:32,760 --> 02:02:34,679
need to successfully wait for the user
2956
02:02:34,679 --> 02:02:37,159
to come back and then we can go fetch
2957
02:02:37,159 --> 02:02:39,040
its
2958
02:02:39,040 --> 02:02:41,599
profile right so this looks very similar
2959
02:02:41,599 --> 02:02:44,159
we doing another dangerous function get
2960
02:02:44,159 --> 02:02:46,880
user profile and it returns a profile
2961
02:02:46,880 --> 02:02:49,199
and an error if an error with the
2962
02:02:49,199 --> 02:02:51,400
profile occurs uh again we'll just kind
2963
02:02:51,400 --> 02:02:52,800
of print out the error and return
2964
02:02:52,800 --> 02:02:55,719
otherwise now we have a profile object
2965
02:02:55,719 --> 02:02:58,560
okay what would we do in JavaScript well
2966
02:02:58,560 --> 02:03:00,760
in JavaScript we can't just take this
2967
02:03:00,760 --> 02:03:04,239
Tri catch and paste it down here and
2968
02:03:04,239 --> 02:03:06,440
update some stuff this will not work if
2969
02:03:06,440 --> 02:03:08,960
we do get user profile
2970
02:03:08,960 --> 02:03:10,639
user.
2971
02:03:10,639 --> 02:03:13,639
ID
2972
02:03:13,639 --> 02:03:16,880
profile the problem with this code is
2973
02:03:16,880 --> 02:03:20,320
that user is only available within this
2974
02:03:20,320 --> 02:03:23,880
Tri Block it's scoped to the tri block
2975
02:03:23,880 --> 02:03:26,599
right so this user object here will be
2976
02:03:26,599 --> 02:03:28,880
undefined so the normal thing to do in
2977
02:03:28,880 --> 02:03:31,560
JavaScript would just be to take this
2978
02:03:31,560 --> 02:03:34,719
line here and inject it
2979
02:03:34,719 --> 02:03:38,199
within the tri block the original Tri
2980
02:03:38,199 --> 02:03:40,320
block right so now I'm doing my second
2981
02:03:40,320 --> 02:03:42,639
dangerous function after I do my first
2982
02:03:42,639 --> 02:03:44,960
dangerous function the reason I don't
2983
02:03:44,960 --> 02:03:48,119
like this is that the logic for handling
2984
02:03:48,119 --> 02:03:51,520
the errors is now all in one place if I
2985
02:03:51,520 --> 02:03:54,159
want want to handle the error for the
2986
02:03:54,159 --> 02:03:56,880
get user profile function differently or
2987
02:03:56,880 --> 02:03:59,239
separately um then I want to handle the
2988
02:03:59,239 --> 02:04:00,920
error from the get user function I have
2989
02:04:00,920 --> 02:04:03,760
to actually Nest the whole Tri
2990
02:04:03,760 --> 02:04:06,239
catch like
2991
02:04:06,239 --> 02:04:09,840
this right so now user. ID is accessible
2992
02:04:09,840 --> 02:04:12,119
because I'm in the same Tri block but I
2993
02:04:12,119 --> 02:04:14,480
get a second catch block so we kind of
2994
02:04:14,480 --> 02:04:17,199
get this nasty nesting if we want to
2995
02:04:17,199 --> 02:04:19,880
treat each individual error separately
2996
02:04:19,880 --> 02:04:21,960
and this kind of brings us to the second
2997
02:04:21,960 --> 02:04:24,480
reason why I prefer Go's error handling
2998
02:04:24,480 --> 02:04:26,880
and it's that it forces us to think
2999
02:04:26,880 --> 02:04:29,599
about each individual error that's
3000
02:04:29,599 --> 02:04:32,360
passed back from a dangerous function so
3001
02:04:32,360 --> 02:04:34,079
again in JavaScript kind of the normal
3002
02:04:34,079 --> 02:04:36,360
thing to do unless you really needed
3003
02:04:36,360 --> 02:04:38,159
separate error handling would be to just
3004
02:04:38,159 --> 02:04:39,840
kind of do all of your dangerous stuff
3005
02:04:39,840 --> 02:04:42,480
in one large Tri block the problem with
3006
02:04:42,480 --> 02:04:46,440
this in my opinion is that it kind of it
3007
02:04:46,440 --> 02:04:48,880
doesn't encourage me to remember which
3008
02:04:48,880 --> 02:04:50,960
of these functions is dangerous in the
3009
02:04:50,960 --> 02:04:52,920
first place for example maybe this is a
3010
02:04:52,920 --> 02:04:54,679
safe function and this is a dangerous
3011
02:04:54,679 --> 02:04:56,000
function that can potentially throw an
3012
02:04:56,000 --> 02:04:58,599
error but looking at this code from um
3013
02:04:58,599 --> 02:05:00,719
kind of a calling perspective I don't
3014
02:05:00,719 --> 02:05:02,599
really know that that's the case whereas
3015
02:05:02,599 --> 02:05:06,480
in go because a function returns kind of
3016
02:05:06,480 --> 02:05:09,599
the valid data and the error with every
3017
02:05:09,599 --> 02:05:12,360
function call I know for a fact that the
3018
02:05:12,360 --> 02:05:16,639
get user profile function can throw an
3019
02:05:16,639 --> 02:05:19,840
error because it returns an error value
3020
02:05:19,840 --> 02:05:21,400
this will probably make more sense if I
3021
02:05:21,400 --> 02:05:22,320
actually write out some of these
3022
02:05:22,320 --> 02:05:24,360
functions so in JavaScript the get user
3023
02:05:24,360 --> 02:05:26,000
function might look just like this
3024
02:05:26,000 --> 02:05:28,520
function get
3025
02:05:28,520 --> 02:05:33,000
user uh we could say uh do some get user
3026
02:05:33,000 --> 02:05:35,119
logic
3027
02:05:35,119 --> 02:05:38,559
here and then maybe it returns you know
3028
02:05:38,559 --> 02:05:39,719
a
3029
02:05:39,719 --> 02:05:42,320
user looking at the function
3030
02:05:42,320 --> 02:05:45,440
signature all I can tell in JavaScript
3031
02:05:45,440 --> 02:05:48,000
is that this function takes no arguments
3032
02:05:48,000 --> 02:05:49,239
and the only way for me to know what it
3033
02:05:49,239 --> 02:05:50,679
returns is to go find that return
3034
02:05:50,679 --> 02:05:53,599
statement see oh okay it returns a user
3035
02:05:53,599 --> 02:05:56,719
however in go I actually get two super
3036
02:05:56,719 --> 02:05:59,000
helpful things in the function signature
3037
02:05:59,000 --> 02:06:00,360
and remember the function signature is
3038
02:06:00,360 --> 02:06:02,639
just kind of that first line of a
3039
02:06:02,639 --> 02:06:04,440
function definition so in go if I were
3040
02:06:04,440 --> 02:06:06,440
to write the function definition for the
3041
02:06:06,440 --> 02:06:07,440
get user function would be something
3042
02:06:07,440 --> 02:06:08,280
like this
3043
02:06:08,280 --> 02:06:12,599
funk get user doesn't take any inputs
3044
02:06:12,599 --> 02:06:17,040
but it returns a let's say a user struct
3045
02:06:17,040 --> 02:06:20,559
and an error right and then we have some
3046
02:06:20,559 --> 02:06:23,599
kind of do get user logic
3047
02:06:23,599 --> 02:06:26,679
here right so now just by looking at
3048
02:06:26,679 --> 02:06:29,159
this function signature I can tell that
3049
02:06:29,159 --> 02:06:31,440
it returns a user and that it could
3050
02:06:31,440 --> 02:06:33,679
possibly return an error as well that I
3051
02:06:33,679 --> 02:06:35,679
need to go handle whereas again in
3052
02:06:35,679 --> 02:06:38,320
JavaScript not only do I not get to see
3053
02:06:38,320 --> 02:06:40,000
in the function signature what is
3054
02:06:40,000 --> 02:06:42,040
potentially returned but I also don't
3055
02:06:42,040 --> 02:06:44,280
know that this function can throw I have
3056
02:06:44,280 --> 02:06:46,840
to kind of go digging deeper into the
3057
02:06:46,840 --> 02:06:49,719
function definition to see if there's
3058
02:06:49,719 --> 02:06:52,239
potentially something uh dangerous going
3059
02:06:52,239 --> 02:06:54,480
on in the meat of the function so again
3060
02:06:54,480 --> 02:06:56,280
to reiterate because this is actually a
3061
02:06:56,280 --> 02:06:57,920
super important point when you're
3062
02:06:57,920 --> 02:06:59,920
learning about how errors are handled in
3063
02:06:59,920 --> 02:07:03,320
go the primary reason I like error
3064
02:07:03,320 --> 02:07:06,199
handling in go is that it forces me as I
3065
02:07:06,199 --> 02:07:09,599
write my code to be kind of hyper aware
3066
02:07:09,599 --> 02:07:12,920
of every potential error and make sure
3067
02:07:12,920 --> 02:07:15,719
that I write code that handles it so now
3068
02:07:15,719 --> 02:07:17,840
that we understand what error handling
3069
02:07:17,840 --> 02:07:19,400
in go kind of looks like from a high
3070
02:07:19,400 --> 02:07:22,239
level let's dive into the detail s
3071
02:07:22,239 --> 02:07:25,280
errors in go are just values and
3072
02:07:25,280 --> 02:07:27,599
specifically they're just interfaces so
3073
02:07:27,599 --> 02:07:30,000
the built-in error interface is an
3074
02:07:30,000 --> 02:07:32,599
interface with a single method the error
3075
02:07:32,599 --> 02:07:34,920
method and that method returns a string
3076
02:07:34,920 --> 02:07:37,639
describing what went wrong so how do we
3077
02:07:37,639 --> 02:07:39,239
actually go about handling errors in
3078
02:07:39,239 --> 02:07:41,280
code well let's take a look at this
3079
02:07:41,280 --> 02:07:42,960
function right here so this is a
3080
02:07:42,960 --> 02:07:44,599
function in the standard Library it's
3081
02:07:44,599 --> 02:07:47,000
called asky to integer it takes a string
3082
02:07:47,000 --> 02:07:48,599
and attempts to convert it into an
3083
02:07:48,599 --> 02:07:50,760
integer value and potentially that can
3084
02:07:50,760 --> 02:07:52,719
be problematic right because you can
3085
02:07:52,719 --> 02:07:55,360
write strings that aren't numbers under
3086
02:07:55,360 --> 02:07:57,559
the hood Okay cool so what do we do we
3087
02:07:57,559 --> 02:08:00,719
get back an integer and an error and in
3088
02:08:00,719 --> 02:08:03,320
essence it's it's it's really simple the
3089
02:08:03,320 --> 02:08:07,760
error is either nil or it's not nil if
3090
02:08:07,760 --> 02:08:10,079
it is nil that means everything went
3091
02:08:10,079 --> 02:08:12,480
fine and nothing went wrong so if the
3092
02:08:12,480 --> 02:08:15,679
error is nil it means there is no kind
3093
02:08:15,679 --> 02:08:18,079
of string representing what went wrong
3094
02:08:18,079 --> 02:08:20,480
because nothing went wrong however if
3095
02:08:20,480 --> 02:08:23,159
the error is not nil that means
3096
02:08:23,159 --> 02:08:25,880
something did go wrong right so if the
3097
02:08:25,880 --> 02:08:28,639
error is not nil in this case then we'll
3098
02:08:28,639 --> 02:08:31,079
print an error message and return from
3099
02:08:31,079 --> 02:08:33,480
the function right so we're basically
3100
02:08:33,480 --> 02:08:36,599
writing guard Clauses that say something
3101
02:08:36,599 --> 02:08:38,800
went wrong let's handle this error and
3102
02:08:38,800 --> 02:08:41,159
get out of here right enough talk let's
3103
02:08:41,159 --> 02:08:42,920
write some code so you can see what I
3104
02:08:42,920 --> 02:08:45,239
mean let me expand this so it's a little
3105
02:08:45,239 --> 02:08:47,440
easier to see the code okay the
3106
02:08:47,440 --> 02:08:49,239
assignment says we offer a product that
3107
02:08:49,239 --> 02:08:51,559
allows businesses that use texo to to
3108
02:08:51,559 --> 02:08:53,679
send pairs of messages to couples it's
3109
02:08:53,679 --> 02:08:55,119
mostly used by flower shops and movie
3110
02:08:55,119 --> 02:08:57,480
theaters okay great complete the send
3111
02:08:57,480 --> 02:08:59,119
SMS to couple function so that's this
3112
02:08:59,119 --> 02:09:00,719
function here it should send two
3113
02:09:00,719 --> 02:09:02,440
messages first to the customer and then
3114
02:09:02,440 --> 02:09:06,559
to the customer's spouse so use send SMS
3115
02:09:06,559 --> 02:09:08,800
to send the message to customer if an
3116
02:09:08,800 --> 02:09:11,320
error is encountered return 0.0 and the
3117
02:09:11,320 --> 02:09:13,520
error uh do the same for message to
3118
02:09:13,520 --> 02:09:15,159
spouse if both messages are sent
3119
02:09:15,159 --> 02:09:16,800
successfully return the total cost of
3120
02:09:16,800 --> 02:09:19,920
the messages added together okay I think
3121
02:09:19,920 --> 02:09:21,559
I understand what's going on so we're
3122
02:09:21,559 --> 02:09:22,880
basically going to send both of these
3123
02:09:22,880 --> 02:09:25,320
messages one after the other um if any
3124
02:09:25,320 --> 02:09:28,159
errors happen we kind of abort early and
3125
02:09:28,159 --> 02:09:29,800
return the
3126
02:09:29,800 --> 02:09:34,679
error okay so uh send SMS takes a
3127
02:09:34,679 --> 02:09:39,280
message as input so first we'll say uh
3128
02:09:39,280 --> 02:09:42,679
send SMS and we'll send the message to
3129
02:09:42,679 --> 02:09:44,639
the
3130
02:09:44,639 --> 02:09:48,239
customer and send SMS returns a float 64
3131
02:09:48,239 --> 02:09:50,920
and error so we'll say um I think it's
3132
02:09:50,920 --> 02:09:53,320
the cost
3133
02:09:53,599 --> 02:09:55,840
return the total cost okay yeah so cost
3134
02:09:55,840 --> 02:09:59,239
error send SMS all right if error does
3135
02:09:59,239 --> 02:10:01,159
not equal nil so if there was a problem
3136
02:10:01,159 --> 02:10:02,719
sending the
3137
02:10:02,719 --> 02:10:05,760
SMS uh return 0.0 and the error so
3138
02:10:05,760 --> 02:10:07,960
return
3139
02:10:12,639 --> 02:10:15,559
0.0 right because this function send SMS
3140
02:10:15,559 --> 02:10:18,360
to couple Returns the total cost and an
3141
02:10:18,360 --> 02:10:20,079
error so we're saying if we failed to
3142
02:10:20,079 --> 02:10:23,440
send the SMS then it costs nothing and
3143
02:10:23,440 --> 02:10:25,599
we'll return the error that describes
3144
02:10:25,599 --> 02:10:26,559
what went
3145
02:10:26,559 --> 02:10:28,599
wrong otherwise we'll do it for the
3146
02:10:28,599 --> 02:10:30,440
message to spouse so we kind of are just
3147
02:10:30,440 --> 02:10:32,480
going to do this exact same thing so I'm
3148
02:10:32,480 --> 02:10:38,119
going to say cost for uh for let's say
3149
02:10:38,400 --> 02:10:41,119
customer cost for
3150
02:10:41,119 --> 02:10:43,119
spouse and we'll be sending the message
3151
02:10:43,119 --> 02:10:44,880
to the
3152
02:10:44,880 --> 02:10:46,559
spouse
3153
02:10:46,559 --> 02:10:48,719
cool all right now if we get to the
3154
02:10:48,719 --> 02:10:49,960
bottom of the function that means
3155
02:10:49,960 --> 02:10:52,960
nothing went wrong so we can
3156
02:10:52,960 --> 02:10:54,960
return cost for
3157
02:10:54,960 --> 02:10:59,000
customer Plus cost for
3158
02:10:59,000 --> 02:11:03,079
spouse and nil right because if we get
3159
02:11:03,079 --> 02:11:04,559
down here nothing went wrong so we don't
3160
02:11:04,559 --> 02:11:06,679
have an error to return okay let's go
3161
02:11:06,679 --> 02:11:10,040
ahead and run this code and see what we
3162
02:11:10,040 --> 02:11:12,320
get and I want to just scroll down and
3163
02:11:12,320 --> 02:11:13,960
take a look at some of these test
3164
02:11:13,960 --> 02:11:16,280
cases okay message for customer thanks
3165
02:11:16,280 --> 02:11:17,679
for coming into our flower shop message
3166
02:11:17,679 --> 02:11:19,320
for spouse we hope you enjoyed your gift
3167
02:11:19,320 --> 02:11:22,000
error can't send texts over 25
3168
02:11:22,000 --> 02:11:24,199
characters Okay cool so I mean if we
3169
02:11:24,199 --> 02:11:26,760
look at the send SMS uh function it
3170
02:11:26,760 --> 02:11:28,880
actually throws an error or I shouldn't
3171
02:11:28,880 --> 02:11:31,040
say throws because we don't throw in go
3172
02:11:31,040 --> 02:11:33,559
right but returns an error value that
3173
02:11:33,559 --> 02:11:35,960
says can't send texts over blank
3174
02:11:35,960 --> 02:11:39,320
characters so that looks correct to me
3175
02:11:39,320 --> 02:11:41,040
um here we've got message to customer
3176
02:11:41,040 --> 02:11:43,320
message to spouse total
3177
02:11:43,320 --> 02:11:45,679
cost okay this is looking pretty good to
3178
02:11:45,679 --> 02:11:47,280
me I'm going to go ahead and submit that
3179
02:11:47,280 --> 02:11:49,320
we talked about how error handling in go
3180
02:11:49,320 --> 02:11:51,480
is all built around the error interface
3181
02:11:51,480 --> 02:11:53,040
in fact let's just review that really
3182
02:11:53,040 --> 02:11:55,559
quickly uh this error interface is
3183
02:11:55,559 --> 02:11:56,920
really just an interface that wraps a
3184
02:11:56,920 --> 02:11:58,800
method returning a string because if you
3185
02:11:58,800 --> 02:12:00,760
think about it at the end of the day an
3186
02:12:00,760 --> 02:12:04,400
error is just a kind of nullable string
3187
02:12:04,400 --> 02:12:06,360
either it's a string representing what
3188
02:12:06,360 --> 02:12:08,679
went wrong or saying what went wrong or
3189
02:12:08,679 --> 02:12:11,199
it's nothing because nothing went wrong
3190
02:12:11,199 --> 02:12:14,679
so being good at handling errors in go
3191
02:12:14,679 --> 02:12:16,679
has a lot to do with being good at
3192
02:12:16,679 --> 02:12:19,320
formatting strings or formatting useful
3193
02:12:19,320 --> 02:12:21,679
error messages so let's review how we
3194
02:12:21,679 --> 02:12:24,280
format strings in go most formatting go
3195
02:12:24,280 --> 02:12:26,639
is built around kind of these formatting
3196
02:12:26,639 --> 02:12:28,920
verbs that are defined in the format
3197
02:12:28,920 --> 02:12:31,079
package the fmt package of the standard
3198
02:12:31,079 --> 02:12:33,840
Library so for example the S printf
3199
02:12:33,840 --> 02:12:35,880
function returns a string where it
3200
02:12:35,880 --> 02:12:38,679
interpolates the values passed into the
3201
02:12:38,679 --> 02:12:41,199
function after the formatting string
3202
02:12:41,199 --> 02:12:43,880
into the formatting string uh string
3203
02:12:43,880 --> 02:12:45,679
where where the verbs exist so for
3204
02:12:45,679 --> 02:12:48,079
example this first percent V is replaced
3205
02:12:48,079 --> 02:12:50,480
with name the second percent V is
3206
02:12:50,480 --> 02:12:53,840
replaced with age percent V is the verb
3207
02:12:53,840 --> 02:12:56,360
we use for sort of the default format
3208
02:12:56,360 --> 02:12:58,280
right if you format an integer using
3209
02:12:58,280 --> 02:13:00,679
percent V then it kind of just prints
3210
02:13:00,679 --> 02:13:03,199
the integer in string form um but there
3211
02:13:03,199 --> 02:13:04,760
are other ways that we can format stuff
3212
02:13:04,760 --> 02:13:07,679
for example the percent F verb is used
3213
02:13:07,679 --> 02:13:10,320
to format floats and you can actually
3214
02:13:10,320 --> 02:13:13,320
specify how many decimal places you want
3215
02:13:13,320 --> 02:13:16,000
to show up in your output string by kind
3216
02:13:16,000 --> 02:13:19,320
of prefixing the F portion with a point
3217
02:13:19,320 --> 02:13:23,159
2 for two decimal places or say A.1 for
3218
02:13:23,159 --> 02:13:25,520
a single decimal place so let's jump
3219
02:13:25,520 --> 02:13:27,440
right into the coding assignment
3220
02:13:27,440 --> 02:13:29,360
assignment says we need better error
3221
02:13:29,360 --> 02:13:30,880
logs for our backend developers to help
3222
02:13:30,880 --> 02:13:33,040
them debug their code complete the get
3223
02:13:33,040 --> 02:13:35,040
SMS error string function so that's this
3224
02:13:35,040 --> 02:13:36,639
one right here um it should return a
3225
02:13:36,639 --> 02:13:38,840
string with this format Okay cool so I'm
3226
02:13:38,840 --> 02:13:41,000
just going to jump right ahead so it
3227
02:13:41,000 --> 02:13:43,360
should
3228
02:13:44,239 --> 02:13:45,880
return
3229
02:13:45,880 --> 02:13:48,800
turn fmts printf right because we're
3230
02:13:48,800 --> 02:13:52,199
trying to format a string uh this format
3231
02:13:52,199 --> 02:13:55,480
let me expand that a little
3232
02:13:56,360 --> 02:13:58,559
bit okay so return a string with that
3233
02:13:58,559 --> 02:14:00,719
format uh cost is the cost of the SMS so
3234
02:14:00,719 --> 02:14:03,719
I'm going to replace cost here with the
3235
02:14:03,719 --> 02:14:06,079
cost formatted to two decimal places so
3236
02:14:06,079 --> 02:14:09,679
percent Point 2 F right for two decimal
3237
02:14:09,679 --> 02:14:12,920
places and replace recipient with the
3238
02:14:12,920 --> 02:14:14,199
stringified representation of the
3239
02:14:14,199 --> 02:14:15,559
recipient's phone number which is the
3240
02:14:15,559 --> 02:14:16,559
string
3241
02:14:16,559 --> 02:14:19,880
here so percent v um it's important to
3242
02:14:19,880 --> 02:14:21,559
point out I could also use S here to
3243
02:14:21,559 --> 02:14:24,000
format a string but V and S do the same
3244
02:14:24,000 --> 02:14:25,960
thing effectively um when you're working
3245
02:14:25,960 --> 02:14:28,079
with
3246
02:14:28,520 --> 02:14:31,040
strings
3247
02:14:31,040 --> 02:14:33,960
and then we need to pass in as
3248
02:14:33,960 --> 02:14:35,960
parameters the values that we want to
3249
02:14:35,960 --> 02:14:37,559
format or that we want to interpolate
3250
02:14:37,559 --> 02:14:39,679
into the string so it's going to be cost
3251
02:14:39,679 --> 02:14:41,679
and
3252
02:14:41,679 --> 02:14:44,040
recipient going to Dent that because
3253
02:14:44,040 --> 02:14:47,199
that is some crazy
3254
02:14:48,480 --> 02:14:51,599
formatting okay that looks better all
3255
02:14:51,599 --> 02:14:54,199
right SMS that costs per point2 F to be
3256
02:14:54,199 --> 02:14:56,719
sent to percent V this looks good to me
3257
02:14:56,719 --> 02:14:57,639
all right I'm going to go ahead and run
3258
02:14:57,639 --> 02:14:59,199
that and see what we
3259
02:14:59,199 --> 02:15:02,960
get ah right can't forget to import the
3260
02:15:02,960 --> 02:15:06,960
formatting package let's run
3261
02:15:06,960 --> 02:15:11,040
that okay SMS that costs 1.40 to be sent
3262
02:15:11,040 --> 02:15:14,079
to the string cannot be
3263
02:15:14,079 --> 02:15:17,119
sent awesome this looks correct to me
3264
02:15:17,119 --> 02:15:19,199
I'm going to go ahead and submit that
3265
02:15:19,199 --> 02:15:21,280
let's talk about building our own cust
3266
02:15:21,280 --> 02:15:24,599
error types so remember the error
3267
02:15:24,599 --> 02:15:26,800
interface is an interface in fact let me
3268
02:15:26,800 --> 02:15:28,639
jump back and show you what it looks
3269
02:15:28,639 --> 02:15:31,320
like again so it's just this interface
3270
02:15:31,320 --> 02:15:33,440
here and because it's an interface that
3271
02:15:33,440 --> 02:15:36,079
means we can build our own types like
3272
02:15:36,079 --> 02:15:38,239
this user error struct here that
3273
02:15:38,239 --> 02:15:40,880
Implement that interface which means
3274
02:15:40,880 --> 02:15:43,920
they can be used as errors and remember
3275
02:15:43,920 --> 02:15:45,920
that the error interface just has one
3276
02:15:45,920 --> 02:15:48,239
single method that we need to Define
3277
02:15:48,239 --> 02:15:50,079
right the error method that returns a
3278
02:15:50,079 --> 02:15:53,280
string and as long as we have that then
3279
02:15:53,280 --> 02:15:56,719
our type can be used as an error so for
3280
02:15:56,719 --> 02:15:58,320
example we could create this user error
3281
02:15:58,320 --> 02:16:01,599
type that stores a name and then we can
3282
02:16:01,599 --> 02:16:04,679
use it as an error to format an error
3283
02:16:04,679 --> 02:16:07,520
message that contains the name of the
3284
02:16:07,520 --> 02:16:10,599
user's account who had an error so for
3285
02:16:10,599 --> 02:16:12,360
example in this snippet here we have a
3286
02:16:12,360 --> 02:16:15,559
send SMS function and if we're not able
3287
02:16:15,559 --> 02:16:17,679
to send a message to a user we can
3288
02:16:17,679 --> 02:16:19,599
actually just return that user error
3289
02:16:19,599 --> 02:16:22,559
struct with the user's name and again
3290
02:16:22,559 --> 02:16:25,360
that is an error we can return that
3291
02:16:25,360 --> 02:16:27,880
struct as an error type because it
3292
02:16:27,880 --> 02:16:30,320
implements the error interface the
3293
02:16:30,320 --> 02:16:31,760
caller of this function would then just
3294
02:16:31,760 --> 02:16:34,559
treat it like any other error the reason
3295
02:16:34,559 --> 02:16:36,880
this is useful is that we can store
3296
02:16:36,880 --> 02:16:39,760
structur data within our errors so if we
3297
02:16:39,760 --> 02:16:42,040
want to format them a specific way we
3298
02:16:42,040 --> 02:16:45,000
have access to sort of dynamic data like
3299
02:16:45,000 --> 02:16:47,519
a name let's write some code that uses
3300
02:16:47,519 --> 02:16:49,599
this concept so the assignment says our
3301
02:16:49,599 --> 02:16:50,920
users are frequently trying to run
3302
02:16:50,920 --> 02:16:52,840
custom analytics queries on their
3303
02:16:52,840 --> 02:16:54,960
message deliverability metrics right so
3304
02:16:54,960 --> 02:16:56,319
we're sending lots of messages we want
3305
02:16:56,319 --> 02:16:58,319
to know are these messages getting
3306
02:16:58,319 --> 02:17:00,479
delivered they end up writing a bad
3307
02:17:00,479 --> 02:17:02,080
query that tries to divide a number by
3308
02:17:02,080 --> 02:17:03,679
zero it's become such a problem that we
3309
02:17:03,679 --> 02:17:04,719
think it would be best to make a
3310
02:17:04,719 --> 02:17:06,920
specific type of error um for dividing
3311
02:17:06,920 --> 02:17:09,280
by zero update the code so that the
3312
02:17:09,280 --> 02:17:12,280
Divide error type so that's this error
3313
02:17:12,280 --> 02:17:15,679
type here or rather this struct here
3314
02:17:15,679 --> 02:17:18,040
implements the error interface its error
3315
02:17:18,040 --> 02:17:19,719
method should return a string formatted
3316
02:17:19,719 --> 02:17:21,880
in the following way cannot divide
3317
02:17:21,880 --> 02:17:24,840
dividend by zero okay let's write that
3318
02:17:24,840 --> 02:17:29,479
method so it's going to be a function on
3319
02:17:29,479 --> 02:17:31,719
the Divide error type so I'm going to
3320
02:17:31,719 --> 02:17:34,479
name it de which is
3321
02:17:34,479 --> 02:17:38,200
a a divide error and the name of the
3322
02:17:38,200 --> 02:17:40,160
function must be error takes no
3323
02:17:40,160 --> 02:17:42,639
arguments and returns a string right so
3324
02:17:42,639 --> 02:17:44,479
that's that's the function signature we
3325
02:17:44,479 --> 02:17:47,479
need to use um to implement the error
3326
02:17:47,479 --> 02:17:49,920
interface and then we're going to return
3327
02:17:49,920 --> 02:17:51,960
a string and we're going to need to
3328
02:17:51,960 --> 02:17:54,080
format the string so we'll use S
3329
02:17:54,080 --> 02:17:58,200
printf uh the format package is already
3330
02:17:58,200 --> 02:18:03,120
imported and this is our template and
3331
02:18:03,120 --> 02:18:06,559
dividend in this case is a float
3332
02:18:06,559 --> 02:18:08,080
64
3333
02:18:08,080 --> 02:18:10,920
and uh you it says here dividend is the
3334
02:18:10,920 --> 02:18:12,679
actual dividend use the percent V verb
3335
02:18:12,679 --> 02:18:14,960
so percent V okay so we're just going to
3336
02:18:14,960 --> 02:18:16,479
kind of do the default formatting for a
3337
02:18:16,479 --> 02:18:17,840
float
3338
02:18:17,840 --> 02:18:21,319
64 and
3339
02:18:21,319 --> 02:18:24,080
let me indent all this so that it's kind
3340
02:18:24,080 --> 02:18:25,639
of
3341
02:18:25,639 --> 02:18:28,120
readable where dividend is the actual
3342
02:18:28,120 --> 02:18:29,559
dividend of the divider okay so we'll do
3343
02:18:29,559 --> 02:18:32,599
de do
3344
02:18:32,599 --> 02:18:36,639
Dividend that will interpolate there
3345
02:18:36,639 --> 02:18:38,719
okay that looks correct to me I think
3346
02:18:38,719 --> 02:18:40,080
we've implemented the error interface
3347
02:18:40,080 --> 02:18:41,719
properly let's go ahead and run
3348
02:18:41,719 --> 02:18:45,319
that uh oh I forgot my
3349
02:18:45,319 --> 02:18:47,719
comma um this is kind of an interesting
3350
02:18:47,719 --> 02:18:50,200
Quirk of the go programming language um
3351
02:18:50,200 --> 02:18:53,280
if you to add a new line after the last
3352
02:18:53,280 --> 02:18:55,439
parameter to a function you have to put
3353
02:18:55,439 --> 02:18:59,000
a comma so this would
3354
02:18:59,000 --> 02:19:01,439
work all right
3355
02:19:01,439 --> 02:19:05,080
and this would
3356
02:19:05,080 --> 02:19:07,639
work but this does not work right that's
3357
02:19:07,639 --> 02:19:08,960
what I did the first time so just kind
3358
02:19:08,960 --> 02:19:11,319
of something to watch out
3359
02:19:11,319 --> 02:19:13,840
for okay so let's take a look at this um
3360
02:19:13,840 --> 02:19:16,599
dividing 10 by 0 cannot divide 10 by 0
3361
02:19:16,599 --> 02:19:19,319
dividing 10 by 2 quotient 5 dividing 15
3362
02:19:19,319 --> 02:19:22,599
by 30 5 question okay this is looking
3363
02:19:22,599 --> 02:19:24,880
like it formatted properly let's submit
3364
02:19:24,880 --> 02:19:26,559
that so we've got a quiz question it
3365
02:19:26,559 --> 02:19:28,519
says what is the underlying type of an
3366
02:19:28,519 --> 02:19:31,240
error is it an interface is it a struct
3367
02:19:31,240 --> 02:19:35,280
is it a string well it could technically
3368
02:19:35,280 --> 02:19:37,240
be a struct or a string right like we
3369
02:19:37,240 --> 02:19:40,319
saw in the last uh the last assignment
3370
02:19:40,319 --> 02:19:42,679
but the most correct thing would be to
3371
02:19:42,679 --> 02:19:43,760
say an
3372
02:19:43,760 --> 02:19:46,840
interface because it must always be an
3373
02:19:46,840 --> 02:19:48,640
interface right it must always implement
3374
02:19:48,640 --> 02:19:50,800
the error interface it could also be a
3375
02:19:50,800 --> 02:19:53,240
struct or a string um but it will always
3376
02:19:53,240 --> 02:19:55,280
be an interface next question is can a
3377
02:19:55,280 --> 02:19:57,520
Type be an error and also fulfill
3378
02:19:57,520 --> 02:20:00,160
another interface well errors are just
3379
02:20:00,160 --> 02:20:01,840
interfaces and we know that types can
3380
02:20:01,840 --> 02:20:03,600
fulfill any number of interfaces as long
3381
02:20:03,600 --> 02:20:05,920
as they have all of the required methods
3382
02:20:05,920 --> 02:20:08,600
so yeah there's no problem with this
3383
02:20:08,600 --> 02:20:11,479
let's talk about the errors package so
3384
02:20:11,479 --> 02:20:13,080
the standard library and go has an
3385
02:20:13,080 --> 02:20:16,479
errors package that exposes a few useful
3386
02:20:16,479 --> 02:20:17,880
functionalities but the one we're most
3387
02:20:17,880 --> 02:20:20,319
interested in right now is the errors.
3388
02:20:20,319 --> 02:20:22,600
new function so the useful thing about
3389
02:20:22,600 --> 02:20:24,880
the errors. new function is allows us to
3390
02:20:24,880 --> 02:20:27,680
create a new error from just a string so
3391
02:20:27,680 --> 02:20:29,479
we don't need to kind of you know Define
3392
02:20:29,479 --> 02:20:31,560
a new struct or a new type and then have
3393
02:20:31,560 --> 02:20:34,319
it explicitly implement the error
3394
02:20:34,319 --> 02:20:36,479
interface that can be a lot of code if
3395
02:20:36,479 --> 02:20:39,120
all we want to do is kind of return an
3396
02:20:39,120 --> 02:20:41,600
error with a very specific string let's
3397
02:20:41,600 --> 02:20:43,160
go ahead and use it the assignment says
3398
02:20:43,160 --> 02:20:45,120
twilio software Architects may have over
3399
02:20:45,120 --> 02:20:46,319
complicated the requirements from the
3400
02:20:46,319 --> 02:20:48,600
last coding assignment yeah all we
3401
02:20:48,600 --> 02:20:50,160
needed was a new generic error message
3402
02:20:50,160 --> 02:20:52,280
that returns a string no dividing by
3403
02:20:52,280 --> 02:20:54,080
zero when a user attempts to get us to
3404
02:20:54,080 --> 02:20:56,120
perform the taboo right the taboo of
3405
02:20:56,120 --> 02:20:58,399
dividing something by zero complete the
3406
02:20:58,399 --> 02:21:00,560
divide function use the errors. new
3407
02:21:00,560 --> 02:21:02,479
function to create an error when y
3408
02:21:02,479 --> 02:21:04,840
equals z that reads no dividing by zero
3409
02:21:04,840 --> 02:21:06,880
okay so this is pretty straightforward
3410
02:21:06,880 --> 02:21:09,720
basically if Y is zero which means that
3411
02:21:09,720 --> 02:21:12,200
the the number that we divide by would
3412
02:21:12,200 --> 02:21:13,720
be zero which is obviously a huge
3413
02:21:13,720 --> 02:21:15,040
problem in mathematics you're not
3414
02:21:15,040 --> 02:21:16,920
allowed to do that in go or most
3415
02:21:16,920 --> 02:21:19,000
programming languages that I'm aware of
3416
02:21:19,000 --> 02:21:21,560
um so we need to return an error here uh
3417
02:21:21,560 --> 02:21:23,800
so that this operation never happens so
3418
02:21:23,800 --> 02:21:26,920
we'll return errors. new looks like the
3419
02:21:26,920 --> 02:21:29,720
errors package is already imported for
3420
02:21:29,720 --> 02:21:33,040
us and we just need to return an
3421
02:21:33,040 --> 02:21:37,520
error that says no dividing by
3422
02:21:37,520 --> 02:21:39,560
zero okay let's go ahead and run that
3423
02:21:39,560 --> 02:21:40,760
and see what we
3424
02:21:40,760 --> 02:21:44,439
get oh I screwed up this function
3425
02:21:44,439 --> 02:21:47,720
returns a float 64 and an error so we
3426
02:21:47,720 --> 02:21:50,280
should return a zero value for that
3427
02:21:50,280 --> 02:21:52,160
first value when we're returning a
3428
02:21:52,160 --> 02:21:54,880
non-nil error let's go ahead and run
3429
02:21:54,880 --> 02:21:58,160
that cool dividing 10 by Z no dividing
3430
02:21:58,160 --> 02:22:00,280
by
3431
02:22:00,520 --> 02:22:03,319
Z all of this looks good to me let's
3432
02:22:03,319 --> 02:22:05,960
talk about loops in go so if you are
3433
02:22:05,960 --> 02:22:07,439
familiar with Loops in other languages
3434
02:22:07,439 --> 02:22:09,160
Loops in go syntactically are very
3435
02:22:09,160 --> 02:22:11,479
similar to say Loops in JavaScript uh
3436
02:22:11,479 --> 02:22:12,760
the main difference is just that we
3437
02:22:12,760 --> 02:22:16,080
don't use the parentheses around uh kind
3438
02:22:16,080 --> 02:22:19,560
of the the signature of the for Loop um
3439
02:22:19,560 --> 02:22:21,000
which again is very similar to how if
3440
02:22:21,000 --> 02:22:22,840
statements in go work we're basically
3441
02:22:22,840 --> 02:22:25,280
just dropping those uh parentheses
3442
02:22:25,280 --> 02:22:27,560
syntactically um the initial portion
3443
02:22:27,560 --> 02:22:29,359
runs at the beginning so for example in
3444
02:22:29,359 --> 02:22:31,120
this uh snippet of code where We're
3445
02:22:31,120 --> 02:22:34,640
looping over the integers 0 through 9 UM
3446
02:22:34,640 --> 02:22:36,120
in the initial section we're just
3447
02:22:36,120 --> 02:22:38,080
initializing a variable I and setting it
3448
02:22:38,080 --> 02:22:40,960
equal to zero um in the condition
3449
02:22:40,960 --> 02:22:42,840
section uh we're checking and making
3450
02:22:42,840 --> 02:22:44,920
sure that I is less than 10 so at the
3451
02:22:44,920 --> 02:22:47,680
end of every uh kind of iteration of the
3452
02:22:47,680 --> 02:22:49,319
body which in this case we're just
3453
02:22:49,319 --> 02:22:52,000
printing I in the body um we're going to
3454
02:22:52,000 --> 02:22:53,439
check and make sure that I is less than
3455
02:22:53,439 --> 02:22:55,720
10 if it is we'll continue on to the
3456
02:22:55,720 --> 02:22:57,040
next iteration of the loop otherwise
3457
02:22:57,040 --> 02:23:00,240
we'll be done um and then at the end of
3458
02:23:00,240 --> 02:23:01,920
every iteration we'll also be running
3459
02:23:01,920 --> 02:23:04,240
this after section so we'll be
3460
02:23:04,240 --> 02:23:07,000
incrementing I and that happens before
3461
02:23:07,000 --> 02:23:10,160
uh the condition is run so for example
3462
02:23:10,160 --> 02:23:13,800
if we increment I to 10 and then I is no
3463
02:23:13,800 --> 02:23:15,960
longer less than 10 we will not continue
3464
02:23:15,960 --> 02:23:17,640
on to the next iteration of loop which
3465
02:23:17,640 --> 02:23:20,160
is why this prints 0 through 9 and not 0
3466
02:23:20,160 --> 02:23:21,720
through 10 10 let's jump right into the
3467
02:23:21,720 --> 02:23:23,479
assignment says at texo we have a
3468
02:23:23,479 --> 02:23:25,200
dynamic formula for determining how much
3469
02:23:25,200 --> 02:23:28,160
a batch of bulk messages cost to send so
3470
02:23:28,160 --> 02:23:29,720
we need to complete the bulk send
3471
02:23:29,720 --> 02:23:31,279
function it takes a number of messages
3472
02:23:31,279 --> 02:23:33,960
as input and returns a float 64 um which
3473
02:23:33,960 --> 02:23:36,840
it looks like will be the total cost of
3474
02:23:36,840 --> 02:23:40,319
the batch of messages okay each message
3475
02:23:40,319 --> 02:23:43,359
costs 1.0 plus an additional fee the fee
3476
02:23:43,359 --> 02:23:45,040
structure is so it's going to be first
3477
02:23:45,040 --> 02:23:49,040
message is 1.0 plus 0 so 0 is the fee
3478
02:23:49,040 --> 02:23:51,200
second message is 1.0 Plus
3479
02:23:51,200 --> 02:23:54,880
01 third message is 1.0 plus 02 okay
3480
02:23:54,880 --> 02:23:56,640
cool and then our job is to use a loop
3481
02:23:56,640 --> 02:23:59,080
to calculate the total cost of all of
3482
02:23:59,080 --> 02:24:01,279
these messages for you know the number
3483
02:24:01,279 --> 02:24:03,960
of messages that we've been given okay
3484
02:24:03,960 --> 02:24:05,680
let's let's just start writing some code
3485
02:24:05,680 --> 02:24:07,960
so total cost I'm going to just start it
3486
02:24:07,960 --> 02:24:11,200
out at 0.0 and then we'll use a loop or
3487
02:24:11,200 --> 02:24:15,160
I equals 0 uh to do like num messages
3488
02:24:15,160 --> 02:24:17,479
iterations so you know a number of
3489
02:24:17,479 --> 02:24:20,080
iterations equal to num messages so um
3490
02:24:20,080 --> 02:24:22,479
start I at zero uh and then we'll do I
3491
02:24:22,479 --> 02:24:23,720
is less
3492
02:24:23,720 --> 02:24:26,720
than n
3493
02:24:26,720 --> 02:24:29,279
messages and I
3494
02:24:29,279 --> 02:24:32,560
Plus+ okay so this uh kind of body of
3495
02:24:32,560 --> 02:24:34,080
the for Loop should execute numb
3496
02:24:34,080 --> 02:24:36,920
messages times and we're going to want
3497
02:24:36,920 --> 02:24:39,920
to add the total cost so plus equals um
3498
02:24:39,920 --> 02:24:41,040
and we're going to use this formula so
3499
02:24:41,040 --> 02:24:43,399
it's going to be 1.0
3500
02:24:43,399 --> 02:24:45,840
plus this fee and how do we calculate
3501
02:24:45,840 --> 02:24:49,080
that fee well it looks to me like it is
3502
02:24:49,080 --> 02:24:51,279
0.01
3503
02:24:51,279 --> 02:24:55,560
times the basically the message number
3504
02:24:55,560 --> 02:24:58,479
right so for the first message at index0
3505
02:24:58,479 --> 02:25:00,840
I equals 0 um it's going to be a fee of
3506
02:25:00,840 --> 02:25:03,399
zero so if we just use I this should
3507
02:25:03,399 --> 02:25:04,760
work because if I is zero and we
3508
02:25:04,760 --> 02:25:07,439
multiply that by 01 anything multiplied
3509
02:25:07,439 --> 02:25:11,560
by 0 is 0 right so we'd get 1.0 + 0 for
3510
02:25:11,560 --> 02:25:13,359
the second message I should be one so
3511
02:25:13,359 --> 02:25:15,760
we'll get 1 plus 01 because anything
3512
02:25:15,760 --> 02:25:18,560
multiplied by one is itself um and so on
3513
02:25:18,560 --> 02:25:20,319
and so forth um that's looking correct
3514
02:25:20,319 --> 02:25:22,439
to me at the end of the function we'll
3515
02:25:22,439 --> 02:25:24,760
just return a total
3516
02:25:24,760 --> 02:25:29,800
cost cool let's run that oh untyped
3517
02:25:29,800 --> 02:25:31,800
float constant truncated to int okay so
3518
02:25:31,800 --> 02:25:34,800
I is an INT and we cannot multiply an
3519
02:25:34,800 --> 02:25:38,000
INT by a float 64 so I'm going to cast
3520
02:25:38,000 --> 02:25:41,680
um I to a float 64 let's try that
3521
02:25:41,680 --> 02:25:43,720
again and take a look at some of these
3522
02:25:43,720 --> 02:25:46,399
numbers Okay cool so the cost for 10
3523
02:25:46,399 --> 02:25:49,080
messages is
3524
02:25:49,080 --> 02:25:52,600
10.45 and and that sounds about right
3525
02:25:52,600 --> 02:25:54,760
right because each message costs
3526
02:25:54,760 --> 02:25:57,800
one plus this like fractional part that
3527
02:25:57,800 --> 02:25:59,880
grows over time so like the 10th message
3528
02:25:59,880 --> 02:26:03,080
would have cost like
3529
02:26:03,080 --> 02:26:06,880
0.10 and it would decrease over time so
3530
02:26:06,880 --> 02:26:10,720
that looks about right to
3531
02:26:12,000 --> 02:26:14,720
me 50
3532
02:26:14,720 --> 02:26:16,960
messages yep okay I'm going to go ahead
3533
02:26:16,960 --> 02:26:18,880
and submit that one interesting thing
3534
02:26:18,880 --> 02:26:21,319
about four Loops in go is that each
3535
02:26:21,319 --> 02:26:23,399
section of the for Loop the initial the
3536
02:26:23,399 --> 02:26:25,160
condition and the after are actually
3537
02:26:25,160 --> 02:26:27,479
optional and we can omit any of them so
3538
02:26:27,479 --> 02:26:30,000
for example if we omit the condition
3539
02:26:30,000 --> 02:26:32,279
then the for Loop will just run forever
3540
02:26:32,279 --> 02:26:34,240
so let's see why this might be useful um
3541
02:26:34,240 --> 02:26:35,920
let's jump into the assignment the
3542
02:26:35,920 --> 02:26:37,279
assignment says complete the max
3543
02:26:37,279 --> 02:26:39,160
messages function given a cost threshold
3544
02:26:39,160 --> 02:26:40,359
it should calculate the maximum number
3545
02:26:40,359 --> 02:26:42,000
of messages that can be sent um and then
3546
02:26:42,000 --> 02:26:44,160
it looks like the fees for each message
3547
02:26:44,160 --> 02:26:45,439
are going to be identical to the last
3548
02:26:45,439 --> 02:26:47,439
assignment so let's go ahead and just
3549
02:26:47,439 --> 02:26:49,760
get started um so max messages we have a
3550
02:26:49,760 --> 02:26:51,800
threshold a cost threshold right we want
3551
02:26:51,800 --> 02:26:54,960
to see how many messages we can send
3552
02:26:54,960 --> 02:26:56,520
while keeping the total cost under the
3553
02:26:56,520 --> 02:26:58,359
threshold so I'm going to create a total
3554
02:26:58,359 --> 02:27:01,680
cost variable and set it equal to
3555
02:27:01,680 --> 02:27:03,520
0.0 and then this is going to look
3556
02:27:03,520 --> 02:27:05,880
really similar to the last assignment um
3557
02:27:05,880 --> 02:27:08,120
but basically we'll set I equal to zero
3558
02:27:08,120 --> 02:27:09,439
to
3559
02:27:09,439 --> 02:27:13,200
start um I'll skip the condition for now
3560
02:27:13,200 --> 02:27:15,560
because we don't know to what number
3561
02:27:15,560 --> 02:27:17,800
we're kind of looping up to right we're
3562
02:27:17,800 --> 02:27:19,840
trying to calculate that so I don't know
3563
02:27:19,840 --> 02:27:23,359
where stop yet um but I do want to
3564
02:27:23,359 --> 02:27:25,840
increment I with every uh iteration of
3565
02:27:25,840 --> 02:27:26,520
the
3566
02:27:26,520 --> 02:27:29,080
loop and then I basically want to um
3567
02:27:29,080 --> 02:27:31,760
update the total cost by adding to it um
3568
02:27:31,760 --> 02:27:34,359
and use uh this formula over here right
3569
02:27:34,359 --> 02:27:36,640
so it's going to be
3570
02:27:36,640 --> 02:27:39,600
1.0 plus
3571
02:27:39,600 --> 02:27:41,279
0.01
3572
02:27:41,279 --> 02:27:46,399
time time I which I need to cast with
3573
02:27:46,399 --> 02:27:49,080
64 okay so that formula is looking again
3574
02:27:49,080 --> 02:27:50,680
identical last time
3575
02:27:50,680 --> 02:27:52,880
now if I want to
3576
02:27:52,880 --> 02:27:55,920
return the the maximum messages that I
3577
02:27:55,920 --> 02:27:57,800
can send while keeping the cost under
3578
02:27:57,800 --> 02:28:00,560
the threshold then basically I need to
3579
02:28:00,560 --> 02:28:04,160
check and say if the total cost is
3580
02:28:04,160 --> 02:28:06,279
greater than the
3581
02:28:06,279 --> 02:28:10,040
threshold then I should return
3582
02:28:10,040 --> 02:28:13,040
IES that sound right so for example
3583
02:28:13,040 --> 02:28:15,439
let's say that right off the bat the
3584
02:28:15,439 --> 02:28:17,680
threshold were I don't know is it
3585
02:28:17,680 --> 02:28:20,000
negative one right so I'm not allowed to
3586
02:28:20,000 --> 02:28:21,399
say send anything I would want to in
3587
02:28:21,399 --> 02:28:23,120
that case return zero right cuz I can't
3588
02:28:23,120 --> 02:28:25,240
send any messages so what would happen
3589
02:28:25,240 --> 02:28:27,319
we'd enter the loop I'd calculate the
3590
02:28:27,319 --> 02:28:29,000
total cost for the first message which
3591
02:28:29,000 --> 02:28:29,840
would be
3592
02:28:29,840 --> 02:28:32,800
1.0 and then because the total cost is
3593
02:28:32,800 --> 02:28:34,040
already higher than the threshold I
3594
02:28:34,040 --> 02:28:36,279
would return I which would be zero so
3595
02:28:36,279 --> 02:28:39,120
that works right however if the
3596
02:28:39,120 --> 02:28:40,240
threshold were a little higher let's say
3597
02:28:40,240 --> 02:28:42,920
the threshold were 1.5 uh then what
3598
02:28:42,920 --> 02:28:45,319
would happen is we do that comparison
3599
02:28:45,319 --> 02:28:49,640
the total cost would be less than the
3600
02:28:49,640 --> 02:28:50,640
threshold
3601
02:28:50,640 --> 02:28:52,240
so we'd continue to the next Loop uh
3602
02:28:52,240 --> 02:28:53,920
iteration of the loop where I would be
3603
02:28:53,920 --> 02:28:56,319
incremented to one and then on that next
3604
02:28:56,319 --> 02:28:57,880
iteration we'd go over okay so this is
3605
02:28:57,880 --> 02:28:59,720
looking good to me let me go ahead and
3606
02:28:59,720 --> 02:29:02,279
run this
3607
02:29:04,200 --> 02:29:08,560
code okay so with a threshold of 10 I
3608
02:29:08,560 --> 02:29:10,439
can send nine messages without going
3609
02:29:10,439 --> 02:29:11,960
over the
3610
02:29:11,960 --> 02:29:16,080
threshold that sounds right right
3611
02:29:16,080 --> 02:29:17,399
because I'd have like nine in some
3612
02:29:17,399 --> 02:29:18,439
fractional
3613
02:29:18,439 --> 02:29:21,640
part let's go ahead and mcy most
3614
02:29:21,640 --> 02:29:23,680
programming languages have support for a
3615
02:29:23,680 --> 02:29:26,720
while loop and really a while loop is
3616
02:29:26,720 --> 02:29:29,080
very similar to a four Loop except it
3617
02:29:29,080 --> 02:29:31,560
doesn't have that kind of initial and
3618
02:29:31,560 --> 02:29:34,800
after statement it it just runs until
3619
02:29:34,800 --> 02:29:38,160
some condition is no longer true now
3620
02:29:38,160 --> 02:29:40,120
because of this similarity the authors
3621
02:29:40,120 --> 02:29:41,880
of the go programming language decided
3622
02:29:41,880 --> 02:29:45,120
to not include an explicit while loop
3623
02:29:45,120 --> 02:29:48,120
with a while keyword instead the for
3624
02:29:48,120 --> 02:29:51,319
Loop is a while loop or just basically
3625
02:29:51,319 --> 02:29:54,560
both those side um kind of sections are
3626
02:29:54,560 --> 02:29:57,600
omitted and we just have a condition
3627
02:29:57,600 --> 02:29:59,560
that follows the four keyword so in
3628
02:29:59,560 --> 02:30:01,640
other words if we have a four keyword
3629
02:30:01,640 --> 02:30:03,920
and then a single expression then it is
3630
02:30:03,920 --> 02:30:07,240
a condition um that while true will
3631
02:30:07,240 --> 02:30:09,840
continue to kind of run the body of the
3632
02:30:09,840 --> 02:30:12,080
loop over and over and over again until
3633
02:30:12,080 --> 02:30:14,520
the condition stops being true let's
3634
02:30:14,520 --> 02:30:17,160
take a look at an example um here we
3635
02:30:17,160 --> 02:30:20,040
have a variable called plant height we
3636
02:30:20,040 --> 02:30:21,960
start it uh equal to one and we've done
3637
02:30:21,960 --> 02:30:24,279
this outside of the for Loop right and
3638
02:30:24,279 --> 02:30:25,840
then within the for Loop we just have
3639
02:30:25,840 --> 02:30:27,680
one section where we're comparing the
3640
02:30:27,680 --> 02:30:30,399
variable plant height to the number five
3641
02:30:30,399 --> 02:30:32,840
right and while it is less than five
3642
02:30:32,840 --> 02:30:34,479
we'll print this message and then at the
3643
02:30:34,479 --> 02:30:36,000
end of the loop we'll increment plant
3644
02:30:36,000 --> 02:30:38,160
height now you might notice this looks
3645
02:30:38,160 --> 02:30:39,279
just like a for Loop where we've
3646
02:30:39,279 --> 02:30:40,600
essentially taken the initial statement
3647
02:30:40,600 --> 02:30:42,439
and moved it up outside of the for Loop
3648
02:30:42,439 --> 02:30:44,319
body and we've taken the after statement
3649
02:30:44,319 --> 02:30:45,840
and moved it within the for Loop body
3650
02:30:45,840 --> 02:30:48,240
and that is what we've done right but
3651
02:30:48,240 --> 02:30:51,520
it's to demonstrate that this is valid
3652
02:30:51,520 --> 02:30:54,000
syntax let's jump right into the
3653
02:30:54,000 --> 02:30:56,279
assignment okay so the assignment says
3654
02:30:56,279 --> 02:30:57,240
we have an interesting new cost
3655
02:30:57,240 --> 02:31:00,120
structure for our SMS vendor so at texo
3656
02:31:00,120 --> 02:31:02,279
we have a vendor that we have to pay to
3657
02:31:02,279 --> 02:31:04,319
send text messages through right so
3658
02:31:04,319 --> 02:31:05,960
we're a software service that makes
3659
02:31:05,960 --> 02:31:07,960
sending text messages easy but we do
3660
02:31:07,960 --> 02:31:10,520
have to pay some kind of uh maybe
3661
02:31:10,520 --> 02:31:12,160
Hardware service that actually does the
3662
02:31:12,160 --> 02:31:15,040
sending of uh the text messages kind of
3663
02:31:15,040 --> 02:31:17,800
over the wireless network okay um they
3664
02:31:17,800 --> 02:31:19,319
charge exponentially more money for each
3665
02:31:19,319 --> 02:31:21,560
consecutive test text we send let's
3666
02:31:21,560 --> 02:31:22,720
write a function that can calculate how
3667
02:31:22,720 --> 02:31:24,200
many messages we can send in a given
3668
02:31:24,200 --> 02:31:26,200
batch uh given a cost multiplier and a
3669
02:31:26,200 --> 02:31:28,960
Max cost in pennies okay so given a cost
3670
02:31:28,960 --> 02:31:31,479
multiplier and a maximum cost our
3671
02:31:31,479 --> 02:31:33,680
function will return basically the
3672
02:31:33,680 --> 02:31:35,160
number of messages that we're allowed to
3673
02:31:35,160 --> 02:31:39,399
send um that's under that that Max cost
3674
02:31:39,399 --> 02:31:40,960
so it says in a nutshell the first
3675
02:31:40,960 --> 02:31:43,319
message costs one penny Okay actual cost
3676
02:31:43,319 --> 02:31:45,080
and pennies starts at one and each
3677
02:31:45,080 --> 02:31:47,200
message after that first message uh
3678
02:31:47,200 --> 02:31:49,439
costs the same as the previous message
3679
02:31:49,439 --> 02:31:52,840
multip by the cost multiplier okay so
3680
02:31:52,840 --> 02:31:55,920
that's happening here um gets expensive
3681
02:31:55,920 --> 02:31:57,840
uh there is an infinite Loop in the code
3682
02:31:57,840 --> 02:32:00,200
okay so on line 10 here we have this
3683
02:32:00,200 --> 02:32:03,040
four with no body and then an open curly
3684
02:32:03,040 --> 02:32:05,319
bracket um let me show you what happens
3685
02:32:05,319 --> 02:32:07,640
when we run that our codee's going to
3686
02:32:07,640 --> 02:32:10,200
sit and run and execute the body of that
3687
02:32:10,200 --> 02:32:12,000
for Loop over and over and over and over
3688
02:32:12,000 --> 02:32:14,080
with no exit condition uh this is
3689
02:32:14,080 --> 02:32:16,279
obviously a problem we don't want uh an
3690
02:32:16,279 --> 02:32:20,080
infinite for Loop there so our job is to
3691
02:32:20,080 --> 02:32:22,640
exit before incrementing Max messages to
3692
02:32:22,640 --> 02:32:24,359
send if the cost of the next message
3693
02:32:24,359 --> 02:32:26,279
would go over the Max cost so all we
3694
02:32:26,279 --> 02:32:29,920
need to do is check and only execute
3695
02:32:29,920 --> 02:32:33,080
this Loop while the actual cost is less
3696
02:32:33,080 --> 02:32:36,920
than or equal to the Max cost in
3697
02:32:36,920 --> 02:32:38,880
pennies um and we're going to have to
3698
02:32:38,880 --> 02:32:40,840
cast looks like so this is a float this
3699
02:32:40,840 --> 02:32:42,960
is an inch so we're going to cast this
3700
02:32:42,960 --> 02:32:45,960
to
3701
02:32:46,880 --> 02:32:49,479
64 now this should work because Max
3702
02:32:49,479 --> 02:32:51,960
message to send starts at
3703
02:32:51,960 --> 02:32:57,399
zero so assuming the actual cost is less
3704
02:32:57,399 --> 02:32:59,560
than the Max cost then we go ahead and
3705
02:32:59,560 --> 02:33:01,479
increment say we can send one more
3706
02:33:01,479 --> 02:33:03,600
message and then we take a look at the
3707
02:33:03,600 --> 02:33:08,160
next cost and if the next cost is still
3708
02:33:08,160 --> 02:33:10,439
less then we'll essentially get to add
3709
02:33:10,439 --> 02:33:12,080
another message so we'll keep kind of
3710
02:33:12,080 --> 02:33:14,880
looking ahead and calculating the next
3711
02:33:14,880 --> 02:33:17,720
cost right and as soon as the next cost
3712
02:33:17,720 --> 02:33:20,399
goes too high we stop okay so I'm going
3713
02:33:20,399 --> 02:33:23,000
to go ahead and run
3714
02:33:23,240 --> 02:33:28,080
that cool so with a multiplier of
3715
02:33:28,479 --> 02:33:31,840
1.1 and a Max cost of five we can send
3716
02:33:31,840 --> 02:33:34,319
17 messages that sounds about
3717
02:33:34,319 --> 02:33:38,840
right right the actual cost starts at
3718
02:33:39,160 --> 02:33:42,399
one the Max cost is five multiplier of
3719
02:33:42,399 --> 02:33:44,680
1.1 yeah that sounds right um so the
3720
02:33:44,680 --> 02:33:47,720
multiplier goes up Max cost goes up now
3721
02:33:47,720 --> 02:33:50,399
we can send nine messages that all looks
3722
02:33:50,399 --> 02:33:53,240
good to me let's talk about the modulo
3723
02:33:53,240 --> 02:33:55,200
operator how it works and go and kind of
3724
02:33:55,200 --> 02:33:58,920
how it works uh generally so the modulo
3725
02:33:58,920 --> 02:34:01,520
operator is a percent sign so it looks
3726
02:34:01,520 --> 02:34:05,080
like this right and the modulo operator
3727
02:34:05,080 --> 02:34:07,640
essentially calculates
3728
02:34:07,640 --> 02:34:10,279
remainders remainders so what do I mean
3729
02:34:10,279 --> 02:34:12,880
by that well let's jump into an example
3730
02:34:12,880 --> 02:34:16,720
uh let me switch colors so
3731
02:34:16,720 --> 02:34:21,680
four 4 / 3 in sort of a normal uh
3732
02:34:21,680 --> 02:34:26,319
floating Point division uh equals like
3733
02:34:26,319 --> 02:34:28,840
1.33333 forever right um we have this
3734
02:34:28,840 --> 02:34:31,800
fractional part however that's how math
3735
02:34:31,800 --> 02:34:33,359
Works normally and that's how math Works
3736
02:34:33,359 --> 02:34:35,279
in floating Point division in a language
3737
02:34:35,279 --> 02:34:38,040
like go if we're doing integer division
3738
02:34:38,040 --> 02:34:39,720
then we can't have a floating Point
3739
02:34:39,720 --> 02:34:43,160
result so the result of four divided 3
3740
02:34:43,160 --> 02:34:45,080
and integer division is actually just
3741
02:34:45,080 --> 02:34:48,160
one it's essentially the number of times
3742
02:34:48,160 --> 02:34:50,760
that three can be divided evenly into
3743
02:34:50,760 --> 02:34:54,040
four and then we chop off the remainder
3744
02:34:54,040 --> 02:34:57,760
the interesting thing about the modulo
3745
02:34:57,760 --> 02:35:02,520
operator is that 4 modulo 3 doesn't
3746
02:35:02,520 --> 02:35:03,840
return the number of times that three
3747
02:35:03,840 --> 02:35:06,640
can be divided evenly into four it
3748
02:35:06,640 --> 02:35:08,399
Returns the
3749
02:35:08,399 --> 02:35:11,080
remainder after that division so
3750
02:35:11,080 --> 02:35:13,160
actually in the case of Four modulo 3
3751
02:35:13,160 --> 02:35:15,479
the remainder is also one so it's the
3752
02:35:15,479 --> 02:35:21,640
same but for example five modulo 3
3753
02:35:21,640 --> 02:35:22,560
is
3754
02:35:22,560 --> 02:35:27,240
two and 6 modulo
3755
02:35:27,240 --> 02:35:30,920
3 is zero again because three divides
3756
02:35:30,920 --> 02:35:36,080
evenly into six right six integer
3757
02:35:36,080 --> 02:35:39,840
division by three is two right because
3758
02:35:39,840 --> 02:35:43,000
three goes evenly into six twice but the
3759
02:35:43,000 --> 02:35:45,960
remainder is zero that's why 6 mod 3 is
3760
02:35:45,960 --> 02:35:47,840
zero let's just do a couple more
3761
02:35:47,840 --> 02:35:50,120
examples feel free to pause the video um
3762
02:35:50,120 --> 02:35:52,880
in between when I give the question and
3763
02:35:52,880 --> 02:35:54,560
provide the solution um so that maybe
3764
02:35:54,560 --> 02:35:56,880
you can practice a little bit okay so
3765
02:35:56,880 --> 02:35:58,640
let's do
3766
02:35:58,640 --> 02:36:01,960
12 mod
3767
02:36:01,960 --> 02:36:04,560
4 we'll do in fact maybe I'll just write
3768
02:36:04,560 --> 02:36:07,560
out all the problems first let's do
3769
02:36:07,560 --> 02:36:10,000
16 mod
3770
02:36:10,000 --> 02:36:11,880
5 let's
3771
02:36:11,880 --> 02:36:14,359
do
3772
02:36:14,359 --> 02:36:17,840
22 mod
3773
02:36:18,120 --> 02:36:22,560
8 and let's let's do
3774
02:36:22,560 --> 02:36:24,479
27
3775
02:36:24,479 --> 02:36:26,080
mod
3776
02:36:26,080 --> 02:36:29,240
6 I think those will be those will be
3777
02:36:29,240 --> 02:36:31,680
good okay 12 mod four so does four
3778
02:36:31,680 --> 02:36:35,240
divide evenly is 12 uh yes 4 * 3 is 12
3779
02:36:35,240 --> 02:36:37,000
right so the remainder is
3780
02:36:37,000 --> 02:36:39,560
zero all right how many times does five
3781
02:36:39,560 --> 02:36:41,760
divide evenly into 16 the answer is
3782
02:36:41,760 --> 02:36:43,760
three right 5 10
3783
02:36:43,760 --> 02:36:47,000
15 and the remainder would then be one
3784
02:36:47,000 --> 02:36:51,080
how many times does 8 go into 22 8 16 24
3785
02:36:51,080 --> 02:36:53,160
so 24 doesn't work so it's going to be
3786
02:36:53,160 --> 02:36:57,600
16 and then 22 subtract 16 is 6 is the
3787
02:36:57,600 --> 02:37:01,200
remainder right and then 27 mod 6 um 6
3788
02:37:01,200 --> 02:37:05,040
goes into 27 four times 6 * 4 is 24 so a
3789
02:37:05,040 --> 02:37:07,800
remainder of three so an important thing
3790
02:37:07,800 --> 02:37:09,840
to note here is if you're trying to
3791
02:37:09,840 --> 02:37:12,200
figure out if a number divides evenly
3792
02:37:12,200 --> 02:37:14,200
into another number then you can just
3793
02:37:14,200 --> 02:37:20,680
check if say a mod b
3794
02:37:20,680 --> 02:37:26,319
equals 0 right if aod B equals z then
3795
02:37:26,319 --> 02:37:29,399
that means B divides into a an even
3796
02:37:29,399 --> 02:37:33,080
number of times so a is a multiple of B
3797
02:37:33,080 --> 02:37:35,800
so in go the module operator is just
3798
02:37:35,800 --> 02:37:39,120
that percent sign right so seven mod 3
3799
02:37:39,120 --> 02:37:41,319
um this expression is going to evaluate
3800
02:37:41,319 --> 02:37:43,479
to one we'll also need to know about the
3801
02:37:43,479 --> 02:37:45,600
logical and operator and the logical or
3802
02:37:45,600 --> 02:37:47,720
operator which are double Ampersand and
3803
02:37:47,720 --> 02:37:50,680
double bar uh respective The Logical and
3804
02:37:50,680 --> 02:37:53,399
operator operates on two Boolean values
3805
02:37:53,399 --> 02:37:57,080
and only returns true if both sides are
3806
02:37:57,080 --> 02:38:01,720
true right this and that the or Operator
3807
02:38:01,720 --> 02:38:05,359
just needs at least one side to be true
3808
02:38:05,359 --> 02:38:07,359
right in order for the entire expression
3809
02:38:07,359 --> 02:38:09,600
to evaluate to True let's jump into the
3810
02:38:09,600 --> 02:38:10,800
assignment it says we're hiring
3811
02:38:10,800 --> 02:38:12,439
engineers at texo so it's time to brush
3812
02:38:12,439 --> 02:38:14,319
up on the classic fizzbuzz game coding
3813
02:38:14,319 --> 02:38:15,439
exercises have been dramatically
3814
02:38:15,439 --> 02:38:17,240
overused in coding interviews around the
3815
02:38:17,240 --> 02:38:19,080
world complete the fizzbuzz function
3816
02:38:19,080 --> 02:38:20,600
that print the numbers 1 to 100
3817
02:38:20,600 --> 02:38:22,439
inclusive each on their own line but
3818
02:38:22,439 --> 02:38:23,800
substitutes multiples of three for the
3819
02:38:23,800 --> 02:38:25,840
text Fizz multiples of five for Buzz and
3820
02:38:25,840 --> 02:38:29,800
multiples of three and five for fizzbuzz
3821
02:38:29,800 --> 02:38:34,359
okay so we need a for Loop for I colon
3822
02:38:34,359 --> 02:38:38,000
equals 0 I is less than 100 actually
3823
02:38:38,000 --> 02:38:39,319
less than or equal to because it said
3824
02:38:39,319 --> 02:38:43,000
inclusive right
3825
02:38:43,520 --> 02:38:46,640
i++ okay um we need to think about the
3826
02:38:46,640 --> 02:38:49,279
order in which kind of these things can
3827
02:38:49,279 --> 02:38:51,000
happen happen so we're checking for
3828
02:38:51,000 --> 02:38:52,640
multiples of three multiples of five and
3829
02:38:52,640 --> 02:38:54,479
multiples of three and five so we
3830
02:38:54,479 --> 02:38:56,000
actually should check for multiples of
3831
02:38:56,000 --> 02:38:58,880
three and five first because something
3832
02:38:58,880 --> 02:39:01,760
could be that and one of the other two
3833
02:39:01,760 --> 02:39:02,920
conditions right it could be a multiple
3834
02:39:02,920 --> 02:39:05,760
of three and five and just a multiple of
3835
02:39:05,760 --> 02:39:07,840
three that makes sense maybe it'll make
3836
02:39:07,840 --> 02:39:13,680
sense when I type it out so if I
3837
02:39:14,080 --> 02:39:16,680
mod 3
3838
02:39:16,680 --> 02:39:20,880
Z and I mod
3839
02:39:20,880 --> 02:39:23,120
mod
3840
02:39:23,120 --> 02:39:26,960
three zero oops not three and three
3841
02:39:26,960 --> 02:39:30,800
three and five then we'll
3842
02:39:30,800 --> 02:39:33,359
print bizbuzz
3843
02:39:33,359 --> 02:39:35,960
right else
3844
02:39:35,960 --> 02:39:40,840
if I mod 3
3845
02:39:40,840 --> 02:39:43,800
0 then we'll just
3846
02:39:43,800 --> 02:39:46,800
print
3847
02:39:46,840 --> 02:39:52,160
is else if I imod five is zero we'll
3848
02:39:52,160 --> 02:39:53,680
just print
3849
02:39:53,680 --> 02:39:55,600
Buzz
3850
02:39:55,600 --> 02:39:59,000
otherwise we'll
3851
02:39:59,760 --> 02:40:01,520
print
3852
02:40:01,520 --> 02:40:03,760
I
3853
02:40:03,760 --> 02:40:06,160
right if they're both multiples Fizz
3854
02:40:06,160 --> 02:40:08,800
buzz if it's just three Fizz if it's
3855
02:40:08,800 --> 02:40:12,279
just five Buzz okay let's try
3856
02:40:12,279 --> 02:40:15,279
that oh cannot forget to import the
3857
02:40:15,279 --> 02:40:18,920
formatting package
3858
02:40:22,240 --> 02:40:24,479
okay let's
3859
02:40:24,479 --> 02:40:29,200
see fizzbuzz one two Fizz four Buzz five
3860
02:40:29,200 --> 02:40:34,680
Fizz seven eight fiz Buzz one oh ha one
3861
02:40:34,680 --> 02:40:36,080
through 100 that would have been close I
3862
02:40:36,080 --> 02:40:37,960
almost didn't follow instructions I was
3863
02:40:37,960 --> 02:40:39,800
like why do we have a Fizz Buzz up front
3864
02:40:39,800 --> 02:40:42,399
that doesn't uh that doesn't make sense
3865
02:40:42,399 --> 02:40:46,000
Okay cool so one two Fizz four Buzz
3866
02:40:46,000 --> 02:40:48,560
right five is a multiple of five 10 is a
3867
02:40:48,560 --> 02:40:50,399
multiple of five
3868
02:40:50,399 --> 02:40:52,920
15 is a multiple of 5 and three so this
3869
02:40:52,920 --> 02:40:55,680
is looking correct to me let me go ahead
3870
02:40:55,680 --> 02:40:57,600
and submit that so in the last
3871
02:40:57,600 --> 02:41:00,000
assignment we kind of uh did a if else
3872
02:41:00,000 --> 02:41:01,800
chain within our for Loop but there's
3873
02:41:01,800 --> 02:41:04,000
another way that we can write guard
3874
02:41:04,000 --> 02:41:06,640
Clauses within Loops um so that we don't
3875
02:41:06,640 --> 02:41:08,720
have to necessarily do that if else
3876
02:41:08,720 --> 02:41:11,279
chaining um if we don't want to uh the
3877
02:41:11,279 --> 02:41:13,120
continue keyword stops the current
3878
02:41:13,120 --> 02:41:14,600
eration of Loop and continues to the
3879
02:41:14,600 --> 02:41:16,399
next iteration so continue is a powerful
3880
02:41:16,399 --> 02:41:17,840
way to use guard classes right so we
3881
02:41:17,840 --> 02:41:20,520
write our for Loop and and then if some
3882
02:41:20,520 --> 02:41:23,040
condition happens um we can kind of bail
3883
02:41:23,040 --> 02:41:25,240
out of the body of the for Loop early
3884
02:41:25,240 --> 02:41:27,319
and just continue on to the next
3885
02:41:27,319 --> 02:41:30,000
iteration the break keyword is similar
3886
02:41:30,000 --> 02:41:32,319
in that it stops the current iteration
3887
02:41:32,319 --> 02:41:34,359
but instead of continuing on to the next
3888
02:41:34,359 --> 02:41:37,000
iteration it just ends the loop entirely
3889
02:41:37,000 --> 02:41:38,960
moving on to the assignment it says as
3890
02:41:38,960 --> 02:41:40,399
an Easter egg we decided to reward our
3891
02:41:40,399 --> 02:41:42,880
users with a free text message if they
3892
02:41:42,880 --> 02:41:45,240
send a prime number of text messages
3893
02:41:45,240 --> 02:41:47,880
this year because textio is is run by a
3894
02:41:47,880 --> 02:41:50,479
bunch of nerds complete the pr the print
3895
02:41:50,479 --> 02:41:52,080
primes function it should print all of
3896
02:41:52,080 --> 02:41:54,240
the prime numbers up to and including
3897
02:41:54,240 --> 02:41:57,399
Max Max it Should Skip any numbers that
3898
02:41:57,399 --> 02:41:59,680
are not prime okay so here's the pseudo
3899
02:41:59,680 --> 02:42:02,279
code print Prime Max so let's convert
3900
02:42:02,279 --> 02:42:07,319
this pseudo code into real go code so um
3901
02:42:07,319 --> 02:42:09,800
for n in range 2 to Max plus one so
3902
02:42:09,800 --> 02:42:13,359
we're going to do 4 n colonal
3903
02:42:13,359 --> 02:42:21,160
2 N is less than Max + 1
3904
02:42:24,040 --> 02:42:29,680
n++ okay if n is two if n is
3905
02:42:29,960 --> 02:42:33,800
two n is prime print it fmt do print
3906
02:42:33,800 --> 02:42:35,520
line
3907
02:42:35,520 --> 02:42:40,840
n and we need to continue right continue
3908
02:42:40,840 --> 02:42:42,640
to the next iteration basically saying
3909
02:42:42,640 --> 02:42:45,040
okay this n is prime we'll print it and
3910
02:42:45,040 --> 02:42:48,240
then we can move on all right if n is
3911
02:42:48,240 --> 02:42:50,640
even so so
3912
02:42:50,640 --> 02:42:55,439
if n mod 2 is zero right that's an easy
3913
02:42:55,439 --> 02:42:58,040
way to check if something is even um and
3914
02:42:58,040 --> 02:43:01,359
not make your way onto our programmer
3915
02:43:01,359 --> 02:43:04,960
humor if n mod 2 is
3916
02:43:04,960 --> 02:43:07,800
zero n is not prime skip to the next n
3917
02:43:07,800 --> 02:43:10,760
so uh we do not print and we just
3918
02:43:10,760 --> 02:43:12,720
skip
3919
02:43:12,720 --> 02:43:15,760
okay next we do a nested for Loop here
3920
02:43:15,760 --> 02:43:20,040
for I in range so for I CL
3921
02:43:20,040 --> 02:43:24,640
equal 3 to the S < TK of n + 1 okay this
3922
02:43:24,640 --> 02:43:27,080
is actually interesting I could use the
3923
02:43:27,080 --> 02:43:29,600
math. square root function here that
3924
02:43:29,600 --> 02:43:31,279
would be a valid way but if I want to
3925
02:43:31,279 --> 02:43:34,560
stay in integer land which I think I do
3926
02:43:34,560 --> 02:43:35,880
I can
3927
02:43:35,880 --> 02:43:37,680
do
3928
02:43:37,680 --> 02:43:45,439
um I can instead Square I so I * I I * I
3929
02:43:45,439 --> 02:43:47,720
and see if it's less than
3930
02:43:47,720 --> 02:43:50,200
n Plus
3931
02:43:50,200 --> 02:43:52,880
right does that make sense so instead of
3932
02:43:52,880 --> 02:43:55,600
doing I is less than the square root of
3933
02:43:55,600 --> 02:44:00,840
N I can do I SAR is less than
3934
02:44:00,840 --> 02:44:02,840
n
3935
02:44:02,840 --> 02:44:06,920
right that that makes sense to me cool
3936
02:44:06,920 --> 02:44:08,279
um because basically we're just saying
3937
02:44:08,279 --> 02:44:10,080
we only need to check up to the square
3938
02:44:10,080 --> 02:44:12,399
root of n we know that if we go higher
3939
02:44:12,399 --> 02:44:15,479
than that um but like we don't care
3940
02:44:15,479 --> 02:44:16,840
about numbers higher than the square
3941
02:44:16,840 --> 02:44:20,040
root um cool
3942
02:44:20,040 --> 02:44:22,880
next one is
3943
02:44:26,160 --> 02:44:29,439
i++ if I could be multiplied into n so
3944
02:44:29,439 --> 02:44:33,880
if n mod I
3945
02:44:33,880 --> 02:44:38,160
oops if if I goes into n evenly so if
3946
02:44:38,160 --> 02:44:42,240
that results in a zero n is not prime
3947
02:44:42,240 --> 02:44:44,040
skip to the next
3948
02:44:44,040 --> 02:44:48,240
n okay so I can't continue here because
3949
02:44:48,240 --> 02:44:49,600
if I continue here here I'll just skip
3950
02:44:49,600 --> 02:44:51,680
to the next I and I want to skip to the
3951
02:44:51,680 --> 02:44:56,120
next n so I think what I do here is I do
3952
02:44:56,120 --> 02:44:59,680
something like is
3953
02:44:59,680 --> 02:45:02,120
prime
3954
02:45:02,120 --> 02:45:05,600
true here I set is prime is
3955
02:45:05,600 --> 02:45:09,040
false and break and then at the end of
3956
02:45:09,040 --> 02:45:14,040
the for loop I can say if not is
3957
02:45:14,560 --> 02:45:16,600
prime
3958
02:45:16,600 --> 02:45:20,600
continue okay
3959
02:45:21,279 --> 02:45:24,680
okay uh if n is not prime skip to next n
3960
02:45:24,680 --> 02:45:27,600
yeah so we'll break out of this
3961
02:45:27,600 --> 02:45:30,880
Loop right we'll break out of this
3962
02:45:30,880 --> 02:45:33,800
Loop and then we'll
3963
02:45:33,800 --> 02:45:35,640
continue
3964
02:45:35,640 --> 02:45:37,800
cool now I just want to be clear there
3965
02:45:37,800 --> 02:45:39,960
are other ways to write this function
3966
02:45:39,960 --> 02:45:42,640
I'm kind of uh on purpose using lots of
3967
02:45:42,640 --> 02:45:44,800
continues and breaks uh so that we can
3968
02:45:44,800 --> 02:45:48,040
get some practice with it cool um n is
3969
02:45:48,040 --> 02:45:49,479
prime printed so if we get all the way
3970
02:45:49,479 --> 02:45:51,399
to here without any of these kind of
3971
02:45:51,399 --> 02:45:53,479
guard Clauses being triggered then n is
3972
02:45:53,479 --> 02:45:56,200
just Prime so fmt print
3973
02:45:56,200 --> 02:45:58,000
line
3974
02:45:58,000 --> 02:46:01,720
n let's run that and just sanity check
3975
02:46:01,720 --> 02:46:07,319
um our code primes up to 10 2 3 5
3976
02:46:07,319 --> 02:46:11,120
7 yep right that's two is a prime number
3977
02:46:11,120 --> 02:46:13,200
it's kind of like the only even prime
3978
02:46:13,200 --> 02:46:17,960
number and nine is an odd number before
3979
02:46:17,960 --> 02:46:20,120
10 but it's not prime because it's
3980
02:46:20,120 --> 02:46:22,640
evenly divided into by three right maybe
3981
02:46:22,640 --> 02:46:24,520
I should have even explained what prime
3982
02:46:24,520 --> 02:46:26,000
numbers are in the first place in case
3983
02:46:26,000 --> 02:46:28,760
you're not familiar um there is uh there
3984
02:46:28,760 --> 02:46:30,640
is a link here if you want to go read
3985
02:46:30,640 --> 02:46:32,520
more about them but basically a prime
3986
02:46:32,520 --> 02:46:36,240
number is any number where the numbers
3987
02:46:36,240 --> 02:46:39,359
that multiply evenly into it are
3988
02:46:39,359 --> 02:46:42,040
anything except one in itself so if it
3989
02:46:42,040 --> 02:46:45,160
has any multiples or if it has anything
3990
02:46:45,160 --> 02:46:48,520
that multiplies into it that isn't just
3991
02:46:48,520 --> 02:46:52,439
one and itself it's Prime right so seven
3992
02:46:52,439 --> 02:46:55,240
you can't you can't multiply two into
3993
02:46:55,240 --> 02:46:57,160
seven you can't multiply three into
3994
02:46:57,160 --> 02:46:59,439
seven you can't multiply four into seven
3995
02:46:59,439 --> 02:47:01,120
right um so it's
3996
02:47:01,120 --> 02:47:03,960
Prime um let's just uh look at a couple
3997
02:47:03,960 --> 02:47:06,600
more of the examples so up to 20 we got
3998
02:47:06,600 --> 02:47:09,960
2 3 5 7 11 13 17 19 right again we're
3999
02:47:09,960 --> 02:47:12,200
skipping 15 because it has the multiples
4000
02:47:12,200 --> 02:47:13,680
three and
4001
02:47:13,680 --> 02:47:17,600
five primes up to 30 um again skipping
4002
02:47:17,600 --> 02:47:21,920
25 um and also skipping 27 because 9
4003
02:47:21,920 --> 02:47:25,399
divides evenly into 27 as as just three
4004
02:47:25,399 --> 02:47:28,160
cool so hopefully that makes a bit of
4005
02:47:28,160 --> 02:47:31,080
sense and then just kind of as a as an
4006
02:47:31,080 --> 02:47:33,279
explanation of of why this pseudo code
4007
02:47:33,279 --> 02:47:34,760
Works we're skipping even numbers
4008
02:47:34,760 --> 02:47:37,399
because they can't be prime right if it
4009
02:47:37,399 --> 02:47:38,880
if two divides into something it's not
4010
02:47:38,880 --> 02:47:40,640
prime um we only check up to the square
4011
02:47:40,640 --> 02:47:42,399
root because anything higher than the
4012
02:47:42,399 --> 02:47:44,800
square root has no chance of multiplying
4013
02:47:44,800 --> 02:47:48,840
evenly into n right so like for example
4014
02:47:48,840 --> 02:47:50,560
take the number 16 its square root is
4015
02:47:50,560 --> 02:47:54,840
four nothing over four could possibly
4016
02:47:54,840 --> 02:47:57,399
evenly divide into
4017
02:47:57,399 --> 02:48:00,479
16 that the square root couldn't right
4018
02:48:00,479 --> 02:48:02,520
so like for example 8 divides evenly
4019
02:48:02,520 --> 02:48:05,160
into 16 but that's only because four and
4020
02:48:05,160 --> 02:48:06,680
two already
4021
02:48:06,680 --> 02:48:09,520
do okay uh we start checking at two
4022
02:48:09,520 --> 02:48:12,520
because one is not prime one's kind of a
4023
02:48:12,520 --> 02:48:13,720
special case
4024
02:48:13,720 --> 02:48:15,800
number okay so this is looking correct
4025
02:48:15,800 --> 02:48:18,000
to me I'm going to go ahead and submit
4026
02:48:18,000 --> 02:48:20,319
it
4027
02:48:20,319 --> 02:48:22,720
let's talk a little bit about how arrays
4028
02:48:22,720 --> 02:48:24,399
work under the hood so if you're
4029
02:48:24,399 --> 02:48:26,760
familiar with the idea of arrays from
4030
02:48:26,760 --> 02:48:29,680
JavaScript or lists from python arrays
4031
02:48:29,680 --> 02:48:33,240
and go are similar you can think of an
4032
02:48:33,240 --> 02:48:36,800
array is just an ordered list of items
4033
02:48:36,800 --> 02:48:39,160
so we usually denote arrays with square
4034
02:48:39,160 --> 02:48:42,000
brackets and an array of say three
4035
02:48:42,000 --> 02:48:47,680
integers might be something like 2 3 1
4036
02:48:47,680 --> 02:48:49,439
right so we've got three integers
4037
02:48:49,439 --> 02:48:52,479
stored in our array the first thing is
4038
02:48:52,479 --> 02:48:55,880
the integer 2 it's stored at index zero
4039
02:48:55,880 --> 02:48:57,640
the next one is a three it's stored at
4040
02:48:57,640 --> 02:49:00,560
index one and finally we have a one
4041
02:49:00,560 --> 02:49:04,080
stored at index 2 now here's the big
4042
02:49:04,080 --> 02:49:06,000
difference between arrays in go and
4043
02:49:06,000 --> 02:49:08,880
arrays in JavaScript or lists in Python
4044
02:49:08,880 --> 02:49:12,520
in go arrays have a fixed size so the
4045
02:49:12,520 --> 02:49:15,560
type of this array would
4046
02:49:15,560 --> 02:49:19,560
be three
4047
02:49:20,920 --> 02:49:24,200
int so inside of the square brackets we
4048
02:49:24,200 --> 02:49:26,319
kind of indicate the size of the array
4049
02:49:26,319 --> 02:49:29,080
and then after we indicate the type of
4050
02:49:29,080 --> 02:49:32,520
thing in the array so this array's type
4051
02:49:32,520 --> 02:49:35,680
is an array of three integers in
4052
02:49:35,680 --> 02:49:38,200
languages like JavaScript or again like
4053
02:49:38,200 --> 02:49:41,399
lists in Python arrays are kind of
4054
02:49:41,399 --> 02:49:43,520
dynamically resize they don't have a
4055
02:49:43,520 --> 02:49:45,399
fixed size you can add things onto the
4056
02:49:45,399 --> 02:49:47,399
end you can push stuff onto the
4057
02:49:47,399 --> 02:49:51,040
beginning but in go arrays are always
4058
02:49:51,040 --> 02:49:53,319
fixed so to show you what this looks
4059
02:49:53,319 --> 02:49:55,520
like in code um basically we can create
4060
02:49:55,520 --> 02:50:00,040
a new array of 10 integers like this it
4061
02:50:00,040 --> 02:50:02,760
will initialize all of the indices in
4062
02:50:02,760 --> 02:50:04,279
the array to the zero value so this
4063
02:50:04,279 --> 02:50:08,120
would be an array of 10 zeros basically
4064
02:50:08,120 --> 02:50:10,600
um if we know what we want to store at
4065
02:50:10,600 --> 02:50:13,040
each index in the array then we can use
4066
02:50:13,040 --> 02:50:14,439
an initialize literal here so we're
4067
02:50:14,439 --> 02:50:17,319
saying we have an array of six integers
4068
02:50:17,319 --> 02:50:19,160
and in the first index I wanted to two
4069
02:50:19,160 --> 02:50:21,200
and then a three and then a five and so
4070
02:50:21,200 --> 02:50:23,479
on so let's jump into an assignment and
4071
02:50:23,479 --> 02:50:25,880
see how this works the assignment says
4072
02:50:25,880 --> 02:50:27,439
when a message is not responded to we
4073
02:50:27,439 --> 02:50:29,080
allow our clients to have up to two
4074
02:50:29,080 --> 02:50:30,560
additional messages that are sent as
4075
02:50:30,560 --> 02:50:33,399
nudging reminders get message with
4076
02:50:33,399 --> 02:50:35,600
retries returns an array of three
4077
02:50:35,600 --> 02:50:37,600
strings where index zero is the first
4078
02:50:37,600 --> 02:50:39,640
message if the first message is not
4079
02:50:39,640 --> 02:50:41,000
answered by the recipient we send the
4080
02:50:41,000 --> 02:50:43,600
second and then we'd send the third
4081
02:50:43,600 --> 02:50:45,359
update get message with reti to return
4082
02:50:45,359 --> 02:50:47,880
the three following strings in an array
4083
02:50:47,880 --> 02:50:49,479
click here to sign up PR please click
4084
02:50:49,479 --> 02:50:51,760
here we beg you to sign up Okay cool so
4085
02:50:51,760 --> 02:50:53,319
this is pretty straightforward here
4086
02:50:53,319 --> 02:50:54,720
we're just going to
4087
02:50:54,720 --> 02:50:57,399
return an array and you can see the
4088
02:50:57,399 --> 02:51:00,040
return type up here it's a string array
4089
02:51:00,040 --> 02:51:03,880
of size three so we just need to create
4090
02:51:03,880 --> 02:51:06,920
an array literal and return it and in
4091
02:51:06,920 --> 02:51:10,200
this case we want an array of strings of
4092
02:51:10,200 --> 02:51:13,239
size three so array string size three
4093
02:51:13,239 --> 02:51:16,040
and we can use these curly
4094
02:51:16,040 --> 02:51:20,120
brackets um to be kind of where we put
4095
02:51:20,120 --> 02:51:21,680
the string literal so the first string
4096
02:51:21,680 --> 02:51:23,920
is going to be click here to sign up
4097
02:51:23,920 --> 02:51:26,640
right this is the first message that's
4098
02:51:26,640 --> 02:51:30,399
sent pretty please click
4099
02:51:30,399 --> 02:51:33,800
here and we beg you we beg you to sign
4100
02:51:33,800 --> 02:51:36,319
up and then just remember that in go you
4101
02:51:36,319 --> 02:51:39,200
do have to put that last comma um if
4102
02:51:39,200 --> 02:51:40,800
you're going to use a new
4103
02:51:40,800 --> 02:51:44,200
line okay um pretty straightforward
4104
02:51:44,200 --> 02:51:47,520
right let's see how that
4105
02:51:47,520 --> 02:51:50,479
works
4106
02:51:50,479 --> 02:51:53,160
sending sending to Bob click here to
4107
02:51:53,160 --> 02:51:55,319
sign up they responded sending to Alice
4108
02:51:55,319 --> 02:51:56,880
click here to sign up pry please click
4109
02:51:56,880 --> 02:52:00,080
here they responded okay this is looking
4110
02:52:00,080 --> 02:52:03,080
this is looking good to
4111
02:52:03,720 --> 02:52:08,399
me going to kind of get a peek at the
4112
02:52:09,160 --> 02:52:11,359
uh at the test
4113
02:52:11,359 --> 02:52:14,359
Suite cool let's submit it and see how
4114
02:52:14,359 --> 02:52:17,120
we did so we've talked about how arrays
4115
02:52:17,120 --> 02:52:18,920
are fixed in size and you might be
4116
02:52:18,920 --> 02:52:21,120
wondering well that's not very useful
4117
02:52:21,120 --> 02:52:23,239
why would I care about an ordered list
4118
02:52:23,239 --> 02:52:25,720
of things if I can't even add to or
4119
02:52:25,720 --> 02:52:28,160
remove from the list well that's where
4120
02:52:28,160 --> 02:52:31,760
slices come into play so let's draw out
4121
02:52:31,760 --> 02:52:33,479
a simple
4122
02:52:33,479 --> 02:52:36,319
array I'll do it in yellow let's just
4123
02:52:36,319 --> 02:52:37,800
say it's storing some numbers we might
4124
02:52:37,800 --> 02:52:43,040
have some numbers like six 3 2
4125
02:52:43,040 --> 02:52:47,200
6 five and I'll draw the indices let's
4126
02:52:47,200 --> 02:52:49,760
do that in pink so the index of the
4127
02:52:49,760 --> 02:52:54,399
first item is zero and then 1 2 3 4
4128
02:52:54,399 --> 02:52:57,080
right and the size of the array is five
4129
02:52:57,080 --> 02:52:59,479
which in go we would write like like
4130
02:52:59,479 --> 02:53:03,120
this we would say we have an array of
4131
02:53:03,120 --> 02:53:06,720
five items and they are integers Okay
4132
02:53:06,720 --> 02:53:08,760
cool so we understand what an array is
4133
02:53:08,760 --> 02:53:11,880
but what's a slice well slices in go are
4134
02:53:11,880 --> 02:53:15,279
written with this syntax open close
4135
02:53:15,279 --> 02:53:19,080
bracket int and you'll notice that the
4136
02:53:19,080 --> 02:53:23,840
size is missing okay so a slice is a
4137
02:53:23,840 --> 02:53:27,319
dynamically sized flexible view into an
4138
02:53:27,319 --> 02:53:29,640
array so slices are built on top of
4139
02:53:29,640 --> 02:53:32,520
arrays so that means for example that I
4140
02:53:32,520 --> 02:53:36,399
could create a slice that just looks at
4141
02:53:36,399 --> 02:53:38,880
this kind of middle
4142
02:53:38,880 --> 02:53:41,920
portion of this array if I were to write
4143
02:53:41,920 --> 02:53:43,720
this in code I would basically say if
4144
02:53:43,720 --> 02:53:47,000
this array is named a so a is this
4145
02:53:47,000 --> 02:53:49,080
yellow array here if if I want to create
4146
02:53:49,080 --> 02:53:52,040
a slice on top of that array then I
4147
02:53:52,040 --> 02:53:54,080
could write
4148
02:53:54,080 --> 02:53:57,560
B colon equals
4149
02:53:57,560 --> 02:54:01,960
a from we're using square brackets here
4150
02:54:01,960 --> 02:54:03,680
index
4151
02:54:03,680 --> 02:54:08,399
one up to but not including index 4 okay
4152
02:54:08,399 --> 02:54:09,680
so the first the first number is
4153
02:54:09,680 --> 02:54:12,479
inclusive the second number is exclusive
4154
02:54:12,479 --> 02:54:16,399
and now B is this slice of kind of just
4155
02:54:16,399 --> 02:54:18,920
that middle view of the array and here's
4156
02:54:18,920 --> 02:54:21,399
the important thing to understand in go
4157
02:54:21,399 --> 02:54:24,080
we actually almost never deal with
4158
02:54:24,080 --> 02:54:28,000
arrays directly 99 times out of 100
4159
02:54:28,000 --> 02:54:30,600
you'll just be working with slices
4160
02:54:30,600 --> 02:54:32,359
because slices provide a much better
4161
02:54:32,359 --> 02:54:35,080
developer experience they're built on
4162
02:54:35,080 --> 02:54:37,040
top of arrays for kind of memory
4163
02:54:37,040 --> 02:54:38,439
management reasons which we'll talk
4164
02:54:38,439 --> 02:54:40,520
about in just a second but you really
4165
02:54:40,520 --> 02:54:43,160
want to be working um for the most part
4166
02:54:43,160 --> 02:54:44,800
with slices because you don't have to
4167
02:54:44,800 --> 02:54:47,960
worry about that fixed size problem so
4168
02:54:47,960 --> 02:54:51,520
just review slices sort of in code um we
4169
02:54:51,520 --> 02:54:54,880
can create an array literal like this
4170
02:54:54,880 --> 02:54:56,800
right this is an array because we have
4171
02:54:56,800 --> 02:54:59,560
we have the uh size of the array there
4172
02:54:59,560 --> 02:55:02,040
six integers and then we can create a
4173
02:55:02,040 --> 02:55:06,120
slice on top of the array like this cool
4174
02:55:06,120 --> 02:55:07,640
um let's jump into the assignment so you
4175
02:55:07,640 --> 02:55:09,880
can kind of get a feel for how this all
4176
02:55:09,880 --> 02:55:12,479
works okay the assignment says retries
4177
02:55:12,479 --> 02:55:14,399
are a premium feature now textos free
4178
02:55:14,399 --> 02:55:16,640
users only get one retry message while
4179
02:55:16,640 --> 02:55:18,840
Pro members get an unlimited amount
4180
02:55:18,840 --> 02:55:20,359
complete the get message with retries
4181
02:55:20,359 --> 02:55:22,600
for plan function it takes a plan
4182
02:55:22,600 --> 02:55:24,359
variable as input that's a string
4183
02:55:24,359 --> 02:55:26,720
matches up to one of these um if the
4184
02:55:26,720 --> 02:55:28,800
plan is a Pro Plan return all of the
4185
02:55:28,800 --> 02:55:31,040
strings from get message with retries
4186
02:55:31,040 --> 02:55:32,920
Okay cool so get message with retries it
4187
02:55:32,920 --> 02:55:34,200
looks like
4188
02:55:34,200 --> 02:55:36,840
returns an array of three
4189
02:55:36,840 --> 02:55:39,120
strings okay let's just jump right into
4190
02:55:39,120 --> 02:55:43,239
it if plan is plan
4191
02:55:43,239 --> 02:55:47,120
Pro then we'll return all messages right
4192
02:55:47,120 --> 02:55:50,520
return all the strings yep and a nil
4193
02:55:50,520 --> 02:55:53,080
error otherwise if the
4194
02:55:53,080 --> 02:55:56,560
plan is plan
4195
02:55:56,560 --> 02:55:59,479
free return the first two strings right
4196
02:55:59,479 --> 02:56:01,600
the original string and kind of the one
4197
02:56:01,600 --> 02:56:04,600
the first retry message so return all
4198
02:56:04,600 --> 02:56:07,080
messages and we're going to slice it
4199
02:56:07,080 --> 02:56:09,279
from index zero up to but not including
4200
02:56:09,279 --> 02:56:11,279
index two so that'll be indexes zero and
4201
02:56:11,279 --> 02:56:14,560
one right two two strings and then we'll
4202
02:56:14,560 --> 02:56:16,120
also return
4203
02:56:16,120 --> 02:56:19,120
nil and finally if it's neither of those
4204
02:56:19,120 --> 02:56:22,000
return an error that says unsupported
4205
02:56:22,000 --> 02:56:28,279
plan so return nil errors. new
4206
02:56:28,279 --> 02:56:31,560
unsupported plan and nil um is just kind
4207
02:56:31,560 --> 02:56:34,080
of the zero value of
4208
02:56:34,080 --> 02:56:36,600
slice cool um this is looking good we
4209
02:56:36,600 --> 02:56:39,600
need to make sure we import the errors
4210
02:56:39,600 --> 02:56:41,640
package let's go ahead and run this and
4211
02:56:41,640 --> 02:56:42,920
see what
4212
02:56:42,920 --> 02:56:46,120
happens o we got an error cannot use all
4213
02:56:46,120 --> 02:56:49,359
messages variable of type
4214
02:56:49,359 --> 02:56:52,520
array size three string as slice of
4215
02:56:52,520 --> 02:56:56,600
string Okay cool so we have an
4216
02:56:56,600 --> 02:56:59,479
array all messages is an array not a
4217
02:56:59,479 --> 02:57:02,600
slice right so we actually need to slice
4218
02:57:02,600 --> 02:57:06,920
this to change its type but we want all
4219
02:57:06,920 --> 02:57:08,680
of the values inside of the array so
4220
02:57:08,680 --> 02:57:10,760
we're just going to use this colon
4221
02:57:10,760 --> 02:57:13,960
syntax to get access to everything in
4222
02:57:13,960 --> 02:57:15,800
the underlying array let's run that
4223
02:57:15,800 --> 02:57:18,800
again
4224
02:57:20,560 --> 02:57:21,800
cool sending to
4225
02:57:21,800 --> 02:57:24,319
osar click here to sign up pretty please
4226
02:57:24,319 --> 02:57:26,439
click here so that's two two messages
4227
02:57:26,439 --> 02:57:27,399
with no
4228
02:57:27,399 --> 02:57:29,800
response um and I'm guessing because yep
4229
02:57:29,800 --> 02:57:32,880
ozer is on a free plan Jess Jeff is on a
4230
02:57:32,880 --> 02:57:35,520
Pro Plan so he gets all three messages
4231
02:57:35,520 --> 02:57:37,479
this is looking correct to me these next
4232
02:57:37,479 --> 02:57:39,399
few questions will reference kind of
4233
02:57:39,399 --> 02:57:42,120
excerpts from the effective gobook which
4234
02:57:42,120 --> 02:57:44,040
is definitely a book I recommend reading
4235
02:57:44,040 --> 02:57:46,239
although it is a bit out of date it was
4236
02:57:46,239 --> 02:57:49,200
written a while ago um and the authors
4237
02:57:49,200 --> 02:57:50,840
have basically made the decision not to
4238
02:57:50,840 --> 02:57:53,200
update um the book over time kind of
4239
02:57:53,200 --> 02:57:55,080
keeping it as a snapshot so it has a lot
4240
02:57:55,080 --> 02:57:57,239
of great stuff in there and go has very
4241
02:57:57,239 --> 02:57:58,600
strong backwards compatibility so it's
4242
02:57:58,600 --> 02:58:00,160
still a great read um just kind of be
4243
02:58:00,160 --> 02:58:03,160
aware that it hasn't been updated um in
4244
02:58:03,160 --> 02:58:07,239
a while cool um that said everything we
4245
02:58:07,239 --> 02:58:09,680
explained here I'll obviously provide uh
4246
02:58:09,680 --> 02:58:13,960
context um for so the thing that's
4247
02:58:13,960 --> 02:58:16,080
important to understand in this section
4248
02:58:16,080 --> 02:58:20,279
is that slices are references to kind of
4249
02:58:20,279 --> 02:58:22,680
what goes on underneath the hood with
4250
02:58:22,680 --> 02:58:26,680
arrays so what that really means to you
4251
02:58:26,680 --> 02:58:29,600
as a developer is when you use slices
4252
02:58:29,600 --> 02:58:31,399
and more specifically when you pass them
4253
02:58:31,399 --> 02:58:33,680
around say into a function you're
4254
02:58:33,680 --> 02:58:36,560
actually passing a reference which means
4255
02:58:36,560 --> 02:58:40,279
if you change the values in that slice
4256
02:58:40,279 --> 02:58:43,560
within a function the caller the person
4257
02:58:43,560 --> 02:58:44,960
who called your function or I should say
4258
02:58:44,960 --> 02:58:46,239
the bit of code that called your
4259
02:58:46,239 --> 02:58:48,399
function will actually have access to
4260
02:58:48,399 --> 02:58:51,000
those changes it will see those changes
4261
02:58:51,000 --> 02:58:53,399
even if you don't explicitly return the
4262
02:58:53,399 --> 02:58:56,319
slice again now this is different um
4263
02:58:56,319 --> 02:58:58,399
from sort of normal primitive values
4264
02:58:58,399 --> 02:59:00,200
which are passed by value you might
4265
02:59:00,200 --> 02:59:02,479
remember us talking about pass by value
4266
02:59:02,479 --> 02:59:05,160
earlier in the course typically if you
4267
02:59:05,160 --> 02:59:07,439
pass in say a string or an integer into
4268
02:59:07,439 --> 02:59:09,080
a function and then within that function
4269
02:59:09,080 --> 02:59:11,399
you change it the caller won't see those
4270
02:59:11,399 --> 02:59:13,800
changes you have your own copy of that
4271
02:59:13,800 --> 02:59:16,720
data that's that does not hold true with
4272
02:59:16,720 --> 02:59:18,920
slices so just understand that when you
4273
02:59:18,920 --> 02:59:21,080
pass a slice into a function it might
4274
02:59:21,080 --> 02:59:21,840
get
4275
02:59:21,840 --> 02:59:25,160
modified okay cool um so which
4276
02:59:25,160 --> 02:59:27,800
references the other is the question do
4277
02:59:27,800 --> 02:59:29,880
arrays reference slices or do slices
4278
02:59:29,880 --> 02:59:31,840
reference arrays and the answer is that
4279
02:59:31,840 --> 02:59:34,760
slices reference arrays the next
4280
02:59:34,760 --> 02:59:37,560
question is can multiple slices point to
4281
02:59:37,560 --> 02:59:39,680
the same array is that true or false
4282
02:59:39,680 --> 02:59:41,760
multiple slices point to the same array
4283
02:59:41,760 --> 02:59:45,439
um that is true remember slices are just
4284
02:59:45,439 --> 02:59:48,120
kind of a view into an array so it makes
4285
02:59:48,120 --> 02:59:49,800
sense that you can have multiple views
4286
02:59:49,800 --> 02:59:52,439
into the same underlying array so
4287
02:59:52,439 --> 02:59:54,880
multiple slices can point to the same
4288
02:59:54,880 --> 02:59:57,479
array now here's that question um that
4289
02:59:57,479 --> 02:59:59,800
we talked about earlier a function that
4290
02:59:59,800 --> 03:00:03,359
only has access to a slice can modify
4291
03:00:03,359 --> 03:00:06,359
the underlying array the answer to this
4292
03:00:06,359 --> 03:00:09,279
is that is true even if the function
4293
03:00:09,279 --> 03:00:12,279
doesn't return that slice it can modify
4294
03:00:12,279 --> 03:00:15,120
the values in the underlying array let's
4295
03:00:15,120 --> 03:00:17,160
talk about how slices work um kind of
4296
03:00:17,160 --> 03:00:18,920
specifically how work in relation to
4297
03:00:18,920 --> 03:00:21,080
your computer's Hardware or your
4298
03:00:21,080 --> 03:00:24,880
computer's Ram now Ram just stands for
4299
03:00:24,880 --> 03:00:27,160
Random Access Memory it's where
4300
03:00:27,160 --> 03:00:29,040
variables are stored the best way to
4301
03:00:29,040 --> 03:00:32,680
think about Ram is just a mapping of
4302
03:00:32,680 --> 03:00:35,160
addresses so
4303
03:00:35,160 --> 03:00:37,640
address to
4304
03:00:37,640 --> 03:00:40,640
data right it gives us a place to store
4305
03:00:40,640 --> 03:00:44,479
stuff so for example at address
4306
03:00:44,479 --> 03:00:47,479
Z we might have some data that
4307
03:00:47,479 --> 03:00:50,279
represents I don't know the number four
4308
03:00:50,279 --> 03:00:54,000
right and then at address one we might
4309
03:00:54,000 --> 03:00:55,880
have some data representing the number
4310
03:00:55,880 --> 03:00:57,960
five I don't know I'm just making stuff
4311
03:00:57,960 --> 03:01:00,200
up but you get the idea we have
4312
03:01:00,200 --> 03:01:03,399
addresses and we have data associated
4313
03:01:03,399 --> 03:01:06,920
with that address slices and the arrays
4314
03:01:06,920 --> 03:01:09,200
that they are built on top of are stored
4315
03:01:09,200 --> 03:01:11,960
in contiguous memory basically what that
4316
03:01:11,960 --> 03:01:16,600
means is a slice or an array is an
4317
03:01:16,600 --> 03:01:18,640
address in memory where where the slice
4318
03:01:18,640 --> 03:01:21,279
or array starts so for example at
4319
03:01:21,279 --> 03:01:23,680
address zero we might say this is the
4320
03:01:23,680 --> 03:01:26,080
start of a
4321
03:01:26,080 --> 03:01:29,359
slice and the slice actually continues
4322
03:01:29,359 --> 03:01:32,800
for the next you know several uh kind of
4323
03:01:32,800 --> 03:01:34,680
bytes of data let's say that it's a
4324
03:01:34,680 --> 03:01:36,800
slice of length three so it actually
4325
03:01:36,800 --> 03:01:39,760
would reach across all three of these
4326
03:01:39,760 --> 03:01:42,080
addresses so if you have an array or a
4327
03:01:42,080 --> 03:01:45,880
slice um and its address is zero and its
4328
03:01:45,880 --> 03:01:49,000
length is three then you know kind of
4329
03:01:49,000 --> 03:01:53,040
how many uh stores of data in memory um
4330
03:01:53,040 --> 03:01:56,840
your slice or array will use now this is
4331
03:01:56,840 --> 03:01:59,319
primarily important for performance
4332
03:01:59,319 --> 03:02:01,960
because all of the data is stored next
4333
03:02:01,960 --> 03:02:04,080
to each other in memory it's going to be
4334
03:02:04,080 --> 03:02:06,239
faster to kind of iterate over all of
4335
03:02:06,239 --> 03:02:08,960
the values in our slice if we stored
4336
03:02:08,960 --> 03:02:11,359
each index in kind of random places in
4337
03:02:11,359 --> 03:02:13,120
memory it would take a lot longer to go
4338
03:02:13,120 --> 03:02:15,120
collect all of that data just you know
4339
03:02:15,120 --> 03:02:17,359
from a hardware perspective however
4340
03:02:17,359 --> 03:02:20,560
there is a downside to having to store
4341
03:02:20,560 --> 03:02:23,359
all of our memory um kind of next to
4342
03:02:23,359 --> 03:02:26,359
each other let's pretend that we have
4343
03:02:26,359 --> 03:02:28,560
this slice or this array that starts at
4344
03:02:28,560 --> 03:02:30,359
address zero and has a length of three
4345
03:02:30,359 --> 03:02:32,319
so it's using kind of these three
4346
03:02:32,319 --> 03:02:34,600
addresses in memory or these three bytes
4347
03:02:34,600 --> 03:02:37,920
of memory and let's say here at address
4348
03:02:37,920 --> 03:02:41,000
3 we're storing a different value maybe
4349
03:02:41,000 --> 03:02:42,840
we're just storing I don't know the
4350
03:02:42,840 --> 03:02:46,479
number six um but this is a different
4351
03:02:46,479 --> 03:02:48,439
variable
4352
03:02:48,439 --> 03:02:50,920
this is some other variable the problem
4353
03:02:50,920 --> 03:02:54,160
is if we want to expand our slice say
4354
03:02:54,160 --> 03:02:56,080
add another value to it we're going to
4355
03:02:56,080 --> 03:02:58,640
run into the next thing in physical
4356
03:02:58,640 --> 03:03:00,239
memory that's a huge problem we don't
4357
03:03:00,239 --> 03:03:02,560
want to overwrite some other variable
4358
03:03:02,560 --> 03:03:05,520
just because we're growing our slice so
4359
03:03:05,520 --> 03:03:08,279
this is why arrays are fixed in size if
4360
03:03:08,279 --> 03:03:10,520
we just can't grow them then we'll never
4361
03:03:10,520 --> 03:03:13,720
have this overwriting problem so the the
4362
03:03:13,720 --> 03:03:15,479
question of course is how do slices do
4363
03:03:15,479 --> 03:03:17,800
it right well slices are built on top of
4364
03:03:17,800 --> 03:03:20,760
rays and basically what happens is I can
4365
03:03:20,760 --> 03:03:23,600
draw this out for us when we want to
4366
03:03:23,600 --> 03:03:25,040
grow a
4367
03:03:25,040 --> 03:03:28,359
slice whose underlying array has run out
4368
03:03:28,359 --> 03:03:31,840
of room right so we have our slice um
4369
03:03:31,840 --> 03:03:34,000
built on top of this length three array
4370
03:03:34,000 --> 03:03:36,279
and we want to grow it into a length of
4371
03:03:36,279 --> 03:03:38,640
four what happens under the hood and
4372
03:03:38,640 --> 03:03:40,439
this all kind of happens without you
4373
03:03:40,439 --> 03:03:41,840
seeing it as a developer you'll you'll
4374
03:03:41,840 --> 03:03:43,640
see later when we get to the syntax it's
4375
03:03:43,640 --> 03:03:45,720
actually really simple um what happens
4376
03:03:45,720 --> 03:03:47,359
is this data is copied into a new
4377
03:03:47,359 --> 03:03:49,359
location memory so we just take this
4378
03:03:49,359 --> 03:03:53,600
four we put it over here five over here
4379
03:03:53,600 --> 03:03:54,800
uh actually I'm going to use the same
4380
03:03:54,800 --> 03:03:56,680
colors that would probably be easier to
4381
03:03:56,680 --> 03:03:59,760
understand so four comes over here five
4382
03:03:59,760 --> 03:04:02,760
comes over here three comes over here
4383
03:04:02,760 --> 03:04:05,319
and then let's say that we um we know we
4384
03:04:05,319 --> 03:04:07,359
want to grow our slice significantly so
4385
03:04:07,359 --> 03:04:09,600
the new underlying
4386
03:04:09,600 --> 03:04:12,760
array let's say will have a length of
4387
03:04:12,760 --> 03:04:16,080
six now so it had three here now the new
4388
03:04:16,080 --> 03:04:19,720
array has allocated pre-allocated right
4389
03:04:19,720 --> 03:04:22,120
we've essentially reserved memory for up
4390
03:04:22,120 --> 03:04:27,640
to six spaces let me draw all of that
4391
03:04:27,640 --> 03:04:31,399
out cool and these addresses over here
4392
03:04:31,399 --> 03:04:32,640
are going to be totally different right
4393
03:04:32,640 --> 03:04:37,760
maybe it's address 15 address 16 17 18
4394
03:04:37,760 --> 03:04:40,279
19 and
4395
03:04:40,279 --> 03:04:42,520
20 cool so all the data from the old
4396
03:04:42,520 --> 03:04:44,560
array gets copied over and now we're
4397
03:04:44,560 --> 03:04:48,720
able to expand our slice
4398
03:04:48,720 --> 03:04:50,920
our slice to a length of
4399
03:04:50,920 --> 03:04:53,680
four right so here our slice was length
4400
03:04:53,680 --> 03:04:55,760
three and the underlying array was
4401
03:04:55,760 --> 03:04:58,920
length three now we've copied over the
4402
03:04:58,920 --> 03:05:01,319
data we've created a much larger
4403
03:05:01,319 --> 03:05:04,640
underlying array and now we have a slice
4404
03:05:04,640 --> 03:05:06,640
of length four maybe we wanted to append
4405
03:05:06,640 --> 03:05:08,920
say the number two to the end of the
4406
03:05:08,920 --> 03:05:11,279
slice so again as the developer you're
4407
03:05:11,279 --> 03:05:13,200
not going to have to do all of this
4408
03:05:13,200 --> 03:05:16,239
array management manually but it's
4409
03:05:16,239 --> 03:05:17,920
important to understand that this is
4410
03:05:17,920 --> 03:05:19,319
what's going on under the hood because
4411
03:05:19,319 --> 03:05:22,080
it has performance implications copying
4412
03:05:22,080 --> 03:05:24,720
data isn't super efficient if you're
4413
03:05:24,720 --> 03:05:27,319
copying data from one section in memory
4414
03:05:27,319 --> 03:05:29,520
to another um over and over and over
4415
03:05:29,520 --> 03:05:32,359
again it can slow down your programs so
4416
03:05:32,359 --> 03:05:34,000
now that we've covered all of that
4417
03:05:34,000 --> 03:05:36,040
memory stuff and how it works under the
4418
03:05:36,040 --> 03:05:39,000
hood what does that mean in code right
4419
03:05:39,000 --> 03:05:42,000
well this is how we can create a slice
4420
03:05:42,000 --> 03:05:44,359
without explicitly creating an array
4421
03:05:44,359 --> 03:05:46,200
under the hood right so this will
4422
03:05:46,200 --> 03:05:48,120
automatically create an an array under
4423
03:05:48,120 --> 03:05:50,439
the hood for us if we use this syntax so
4424
03:05:50,439 --> 03:05:51,960
this is basically saying I want a new
4425
03:05:51,960 --> 03:05:54,880
slice of integers I want its initial
4426
03:05:54,880 --> 03:05:57,439
length to be five so the length of the
4427
03:05:57,439 --> 03:05:59,760
slice right the length of the view into
4428
03:05:59,760 --> 03:06:03,720
the array will be five and the capacity
4429
03:06:03,720 --> 03:06:07,439
will be 10 so the capacity is kind of
4430
03:06:07,439 --> 03:06:09,960
the total space that we have to grow the
4431
03:06:09,960 --> 03:06:12,880
slice until we need to allocate a new
4432
03:06:12,880 --> 03:06:14,439
array under the hood so you could almost
4433
03:06:14,439 --> 03:06:16,359
think of this capacity is just the
4434
03:06:16,359 --> 03:06:18,680
length of the underlying array now I
4435
03:06:18,680 --> 03:06:20,000
told you that you don't need to think
4436
03:06:20,000 --> 03:06:21,200
about the size of the under the Ling
4437
03:06:21,200 --> 03:06:23,840
array and that is true typically you'll
4438
03:06:23,840 --> 03:06:25,760
actually use this syntax where you don't
4439
03:06:25,760 --> 03:06:30,319
even specify a capacity so if you do not
4440
03:06:30,319 --> 03:06:32,279
specify a capacity it defaults to the
4441
03:06:32,279 --> 03:06:35,000
length so the kind of length of the
4442
03:06:35,000 --> 03:06:37,600
underlying array for a slice of integers
4443
03:06:37,600 --> 03:06:40,000
with length five will just be five and
4444
03:06:40,000 --> 03:06:42,319
if you grow it past that the memory
4445
03:06:42,319 --> 03:06:44,520
copying will happen and you'll create a
4446
03:06:44,520 --> 03:06:46,560
new underlying array now you might be
4447
03:06:46,560 --> 03:06:47,800
thinking oh that's terrible for
4448
03:06:47,800 --> 03:06:51,319
performance in reality it's not that bad
4449
03:06:51,319 --> 03:06:52,880
the only reason you would start to kind
4450
03:06:52,880 --> 03:06:55,560
of fuss with specific capacities and
4451
03:06:55,560 --> 03:06:57,760
optimizing your memory copying is if
4452
03:06:57,760 --> 03:07:00,319
you're having performance problems
4453
03:07:00,319 --> 03:07:02,920
generally speaking the convenience of
4454
03:07:02,920 --> 03:07:04,640
keeping your code simple and easy to
4455
03:07:04,640 --> 03:07:07,040
understand is going to outweigh kind of
4456
03:07:07,040 --> 03:07:09,399
the performance cost that it'll have
4457
03:07:09,399 --> 03:07:11,160
it's it's a very small one generally
4458
03:07:11,160 --> 03:07:13,000
speaking and then it's also just worth
4459
03:07:13,000 --> 03:07:14,720
pointing out that we can also create
4460
03:07:14,720 --> 03:07:16,560
slice literals right so this just
4461
03:07:16,560 --> 03:07:18,760
creates a new slice slice of length
4462
03:07:18,760 --> 03:07:22,160
three um and initializes these three
4463
03:07:22,160 --> 03:07:24,760
values into that slice rather than what
4464
03:07:24,760 --> 03:07:26,880
would happen up here which is that we
4465
03:07:26,880 --> 03:07:29,680
create kind of all of the zero values um
4466
03:07:29,680 --> 03:07:31,560
to fill out the slice kind of of the
4467
03:07:31,560 --> 03:07:33,479
given length so this would be a slice of
4468
03:07:33,479 --> 03:07:35,600
five zeros right and then to just point
4469
03:07:35,600 --> 03:07:37,720
out two more things regarding syntax
4470
03:07:37,720 --> 03:07:40,239
there is a built-in length function that
4471
03:07:40,239 --> 03:07:42,319
Returns the length of a slice and a
4472
03:07:42,319 --> 03:07:45,279
built-in cap function that Returns the
4473
03:07:45,279 --> 03:07:47,680
capacity so now that we are experts on
4474
03:07:47,680 --> 03:07:49,880
slices let's jump into the
4475
03:07:49,880 --> 03:07:51,920
assignment says we send a lot of text
4476
03:07:51,920 --> 03:07:53,439
messages at texo and our API is getting
4477
03:07:53,439 --> 03:07:55,279
slow and unresponsive so I just
4478
03:07:55,279 --> 03:07:56,800
mentioned how you probably shouldn't
4479
03:07:56,800 --> 03:07:59,600
worry about performance well here's a
4480
03:07:59,600 --> 03:08:00,439
case where you should worry about
4481
03:08:00,439 --> 03:08:01,800
performance right you shouldn't worry
4482
03:08:01,800 --> 03:08:03,479
about performance until well it starts
4483
03:08:03,479 --> 03:08:05,640
to become a problem so we're starting to
4484
03:08:05,640 --> 03:08:07,720
have a problem with um this memory
4485
03:08:07,720 --> 03:08:10,920
copying being slow so we've been asked
4486
03:08:10,920 --> 03:08:13,359
to preallocate our
4487
03:08:13,359 --> 03:08:17,040
slices it says um if we know the Rough
4488
03:08:17,040 --> 03:08:18,600
Side of the before we fill it up we can
4489
03:08:18,600 --> 03:08:20,120
make our program Faster by creating the
4490
03:08:20,120 --> 03:08:22,000
slice with that size ahead of time all
4491
03:08:22,000 --> 03:08:23,319
right so complete the message get
4492
03:08:23,319 --> 03:08:25,760
message costs function it takes a slice
4493
03:08:25,760 --> 03:08:27,319
of messages and returns a slice of
4494
03:08:27,319 --> 03:08:31,160
message costs FL 64s right reallocate a
4495
03:08:31,160 --> 03:08:32,680
slice for the message cost with the same
4496
03:08:32,680 --> 03:08:34,160
length as the message slice let's go
4497
03:08:34,160 --> 03:08:37,880
ahead and start off with that so
4498
03:08:37,880 --> 03:08:40,120
costs we'll make a new slice and it's
4499
03:08:40,120 --> 03:08:43,120
going to be a slice of float
4500
03:08:43,120 --> 03:08:48,239
64 and a length of length messages right
4501
03:08:48,239 --> 03:08:52,120
same same length cool um now we want to
4502
03:08:52,120 --> 03:08:54,239
fill the co fill the cost slice with
4503
03:08:54,239 --> 03:08:55,920
cost reach message so let's go ahead and
4504
03:08:55,920 --> 03:08:59,680
iterate over each message so for I colum
4505
03:08:59,680 --> 03:09:00,880
equals
4506
03:09:00,880 --> 03:09:04,439
0 I is less than length of
4507
03:09:04,439 --> 03:09:07,439
messages
4508
03:09:09,479 --> 03:09:13,120
i++ let's get the message at that index
4509
03:09:13,120 --> 03:09:15,160
messages
4510
03:09:15,160 --> 03:09:19,960
zero oh not a zero excuse me at
4511
03:09:19,960 --> 03:09:22,399
I okay the cost in the cost slice should
4512
03:09:22,399 --> 03:09:23,439
correspond to the message and the
4513
03:09:23,439 --> 03:09:24,840
message slice at the same index the cost
4514
03:09:24,840 --> 03:09:26,080
of a message is the length of the
4515
03:09:26,080 --> 03:09:29,760
message multiplied by 01 so cost equals
4516
03:09:29,760 --> 03:09:32,760
the length of the message multiplied by
4518
03:09:34,439 --> 03:09:36,960
01 that's going to need to be cast to a
4519
03:09:36,960 --> 03:09:39,200
float
4520
03:09:39,200 --> 03:09:42,520
64 perfect cool and then we just need to
4521
03:09:42,520 --> 03:09:45,439
save that into the costs slice so costs
4522
03:09:45,439 --> 03:09:49,000
at I equals
4523
03:09:49,000 --> 03:09:52,239
cost right correspond with the same
4524
03:09:52,239 --> 03:09:55,640
index and we know that that um that
4525
03:09:55,640 --> 03:09:57,760
index already exists because we
4526
03:09:57,760 --> 03:10:00,760
pre-allocated it to the correct size
4527
03:10:00,760 --> 03:10:03,439
cool so now we can just return costs
4528
03:10:03,439 --> 03:10:06,279
let's go ahead and run
4529
03:10:07,760 --> 03:10:12,359
that and see if these make
4530
03:10:12,399 --> 03:10:15,520
sense okay these costs line up with the
4531
03:10:15,520 --> 03:10:17,399
length of the messages so this is is
4532
03:10:17,399 --> 03:10:18,960
looking good to me let's review the
4533
03:10:18,960 --> 03:10:20,479
difference between the length and the
4534
03:10:20,479 --> 03:10:22,160
capacity of a slice sometimes this can
4535
03:10:22,160 --> 03:10:24,560
be a little bit confusing the length is
4536
03:10:24,560 --> 03:10:26,000
the thing that you're going to care
4537
03:10:26,000 --> 03:10:28,120
about most often the length just tells
4538
03:10:28,120 --> 03:10:30,160
you how many things are in that slice
4539
03:10:30,160 --> 03:10:32,000
right if I have five items then the
4540
03:10:32,000 --> 03:10:34,720
length of the slice is going to be five
4541
03:10:34,720 --> 03:10:35,600
the
4542
03:10:35,600 --> 03:10:39,000
capacity the capacity of a slice reports
4543
03:10:39,000 --> 03:10:41,680
the maximum length the slice can assume
4544
03:10:41,680 --> 03:10:44,000
right before it gets kind of reassigned
4545
03:10:44,000 --> 03:10:46,840
into a new array so capacity is really
4546
03:10:46,840 --> 03:10:48,160
again only something you're going to
4547
03:10:48,160 --> 03:10:49,640
care about if you're worried about
4548
03:10:49,640 --> 03:10:51,920
performance but the length you'll be
4549
03:10:51,920 --> 03:10:53,960
concerned about just for kind of normal
4550
03:10:53,960 --> 03:10:55,479
business logic reasons right just
4551
03:10:55,479 --> 03:10:56,840
because you want to know how many things
4552
03:10:56,840 --> 03:10:59,040
are stored in your slice so to answer
4553
03:10:59,040 --> 03:11:00,840
this question it says what does the cap
4554
03:11:00,840 --> 03:11:03,000
function return answers are the last
4555
03:11:03,000 --> 03:11:05,319
last element of a slice or the maximum
4556
03:11:05,319 --> 03:11:07,680
length the slice of the slice before
4557
03:11:07,680 --> 03:11:09,640
reallocation of the underlying array is
4558
03:11:09,640 --> 03:11:12,520
necessary the answer is going to be the
4559
03:11:12,520 --> 03:11:14,399
maximum length the next question is what
4560
03:11:14,399 --> 03:11:17,000
does the length function return current
4561
03:11:17,000 --> 03:11:18,680
length of the slice or the maximum
4562
03:11:18,680 --> 03:11:19,560
length of the slice before the
4563
03:11:19,560 --> 03:11:22,120
reallocation is necessary and the answer
4564
03:11:22,120 --> 03:11:23,600
is going to be the current length of the
4565
03:11:23,600 --> 03:11:25,640
slice and we haven't really talked about
4566
03:11:25,640 --> 03:11:27,720
this yet but I'll just kind of inform
4567
03:11:27,720 --> 03:11:29,920
you as we answer this question says what
4568
03:11:29,920 --> 03:11:33,600
do length and cap the two functions do
4569
03:11:33,600 --> 03:11:37,120
when a slice is nil do they Panic or
4570
03:11:37,120 --> 03:11:39,200
return zero and the answer is that they
4571
03:11:39,200 --> 03:11:41,000
return zero they are safe functions to
4572
03:11:41,000 --> 03:11:43,640
call um they won't make your code panic
4573
03:11:43,640 --> 03:11:46,279
and error and crash right um I don't
4574
03:11:46,279 --> 03:11:47,479
know how much we've talked about
4575
03:11:47,479 --> 03:11:49,720
panicking up to this point in the course
4576
03:11:49,720 --> 03:11:52,200
but panicking just means runtime error
4577
03:11:52,200 --> 03:11:54,040
that's unrecoverable
4578
03:11:54,040 --> 03:11:56,359
unrecoverable um generally speaking you
4579
03:11:56,359 --> 03:11:58,000
don't want your code panicking and you
4580
03:11:58,000 --> 03:11:59,760
want to write your code in such a way
4581
03:11:59,760 --> 03:12:03,040
that it can't Panic um so again length
4582
03:12:03,040 --> 03:12:05,439
and cap here um are safe they will never
4583
03:12:05,439 --> 03:12:08,920
Panic if um a slice happens to be um the
4584
03:12:08,920 --> 03:12:11,760
zero value which is nil time for some
4585
03:12:11,760 --> 03:12:15,000
vartic functions um this sounds like a
4586
03:12:15,000 --> 03:12:16,840
really complex thing but we've actually
4587
03:12:16,840 --> 03:12:18,880
been using vartic functions up to this
4588
03:12:18,880 --> 03:12:22,279
point in the course because the S printf
4589
03:12:22,279 --> 03:12:24,640
print F print line all of those
4590
03:12:24,640 --> 03:12:27,359
functions are actually vartic so a
4591
03:12:27,359 --> 03:12:29,760
vartic function receives the vartic
4592
03:12:29,760 --> 03:12:31,720
arguments as a slice let's take a look
4593
03:12:31,720 --> 03:12:34,560
at the syntax so here we have a sum
4594
03:12:34,560 --> 03:12:36,880
function and its function signature is
4595
03:12:36,880 --> 03:12:38,080
just maybe a little bit different than
4596
03:12:38,080 --> 03:12:40,000
you're used to basically we have this
4597
03:12:40,000 --> 03:12:44,040
nums uh parameter which is of type dot
4598
03:12:44,040 --> 03:12:48,200
dot do int now here's the thing dot dot
4599
03:12:48,200 --> 03:12:49,040
do
4600
03:12:49,040 --> 03:12:52,200
int as far as the function definition is
4601
03:12:52,200 --> 03:12:55,840
concerned is just a slice we treat this
4602
03:12:55,840 --> 03:12:58,279
just like we would if it said you know
4603
03:12:58,279 --> 03:13:01,359
square brackets int it's it's just a
4604
03:13:01,359 --> 03:13:03,800
slice of integers so you're probably
4605
03:13:03,800 --> 03:13:05,399
sitting there thinking well why can't I
4606
03:13:05,399 --> 03:13:06,880
just use a slice of integers why can't
4607
03:13:06,880 --> 03:13:08,560
we just keep it simple why do we have to
4608
03:13:08,560 --> 03:13:11,520
do everything differently ah okay well
4609
03:13:11,520 --> 03:13:13,840
uh don't don't worry too much um the
4610
03:13:13,840 --> 03:13:16,800
difference is on the caller's side so
4611
03:13:16,800 --> 03:13:18,600
the function definition is the same
4612
03:13:18,600 --> 03:13:20,359
whether you use dot dot dot int or
4613
03:13:20,359 --> 03:13:23,399
square brackets int but if you use a
4614
03:13:23,399 --> 03:13:27,760
vartic function then the calling code so
4615
03:13:27,760 --> 03:13:30,439
the code that uses the sum function can
4616
03:13:30,439 --> 03:13:33,200
actually pass in kind of any number of
4617
03:13:33,200 --> 03:13:35,680
arguments and they'll come into the
4618
03:13:35,680 --> 03:13:37,880
function as a slice of integers so here
4619
03:13:37,880 --> 03:13:42,239
we could call for example sum 1 2 3 and
4620
03:13:42,239 --> 03:13:44,399
the sum function gets a slice of
4621
03:13:44,399 --> 03:13:47,560
integers with you know the values one
4622
03:13:47,560 --> 03:13:50,399
two and three in the first three indexes
4623
03:13:50,399 --> 03:13:53,200
of the slice um this means that the
4624
03:13:53,200 --> 03:13:56,520
caller could also call some one comma 2
4625
03:13:56,520 --> 03:13:58,359
right and we'd have a slice of length
4626
03:13:58,359 --> 03:14:01,080
two so it kind of just gives the collar
4627
03:14:01,080 --> 03:14:03,720
of the function a different syntax um
4628
03:14:03,720 --> 03:14:05,960
and specifically kind of a more flexible
4629
03:14:05,960 --> 03:14:08,600
syntax uh for how they're able to pass
4630
03:14:08,600 --> 03:14:11,239
in sort of a dynamic number of arguments
4631
03:14:11,239 --> 03:14:12,920
into the function now again we've
4632
03:14:12,920 --> 03:14:15,680
already been using vartic functions you
4633
03:14:15,680 --> 03:14:17,960
probably remember the print line
4634
03:14:17,960 --> 03:14:21,040
function right this is how we print text
4635
03:14:21,040 --> 03:14:25,439
to the console um it's a vartic function
4636
03:14:25,439 --> 03:14:28,960
dot dot dot interface right so it can
4637
03:14:28,960 --> 03:14:32,399
take any number of arbitrary inputs and
4638
03:14:32,399 --> 03:14:35,319
it sort of prints them all out with new
4639
03:14:35,319 --> 03:14:38,040
lines in between each element now along
4640
03:14:38,040 --> 03:14:41,319
with vartic function definitions we also
4641
03:14:41,319 --> 03:14:43,760
have another operator called the spread
4642
03:14:43,760 --> 03:14:46,040
operator and the spread operator is kind
4643
03:14:46,040 --> 03:14:47,680
of like the inverse
4644
03:14:47,680 --> 03:14:51,239
of a vartic function by using the spread
4645
03:14:51,239 --> 03:14:55,359
operator we're able to take a slice of
4646
03:14:55,359 --> 03:14:59,399
values and pass them into a vartic
4647
03:14:59,399 --> 03:15:02,279
function so this isn't the intended use
4648
03:15:02,279 --> 03:15:05,120
case 100% of the time otherwise you just
4649
03:15:05,120 --> 03:15:07,160
Define your your function to take a
4650
03:15:07,160 --> 03:15:08,560
slice of strings and you'd pass in a
4651
03:15:08,560 --> 03:15:10,800
slice of strings but if you do have a
4652
03:15:10,800 --> 03:15:13,239
function that is already vartic and you
4653
03:15:13,239 --> 03:15:16,120
want to pass in a slice as the variable
4654
03:15:16,120 --> 03:15:18,319
part then you can use this spread
4655
03:15:18,319 --> 03:15:21,120
operator this trailing dot dot dot to
4656
03:15:21,120 --> 03:15:24,960
sort of spread out in this case this
4657
03:15:24,960 --> 03:15:28,840
name slice into the vartic function
4658
03:15:28,840 --> 03:15:30,600
let's get our hands dirty with this so
4659
03:15:30,600 --> 03:15:32,600
it says we need to sum up the costs of
4660
03:15:32,600 --> 03:15:34,080
all individual messages so that we can
4661
03:15:34,080 --> 03:15:35,640
send an end of Monon Bill to our
4662
03:15:35,640 --> 03:15:38,120
customers complete the sum function so
4663
03:15:38,120 --> 03:15:40,640
that it Returns the sum of all of its
4664
03:15:40,640 --> 03:15:43,880
inputs cool so this is going to be very
4665
03:15:43,880 --> 03:15:46,160
similar to this sum function right the
4666
03:15:46,160 --> 03:15:47,760
the difference here is that we're using
4667
03:15:47,760 --> 03:15:50,080
float 64s and we're going to write it
4668
03:15:50,080 --> 03:15:52,399
from scratch uh so that we get our own
4669
03:15:52,399 --> 03:15:56,520
our own crack at it okay so first things
4670
03:15:56,520 --> 03:15:58,359
first uh let's create kind of the
4671
03:15:58,359 --> 03:16:02,880
default sum which is going to be
4672
03:16:02,880 --> 03:16:07,760
0.0.0 so uh let's say
4673
03:16:07,760 --> 03:16:11,000
total now remember we can treat nums as
4674
03:16:11,000 --> 03:16:15,279
just another slice of float 64s so 4 I
4675
03:16:15,279 --> 03:16:19,520
colon equals 0 I is less than length of
4676
03:16:19,520 --> 03:16:22,520
nums
4677
03:16:22,920 --> 03:16:25,800
i++ total plus
4678
03:16:25,800 --> 03:16:28,520
equals nums at
4679
03:16:28,520 --> 03:16:31,040
I
4680
03:16:31,040 --> 03:16:33,760
right return
4681
03:16:33,760 --> 03:16:37,439
total cool pretty straightforward um
4682
03:16:37,439 --> 03:16:40,199
let's go ahead and run
4683
03:16:41,800 --> 03:16:44,840
that so summing three costs bill for the
4684
03:16:44,840 --> 03:16:47,439
month $6
4685
03:16:47,439 --> 03:16:52,279
5 costs 15 10 costs 55 do these match up
4686
03:16:52,279 --> 03:16:55,359
looks like yep that should be
4687
03:16:55,359 --> 03:16:59,560
six 6 + 4 + 5 that's 6+ 9 that's 15 Yep
4688
03:16:59,560 --> 03:17:00,439
this is looking good I'm going to go
4689
03:17:00,439 --> 03:17:03,239
ahead and submit that now I told you
4690
03:17:03,239 --> 03:17:05,520
that resizing slices is possible we just
4691
03:17:05,520 --> 03:17:07,199
haven't really done it yet um that's
4692
03:17:07,199 --> 03:17:09,560
what the append function is for so the
4693
03:17:09,560 --> 03:17:12,120
built-in append function is actually a
4694
03:17:12,120 --> 03:17:14,239
VAR adic function but it allows us to
4695
03:17:14,239 --> 03:17:16,040
just add new things to the end of a
4696
03:17:16,040 --> 03:17:18,199
slice and automatically takes care of
4697
03:17:18,199 --> 03:17:20,080
adjusting the length and the capacity of
4698
03:17:20,080 --> 03:17:22,520
the slice accordingly right allocating
4699
03:17:22,520 --> 03:17:25,640
new underlying arrays as necessary now
4700
03:17:25,640 --> 03:17:29,000
here are your syntax options for using
4701
03:17:29,000 --> 03:17:30,880
the append function if you just want to
4702
03:17:30,880 --> 03:17:32,399
append one thing then you'll use this
4703
03:17:32,399 --> 03:17:34,120
top option let's say we have a slice
4704
03:17:34,120 --> 03:17:36,199
called slice we want to append a
4705
03:17:36,199 --> 03:17:37,920
variable called one thing to it
4706
03:17:37,920 --> 03:17:40,880
basically we call the append function we
4707
03:17:40,880 --> 03:17:43,239
pass in the slice we want to append to
4708
03:17:43,239 --> 03:17:46,120
as the first uh item we pass the
4709
03:17:46,120 --> 03:17:48,000
variable that we want to append onto the
4710
03:17:48,000 --> 03:17:50,199
end as the next thing and then we
4711
03:17:50,199 --> 03:17:54,120
reassign back into that same slice now
4712
03:17:54,120 --> 03:17:56,880
because append is a vartic function we
4713
03:17:56,880 --> 03:17:59,760
can append multiple things right so um
4714
03:17:59,760 --> 03:18:01,640
if we want to append the first thing and
4715
03:18:01,640 --> 03:18:03,680
then the second thing after that um we
4716
03:18:03,680 --> 03:18:05,319
could do it like this and obviously we
4717
03:18:05,319 --> 03:18:07,479
could also use the spread operator if we
4718
03:18:07,479 --> 03:18:10,880
want to to be 100% honest though 99% of
4719
03:18:10,880 --> 03:18:12,479
the time you'll be using this first one
4720
03:18:12,479 --> 03:18:14,000
because you'll just be appending items
4721
03:18:14,000 --> 03:18:15,479
one at a time let's hop into the
4722
03:18:15,479 --> 03:18:17,399
assignment it says we've been asked to
4723
03:18:17,399 --> 03:18:20,520
bucket costs for an entire month into
4724
03:18:20,520 --> 03:18:23,520
the costs that occurred on each day of
4725
03:18:23,520 --> 03:18:26,279
the month so complete the get cost by
4726
03:18:26,279 --> 03:18:28,199
day function it to return a slice of
4727
03:18:28,199 --> 03:18:30,319
float 64s where each element is the
4728
03:18:30,319 --> 03:18:32,239
total cost for that day okay so we have
4729
03:18:32,239 --> 03:18:34,279
like this giant list of costs and we
4730
03:18:34,279 --> 03:18:37,359
need to kind of uh condense all the
4731
03:18:37,359 --> 03:18:39,600
costs that happened on a specific day
4732
03:18:39,600 --> 03:18:43,199
into one index for that day makes sense
4733
03:18:43,199 --> 03:18:45,479
to me the length of the slice should be
4734
03:18:45,479 --> 03:18:47,279
equal to the number of days represented
4735
03:18:47,279 --> 03:18:50,239
in the costs
4736
03:18:50,239 --> 03:18:53,000
slice including any days that have no
4737
03:18:53,000 --> 03:18:55,680
costs up to the last day represented in
4738
03:18:55,680 --> 03:18:58,040
the slice Okay cool so if we have costs
4739
03:18:58,040 --> 03:19:00,560
just for say the first month or the
4740
03:19:00,560 --> 03:19:02,080
first day of the month and the fifth day
4741
03:19:02,080 --> 03:19:04,479
of the month then we should have um kind
4742
03:19:04,479 --> 03:19:07,920
of five indexes in our resulting array
4743
03:19:07,920 --> 03:19:09,720
with kind of a non-zero value in the
4744
03:19:09,720 --> 03:19:12,319
first and the fifth indexes zeros in the
4745
03:19:12,319 --> 03:19:15,399
middle and nothing after that okay here
4746
03:19:15,399 --> 03:19:18,560
we've got an example
4747
03:19:18,560 --> 03:19:23,040
um given this input so day cost so we
4748
03:19:23,040 --> 03:19:26,720
have costs on days on days 0o one and
4749
03:19:26,720 --> 03:19:30,080
five this would be the resulting array
4750
03:19:30,080 --> 03:19:34,520
right $4 on the first day 5.2 on the
4751
03:19:34,520 --> 03:19:37,399
second day because we sum those right
4752
03:19:37,399 --> 03:19:39,520
and then on that last day we'd have
4753
03:19:39,520 --> 03:19:43,239
2.5 cool let's write the
4754
03:19:43,239 --> 03:19:45,560
function so first things first we're
4755
03:19:45,560 --> 03:19:47,239
going to need
4756
03:19:47,239 --> 03:19:50,120
um we're going to need a slice to append
4757
03:19:50,120 --> 03:19:56,760
into so costs by day we'll make a new uh
4758
03:19:56,760 --> 03:20:00,199
a new slice of float 64 and here I'm
4759
03:20:00,199 --> 03:20:03,160
just using the slice literal syntax um
4760
03:20:03,160 --> 03:20:05,319
instead of the make function they're
4761
03:20:05,319 --> 03:20:07,640
pretty dang
4762
03:20:07,640 --> 03:20:09,840
similar now we're probably going to want
4763
03:20:09,840 --> 03:20:14,160
to iterate over all of the cost so for I
4764
03:20:14,160 --> 03:20:17,760
equals 0 I is less than length
4765
03:20:17,760 --> 03:20:20,760
costs
4766
03:20:24,920 --> 03:20:27,520
i++ costs at
4767
03:20:27,520 --> 03:20:32,120
I okay so a cost is this structure here
4768
03:20:32,120 --> 03:20:34,760
and we can take a look at the day
4769
03:20:34,760 --> 03:20:38,439
there um we're going to need to figure
4770
03:20:38,439 --> 03:20:41,680
out basically when we're appending to
4771
03:20:41,680 --> 03:20:45,080
this costs by day slice and when we're
4772
03:20:45,080 --> 03:20:47,960
just adding to an existing index so I
4773
03:20:47,960 --> 03:20:50,199
think the easiest thing to do would
4774
03:20:50,199 --> 03:20:51,720
basically be to
4775
03:20:51,720 --> 03:20:55,239
say um
4776
03:20:55,640 --> 03:20:59,239
if day is greater than the length of
4777
03:20:59,239 --> 03:21:02,560
costs by
4778
03:21:03,479 --> 03:21:06,760
day actually it's going to be a four so
4779
03:21:06,760 --> 03:21:09,720
like while the day is greater than the
4780
03:21:09,720 --> 03:21:11,279
length of cost by day we're going to
4781
03:21:11,279 --> 03:21:15,479
append cost by day equals append cost by
4782
03:21:15,479 --> 03:21:18,319
day
4783
03:21:18,319 --> 03:21:21,160
0.0 right so in effect this for Loop
4784
03:21:21,160 --> 03:21:25,160
here just says if I've encountered a day
4785
03:21:25,160 --> 03:21:28,160
that I don't yet have room for I'm going
4786
03:21:28,160 --> 03:21:31,600
to grow the slice by just appending
4787
03:21:31,600 --> 03:21:34,880
zeros until I have enough room so once
4788
03:21:34,880 --> 03:21:37,560
we're done with that Loop we should be
4789
03:21:37,560 --> 03:21:40,399
able to assign directly into the costs
4790
03:21:40,399 --> 03:21:41,439
by
4791
03:21:41,439 --> 03:21:44,359
day I basically saying cost by day plus
4792
03:21:44,359 --> 03:21:47,359
equals
4793
03:21:49,560 --> 03:21:51,000
cost.
4794
03:21:51,000 --> 03:21:54,279
value right because it starts at zero so
4795
03:21:54,279 --> 03:21:56,399
then we can just
4796
03:21:56,399 --> 03:22:00,760
add we just add the cost and again if if
4797
03:22:00,760 --> 03:22:02,800
the day is less than cost by day then we
4798
03:22:02,800 --> 03:22:04,760
just don't do this step we just skip
4799
03:22:04,760 --> 03:22:07,239
over this for Loop so that's looking
4800
03:22:07,239 --> 03:22:08,840
correct to me I'm going to go ahead and
4801
03:22:08,840 --> 03:22:12,319
return costs by
4802
03:22:12,319 --> 03:22:16,199
day and let's run that code see what we
4803
03:22:16,199 --> 03:22:22,080
get undefined day what did I screw up
4804
03:22:22,560 --> 03:22:27,640
here yeah needs to be cost. day right
4805
03:22:27,640 --> 03:22:28,920
access that
4806
03:22:28,920 --> 03:22:31,600
field invalid operation cost by day plus
4807
03:22:31,600 --> 03:22:34,800
equals cost. value so cost. value is a
4808
03:22:34,800 --> 03:22:35,680
float
4809
03:22:35,680 --> 03:22:38,439
64 costs by
4810
03:22:38,439 --> 03:22:42,800
day is a slice of flow
4811
03:22:42,800 --> 03:22:45,600
64s right because this is a slice so
4812
03:22:45,600 --> 03:22:47,040
costs by
4813
03:22:47,040 --> 03:22:50,040
a
4814
03:22:51,479 --> 03:22:54,560
at at cost.
4815
03:22:54,560 --> 03:22:57,560
day
4816
03:22:57,800 --> 03:23:00,239
right right because our the slice that
4817
03:23:00,239 --> 03:23:00,960
we're
4818
03:23:00,960 --> 03:23:05,600
returning um the indexes in each or the
4819
03:23:05,600 --> 03:23:07,239
indexes of the slice represent each day
4820
03:23:07,239 --> 03:23:09,080
in the month so we need to index back
4821
03:23:09,080 --> 03:23:10,399
into the
4822
03:23:10,399 --> 03:23:14,319
day okay try
4823
03:23:14,319 --> 03:23:18,080
that whoa what do we got
4824
03:23:18,080 --> 03:23:20,199
Panic runtime error index out of range
4825
03:23:20,199 --> 03:23:21,960
zero with length
4826
03:23:21,960 --> 03:23:24,000
zero
4827
03:23:24,000 --> 03:23:26,760
okay what did we screw
4828
03:23:26,760 --> 03:23:29,760
up
4829
03:23:30,439 --> 03:23:36,000
so somewhere we are indexing into a
4830
03:23:36,000 --> 03:23:39,680
slice where the value doesn't like the
4831
03:23:39,680 --> 03:23:41,479
the the index that we're indexing with
4832
03:23:41,479 --> 03:23:43,560
is outside the range of the slice so um
4833
03:23:43,560 --> 03:23:45,000
we haven't really talked about this this
4834
03:23:45,000 --> 03:23:46,680
is probably great that we ran into this
4835
03:23:46,680 --> 03:23:51,880
bug um if you try to index which is this
4836
03:23:51,880 --> 03:23:53,920
operation here so like this is indexing
4837
03:23:53,920 --> 03:23:55,960
into index five right but here we're
4838
03:23:55,960 --> 03:23:58,640
indexing into cost. day which holds an
4839
03:23:58,640 --> 03:24:01,680
integer um if you try to index into an
4840
03:24:01,680 --> 03:24:04,279
index that is outside the length of the
4841
03:24:04,279 --> 03:24:06,399
slice so you have a slice of length say
4842
03:24:06,399 --> 03:24:09,960
three and you try to access index six
4843
03:24:09,960 --> 03:24:11,920
then you'll encounter this error that
4844
03:24:11,920 --> 03:24:14,439
that's what we're seeing here so it
4845
03:24:14,439 --> 03:24:17,080
looks like that's what we are doing
4846
03:24:17,080 --> 03:24:21,479
so for cost. day is greater than the
4847
03:24:21,479 --> 03:24:24,560
length now let's think about that if the
4848
03:24:24,560 --> 03:24:29,120
day is five and the length is
4849
03:24:29,120 --> 03:24:33,120
five we are not going to do our growth
4850
03:24:33,120 --> 03:24:35,160
so I'm actually I think I have an off by
4851
03:24:35,160 --> 03:24:38,239
one error here right I actually what I
4852
03:24:38,239 --> 03:24:42,040
actually want to do is say if the cost
4853
03:24:42,040 --> 03:24:44,239
if the if the cost. day is greater than
4854
03:24:44,239 --> 03:24:48,800
or equal to the length right because an
4855
03:24:48,800 --> 03:24:52,359
array or a slice of length four actually
4856
03:24:52,359 --> 03:24:54,160
only has
4857
03:24:54,160 --> 03:24:57,160
three um kind of indexes I mean it has
4858
03:24:57,160 --> 03:24:59,040
four indexes but they start at zero so
4859
03:24:59,040 --> 03:25:01,720
like length four the indexes are 0 1 2
4860
03:25:01,720 --> 03:25:04,160
and three right let's go ahead and run
4861
03:25:04,160 --> 03:25:05,680
that
4862
03:25:05,680 --> 03:25:10,199
again cool no more
4863
03:25:11,040 --> 03:25:15,479
Panic day one $1 or day Zero $1 day one
4864
03:25:15,479 --> 03:25:19,319
510 day 2 250 let's see if that lines up
4865
03:25:19,319 --> 03:25:21,840
with the test
4866
03:25:23,960 --> 03:25:26,439
Suite so here it looks like Day Zero
4867
03:25:26,439 --> 03:25:29,640
should have one day one should have yep
4868
03:25:29,640 --> 03:25:32,479
5.1 if we add those together and day 3
4869
03:25:32,479 --> 03:25:35,880
should have 5 point what's that
4870
03:25:35,880 --> 03:25:39,319
6.3 yep 6.3 okay this is looking correct
4871
03:25:39,319 --> 03:25:40,520
to
4872
03:25:40,520 --> 03:25:44,199
me slices can hold other slices right
4873
03:25:44,199 --> 03:25:48,880
this kind of creates a 2d Matrix um of
4874
03:25:48,880 --> 03:25:52,800
values right so for example here a 10x10
4875
03:25:52,800 --> 03:25:54,760
Matrix of integers would look something
4876
03:25:54,760 --> 03:25:57,720
like this where the First Slice is just
4877
03:25:57,720 --> 03:26:01,560
a slice of slices hopefully that makes
4878
03:26:01,560 --> 03:26:03,680
some amount of sense if not don't worry
4879
03:26:03,680 --> 03:26:05,439
we'll get into the assignment here in
4880
03:26:05,439 --> 03:26:07,800
just a second so it says we support
4881
03:26:07,800 --> 03:26:10,080
various graphs and dashboards on Tex
4882
03:26:10,080 --> 03:26:11,760
that display message analytics for our
4883
03:26:11,760 --> 03:26:14,080
users the UI for our graphs and charts
4884
03:26:14,080 --> 03:26:16,359
is built on top of a grid system let's
4885
03:26:16,359 --> 03:26:18,239
build that grid logic so this is super
4886
03:26:18,239 --> 03:26:19,880
common in graphics development right
4887
03:26:19,880 --> 03:26:22,239
we're kind of building on 2D screens so
4888
03:26:22,239 --> 03:26:25,720
we need sort of an X and A Y um cell
4889
03:26:25,720 --> 03:26:27,920
within a matrix which is again often
4890
03:26:27,920 --> 03:26:30,600
represented as a slice of slices the
4891
03:26:30,600 --> 03:26:32,520
assignment says complete the create
4892
03:26:32,520 --> 03:26:34,479
Matrix function it takes a number of
4893
03:26:34,479 --> 03:26:36,960
rows and columns and returns a 2d slice
4894
03:26:36,960 --> 03:26:38,600
of integers where the value of each cell
4895
03:26:38,600 --> 03:26:42,160
is I * J where I and J are the indexes
4896
03:26:42,160 --> 03:26:44,640
of the row and column
4897
03:26:44,640 --> 03:26:47,960
respectively okay cool so create Matrix
4898
03:26:47,960 --> 03:26:50,520
we get two integers representing how big
4899
03:26:50,520 --> 03:26:52,000
we want the Matrix to be and we just
4900
03:26:52,000 --> 03:26:55,680
have to return the Matrix Okay
4901
03:26:55,680 --> 03:26:57,439
cool
4902
03:26:57,439 --> 03:27:00,279
so let's go ahead and start building
4903
03:27:00,279 --> 03:27:03,840
that out first we need to create um or
4904
03:27:03,840 --> 03:27:07,319
initialize the Matrix so let's say
4905
03:27:07,319 --> 03:27:10,800
Matrix slice let's use make make slice
4906
03:27:10,800 --> 03:27:13,000
slice
4907
03:27:13,000 --> 03:27:16,520
in right and we can just initialize it
4908
03:27:16,520 --> 03:27:18,520
to a length of zero it doesn't matter
4909
03:27:18,520 --> 03:27:22,680
we're going to grow it and four I col
4910
03:27:22,680 --> 03:27:27,359
equals 0 I is less than length of
4911
03:27:27,359 --> 03:27:30,120
rows
4912
03:27:30,120 --> 03:27:31,960
i++ and then we're going to need an
4913
03:27:31,960 --> 03:27:33,600
inner for
4914
03:27:33,600 --> 03:27:38,199
Loop manage J which is going
4915
03:27:38,199 --> 03:27:41,640
to deal with the number of columns
4916
03:27:41,640 --> 03:27:43,840
columns
4917
03:27:43,840 --> 03:27:47,160
j++ okay so what do we do
4918
03:27:47,160 --> 03:27:49,199
um when we get to the first row well the
4919
03:27:49,199 --> 03:27:52,199
first thing we need to do is make a new
4920
03:27:52,199 --> 03:27:56,439
slice to represent the row so we'll say
4921
03:27:56,439 --> 03:27:59,960
row make and we can just
4922
03:27:59,960 --> 03:28:04,439
do a a single slice of integers again
4923
03:28:04,439 --> 03:28:08,800
row uh length of Zer is fine um we could
4924
03:28:08,800 --> 03:28:11,040
pre-allocate but it probably doesn't
4925
03:28:11,040 --> 03:28:12,680
matter too much at this
4926
03:28:12,680 --> 03:28:17,080
point um and then for each J a we're now
4927
03:28:17,080 --> 03:28:19,040
going to append into the row so we do
4928
03:28:19,040 --> 03:28:22,680
row equals
4929
03:28:22,680 --> 03:28:24,199
append
4930
03:28:24,199 --> 03:28:28,040
row I * J I believe was the formula
4931
03:28:28,040 --> 03:28:31,760
right we want every cell to be the
4932
03:28:31,760 --> 03:28:35,399
result of I * J so the values will sort
4933
03:28:35,399 --> 03:28:38,199
of grow out um as the Matrix gets larger
4934
03:28:38,199 --> 03:28:39,600
and
4935
03:28:39,600 --> 03:28:42,880
larger cool so that's adding the like
4936
03:28:42,880 --> 03:28:46,520
this inner loop is adding values to each
4937
03:28:46,520 --> 03:28:48,800
individual row and then we just need to
4938
03:28:48,800 --> 03:28:51,000
append the row to The Matrix so
4939
03:28:51,000 --> 03:28:55,359
Matrix equals append
4940
03:28:55,359 --> 03:28:57,000
Matrix
4941
03:28:57,000 --> 03:28:59,120
row and then when we're done appending
4942
03:28:59,120 --> 03:29:00,560
all of the rows to The Matrix we can
4943
03:29:00,560 --> 03:29:03,160
return the Matrix
4944
03:29:03,160 --> 03:29:06,000
itself go aad and run
4945
03:29:06,000 --> 03:29:08,840
that invalid argument row variable of
4946
03:29:08,840 --> 03:29:12,840
type int for length see what we got
4947
03:29:12,840 --> 03:29:16,840
here where did I screw up
4948
03:29:16,840 --> 03:29:19,160
this time
4949
03:29:19,160 --> 03:29:21,600
right I don't know why I'm checking a
4950
03:29:21,600 --> 03:29:25,880
length here Rose is just an integer it's
4951
03:29:25,880 --> 03:29:31,279
not a slice with a size let's try that
4952
03:29:32,040 --> 03:29:35,120
again cool creating a 3X3
4953
03:29:35,120 --> 03:29:37,880
Matrix does that math check
4954
03:29:37,880 --> 03:29:43,279
out 1 * 1 is 1 1 * 2 is 2 2 * 2 is 4 yep
4955
03:29:43,279 --> 03:29:47,399
that looks good cool let's submit it I
4956
03:29:47,399 --> 03:29:49,760
want to show you a common Pitfall that
4957
03:29:49,760 --> 03:29:52,160
you might fall into uh when dealing with
4958
03:29:52,160 --> 03:29:53,479
slices and how you can just outright
4959
03:29:53,479 --> 03:29:57,239
avoid it um this is something you should
4960
03:29:57,239 --> 03:30:00,359
pretty much never do when you want to
4961
03:30:00,359 --> 03:30:04,199
append to um other slice in this case
4962
03:30:04,199 --> 03:30:06,319
you want to append elements to other
4963
03:30:06,319 --> 03:30:09,600
slice you should always reassign into
4964
03:30:09,600 --> 03:30:12,279
the same slice so this should read other
4965
03:30:12,279 --> 03:30:15,199
slice equals append other slice element
4966
03:30:15,199 --> 03:30:17,680
you don't want to be pending um kind of
4967
03:30:17,680 --> 03:30:20,680
into one thing and reassigning into a
4968
03:30:20,680 --> 03:30:23,279
separate slice you'll run into some bugs
4969
03:30:23,279 --> 03:30:24,720
and we're going to talk about how that
4970
03:30:24,720 --> 03:30:27,560
works right now so in this first example
4971
03:30:27,560 --> 03:30:31,600
we have these slices a b and c and by
4972
03:30:31,600 --> 03:30:33,319
the way I would highly recommend coming
4973
03:30:33,319 --> 03:30:35,239
here on bootd so that you can actually
4974
03:30:35,239 --> 03:30:37,120
kind of look and puzzle through what's
4975
03:30:37,120 --> 03:30:38,760
going on in the code rather than just
4976
03:30:38,760 --> 03:30:41,319
seeing it on the screen um but basically
4977
03:30:41,319 --> 03:30:44,800
we have these slices and when we append
4978
03:30:44,800 --> 03:30:46,439
to them
4979
03:30:46,439 --> 03:30:48,680
we're we're breaking the rule basically
4980
03:30:48,680 --> 03:30:52,239
we're uh appending for example here um
4981
03:30:52,239 --> 03:30:56,199
four onto a but then returning the
4982
03:30:56,199 --> 03:30:59,120
value the value returned by a pend we're
4983
03:30:59,120 --> 03:31:00,760
kind of saving it into a new slice
4984
03:31:00,760 --> 03:31:02,720
called B which again you you generally
4985
03:31:02,720 --> 03:31:04,319
should not do you should just save it
4986
03:31:04,319 --> 03:31:08,120
back into the same slice a um but
4987
03:31:08,120 --> 03:31:09,960
anyways we're going along um kind of
4988
03:31:09,960 --> 03:31:13,399
doing that pattern and at the end you'll
4989
03:31:13,399 --> 03:31:15,439
notice that nothing too terrible
4990
03:31:15,439 --> 03:31:18,000
happened um basically we ended up with
4991
03:31:18,000 --> 03:31:20,800
an a with three zeros B had four
4992
03:31:20,800 --> 03:31:24,880
appended to it properly and C had five
4993
03:31:24,880 --> 03:31:26,560
appended to it properly so you could
4994
03:31:26,560 --> 03:31:28,359
kind of take away from this example well
4995
03:31:28,359 --> 03:31:30,319
maybe there's nothing wrong maybe we can
4996
03:31:30,319 --> 03:31:33,680
just kind of uh break the rule and
4997
03:31:33,680 --> 03:31:36,000
append into new slices seems like
4998
03:31:36,000 --> 03:31:37,960
everything's working like I'd expect and
4999
03:31:37,960 --> 03:31:39,880
it's worth pointing out that we can even
5000
03:31:39,880 --> 03:31:43,800
print out the addresses in memory of the
5001
03:31:43,800 --> 03:31:47,319
slices B and C and see the addresses are
5002
03:31:47,319 --> 03:31:49,680
different in other words when we called
5003
03:31:49,680 --> 03:31:51,880
this append functions where we append
5004
03:31:51,880 --> 03:31:57,199
five onto um you know the slice a and
5005
03:31:57,199 --> 03:31:59,760
save it back into the variable C we can
5006
03:31:59,760 --> 03:32:01,560
see that actually C is being kind of
5007
03:32:01,560 --> 03:32:04,359
copied into a new location so again
5008
03:32:04,359 --> 03:32:06,120
everything's kind of working as we'd
5009
03:32:06,120 --> 03:32:08,439
expect now it's really in this example
5010
03:32:08,439 --> 03:32:12,439
two that something very strange happens
5011
03:32:12,439 --> 03:32:14,000
if we look
5012
03:32:14,000 --> 03:32:17,680
down here we're a pending onto
5013
03:32:17,680 --> 03:32:21,279
J the value four and then we're
5014
03:32:21,279 --> 03:32:26,720
appending onto G here the value five but
5015
03:32:26,720 --> 03:32:29,359
the interesting thing is that after we
5016
03:32:29,359 --> 03:32:33,520
append five to G if we print out J again
5017
03:32:33,520 --> 03:32:36,520
we can see that J was actually changed
5018
03:32:36,520 --> 03:32:40,319
kind of under the hood right up here J
5019
03:32:40,319 --> 03:32:43,399
had four in its fourth
5020
03:32:43,399 --> 03:32:46,279
index and then we never touched J again
5021
03:32:46,279 --> 03:32:49,399
directly but by appending onto G we
5022
03:32:49,399 --> 03:32:53,600
actually screwed up J we mutated J and
5023
03:32:53,600 --> 03:32:55,920
the reason for that is because in this
5024
03:32:55,920 --> 03:32:57,479
example because of the way we've
5025
03:32:57,479 --> 03:33:01,399
sloppily used the append function G and
5026
03:33:01,399 --> 03:33:04,439
J actually point to the same address in
5027
03:33:04,439 --> 03:33:09,880
memory so mutating G changed J now I
5028
03:33:09,880 --> 03:33:11,520
already mentioned that we were doing the
5029
03:33:11,520 --> 03:33:13,760
same thing up here right we were using
5030
03:33:13,760 --> 03:33:15,960
the same kind of sloppy use of the a
5031
03:33:15,960 --> 03:33:17,840
pend function that I'm recommending to
5032
03:33:17,840 --> 03:33:20,800
avoid but we only had the bug in example
5033
03:33:20,800 --> 03:33:24,080
two and the reason for that is because
5034
03:33:24,080 --> 03:33:27,279
the original slice in example two has a
5035
03:33:27,279 --> 03:33:28,560
capacity of
5036
03:33:28,560 --> 03:33:31,920
eight while the original slice in
5037
03:33:31,920 --> 03:33:34,880
example one had a capacity of three so
5038
03:33:34,880 --> 03:33:37,520
what that means is when we used the
5039
03:33:37,520 --> 03:33:40,520
append function in the first example
5040
03:33:40,520 --> 03:33:42,680
once we went over the capacity we
5041
03:33:42,680 --> 03:33:44,960
allocated a new underlying array which
5042
03:33:44,960 --> 03:33:47,560
is why we got different memory addresses
5043
03:33:47,560 --> 03:33:50,800
and so when we mutate C here C is in a
5044
03:33:50,800 --> 03:33:53,120
different place in memory than b so
5045
03:33:53,120 --> 03:33:55,199
they're kind of operating independently
5046
03:33:55,199 --> 03:33:57,160
which is again what you usually want in
5047
03:33:57,160 --> 03:33:58,560
your
5048
03:33:58,560 --> 03:34:01,359
code however because the capacity was
5049
03:34:01,359 --> 03:34:03,720
already large enough in example two
5050
03:34:03,720 --> 03:34:06,000
there was no need for the append
5051
03:34:06,000 --> 03:34:07,520
function to create a new underlying
5052
03:34:07,520 --> 03:34:11,560
array so G and J point to the same the
5053
03:34:11,560 --> 03:34:14,760
same array in memory again which means
5054
03:34:14,760 --> 03:34:17,000
if we mutate G under the hood we just
5055
03:34:17,000 --> 03:34:20,399
mutating J so again the way you can
5056
03:34:20,399 --> 03:34:22,479
avoid all of this
5057
03:34:22,479 --> 03:34:26,359
headache is to just not do this right
5058
03:34:26,359 --> 03:34:30,040
append onto the same slice pretty much
5059
03:34:30,040 --> 03:34:32,279
every time unless you have like some
5060
03:34:32,279 --> 03:34:35,080
crazy specific reason not to do so which
5061
03:34:35,080 --> 03:34:37,680
like I'm skeptical that exists I
5062
03:34:37,680 --> 03:34:39,800
certainly haven't run into it in you
5063
03:34:39,800 --> 03:34:41,600
know many years of writing application
5064
03:34:41,600 --> 03:34:45,359
code in go so the question for this quiz
5065
03:34:45,359 --> 03:34:48,319
is why is five the final value in the
5066
03:34:48,319 --> 03:34:52,439
last index of array J right so why why
5067
03:34:52,439 --> 03:34:54,399
did we have a five here even though we
5068
03:34:54,399 --> 03:34:57,600
appended for um and the answers are J
5069
03:34:57,600 --> 03:34:59,880
and G point to the same underlying array
5070
03:34:59,880 --> 03:35:02,359
so G is aend over OJ the go team is
5071
03:35:02,359 --> 03:35:04,960
trolling I think that's obviously not it
5072
03:35:04,960 --> 03:35:06,359
uh and because a pend only works
5073
03:35:06,359 --> 03:35:07,640
properly when the number of elements is
5074
03:35:07,640 --> 03:35:09,800
less than 10 uh that would be very silly
5075
03:35:09,800 --> 03:35:12,680
so it's it's definitely this middle one
5076
03:35:12,680 --> 03:35:15,120
we're overwriting the same location in
5077
03:35:15,120 --> 03:35:17,520
memory next question on the same topic
5078
03:35:17,520 --> 03:35:19,840
is why doesn't the bug regarding slices
5079
03:35:19,840 --> 03:35:23,880
J and G in example two occur in example
5080
03:35:23,880 --> 03:35:26,920
one as well and the the answers are
5081
03:35:26,920 --> 03:35:28,279
because there are fewer elements and
5082
03:35:28,279 --> 03:35:29,920
goes runtime can't handle more than
5083
03:35:29,920 --> 03:35:32,920
eight elements that would be awful um or
5084
03:35:32,920 --> 03:35:34,800
the array's cap is exceeded so a new
5085
03:35:34,800 --> 03:35:36,920
underlying array is allocated and and
5086
03:35:36,920 --> 03:35:39,000
that one is the answer so the next
5087
03:35:39,000 --> 03:35:41,239
question is how can you best avoid these
5088
03:35:41,239 --> 03:35:43,560
types of bugs don't use the append
5089
03:35:43,560 --> 03:35:45,399
function always assign the result of the
5090
03:35:45,399 --> 03:35:46,880
append pend function back into the same
5091
03:35:46,880 --> 03:35:49,120
slice or always assign the result of the
5092
03:35:49,120 --> 03:35:52,000
append function to a new slice well it's
5093
03:35:52,000 --> 03:35:53,920
not using a new slice that's how we got
5094
03:35:53,920 --> 03:35:55,680
into this trouble in the first place and
5095
03:35:55,680 --> 03:35:57,120
we definitely want to use the append
5096
03:35:57,120 --> 03:35:59,640
function it's pretty useful so again
5097
03:35:59,640 --> 03:36:01,479
always assign the result of the append
5098
03:36:01,479 --> 03:36:04,199
function back into the same slice you'll
5099
03:36:04,199 --> 03:36:06,439
avoid a lot of headache that way finally
5100
03:36:06,439 --> 03:36:09,399
some syntactic sugar to help us iterate
5101
03:36:09,399 --> 03:36:11,760
over the elements of a slice you've
5102
03:36:11,760 --> 03:36:13,640
probably been wondering for the majority
5103
03:36:13,640 --> 03:36:15,880
of this chapter uh do I have to do this
5104
03:36:15,880 --> 03:36:18,720
I equals z i is less than the length
5105
03:36:18,720 --> 03:36:20,120
every time I want to iterate over the
5106
03:36:20,120 --> 03:36:22,000
elements of the slice other languages
5107
03:36:22,000 --> 03:36:24,160
have syntactic sugar to make it easier
5108
03:36:24,160 --> 03:36:26,840
so does go so the syntax is pretty
5109
03:36:26,840 --> 03:36:29,439
simple um this is it right here and
5110
03:36:29,439 --> 03:36:31,960
basically by writing it this way index
5111
03:36:31,960 --> 03:36:33,800
at each iteration of the loop will be
5112
03:36:33,800 --> 03:36:35,680
equal to the index in the loop starting
5113
03:36:35,680 --> 03:36:38,560
at zero right so 0 1 2 3 and then
5114
03:36:38,560 --> 03:36:41,000
element is the value associated with
5115
03:36:41,000 --> 03:36:42,560
that Index right and then obviously
5116
03:36:42,560 --> 03:36:44,840
slice here is the name of the slice so
5117
03:36:44,840 --> 03:36:46,040
range is a real
5118
03:36:46,040 --> 03:36:48,120
the interesting keyword that allows us
5119
03:36:48,120 --> 03:36:50,359
to iterate over everything stored in a
5120
03:36:50,359 --> 03:36:53,399
slice to give a more concrete example
5121
03:36:53,399 --> 03:36:55,439
here we have a slice of strings called
5122
03:36:55,439 --> 03:36:57,880
fruits and we can arrange over the
5123
03:36:57,880 --> 03:37:01,319
fruits and if we print I and fruit in
5124
03:37:01,319 --> 03:37:04,319
this example that we print zero apple
5125
03:37:04,319 --> 03:37:07,840
one banana two grape and so on let's
5126
03:37:07,840 --> 03:37:09,800
jump into the assignment it says we need
5127
03:37:09,800 --> 03:37:12,080
to be able to quickly detect bad words
5128
03:37:12,080 --> 03:37:14,439
in the messages that our system sends
5129
03:37:14,439 --> 03:37:15,840
complete the index of first first bad
5130
03:37:15,840 --> 03:37:18,880
word function okay so that's this um it
5131
03:37:18,880 --> 03:37:20,960
finds any bad words in the message if it
5132
03:37:20,960 --> 03:37:22,800
finds any bad words in the message it
5133
03:37:22,800 --> 03:37:25,239
should return the index of the first bad
5134
03:37:25,239 --> 03:37:27,160
word in the message slice this will help
5135
03:37:27,160 --> 03:37:29,040
us filter out naughty words uh from our
5136
03:37:29,040 --> 03:37:30,560
messaging system if no bad words are
5137
03:37:30,560 --> 03:37:32,439
found will return negative one instead
5138
03:37:32,439 --> 03:37:34,199
use the range
5139
03:37:34,199 --> 03:37:37,399
keyword Okay cool so the bad words
5140
03:37:37,399 --> 03:37:39,520
themselves are defined for us and passed
5141
03:37:39,520 --> 03:37:41,560
into our function and then the message
5142
03:37:41,560 --> 03:37:44,199
itself is already broken up into words
5143
03:37:44,199 --> 03:37:46,239
it looks like and passed in is an array
5144
03:37:46,239 --> 03:37:48,239
of strings right so we can I'm kind of
5145
03:37:48,239 --> 03:37:50,319
just figuring this out by looking uh
5146
03:37:50,319 --> 03:37:52,520
looking down here so we have a slice of
5147
03:37:52,520 --> 03:37:55,720
bad words and a slice of words in the
5148
03:37:55,720 --> 03:37:59,680
message hey there John Okay
5149
03:37:59,680 --> 03:38:03,600
cool so um let's
5150
03:38:03,600 --> 03:38:07,199
start by iterating over all of the words
5151
03:38:07,199 --> 03:38:08,960
in the message right seems like a
5152
03:38:08,960 --> 03:38:12,239
reasonable place to start so
5153
03:38:12,239 --> 03:38:19,680
for I word colon equals range
5154
03:38:19,680 --> 03:38:22,479
message and then we want to check and
5155
03:38:22,479 --> 03:38:25,479
see
5156
03:38:25,479 --> 03:38:29,399
if if one of these words is equal to one
5157
03:38:29,399 --> 03:38:30,960
of the bad words so we're going to use a
5158
03:38:30,960 --> 03:38:33,840
nested Loop
5159
03:38:33,840 --> 03:38:36,479
actually we'll do
5160
03:38:36,479 --> 03:38:40,760
J bad word in range bad
5161
03:38:40,760 --> 03:38:44,399
words right and then here we can say if
5162
03:38:44,399 --> 03:38:47,640
word equals equals bad
5163
03:38:47,640 --> 03:38:50,560
word that means we found the bad word
5164
03:38:50,560 --> 03:38:52,239
and we can
5165
03:38:52,239 --> 03:38:54,880
return we want to return the index so we
5166
03:38:54,880 --> 03:38:57,920
return I right that would be the index
5167
03:38:57,920 --> 03:38:59,279
of the bad
5168
03:38:59,279 --> 03:39:01,560
word otherwise if we don't find a bad
5169
03:39:01,560 --> 03:39:03,760
word we'll just keep going um in fact
5170
03:39:03,760 --> 03:39:04,720
we'll just keep going through all the
5171
03:39:04,720 --> 03:39:05,680
bad words and then we'll keep going
5172
03:39:05,680 --> 03:39:07,399
through all the rest of the
5173
03:39:07,399 --> 03:39:09,439
words and if we get to the end of
5174
03:39:09,439 --> 03:39:11,239
everything without finding any matches
5175
03:39:11,239 --> 03:39:13,279
then we can just return negative
5176
03:39:13,279 --> 03:39:16,760
1 makes sense right
5177
03:39:16,760 --> 03:39:18,760
cool let's run
5178
03:39:18,760 --> 03:39:23,199
that J declared not used right um so
5179
03:39:23,199 --> 03:39:24,880
we've come across this syntax before we
5180
03:39:24,880 --> 03:39:27,319
can ignore variables with an underscore
5181
03:39:27,319 --> 03:39:30,399
right let's run
5182
03:39:30,399 --> 03:39:33,000
that let's take a look at our test Suite
5183
03:39:33,000 --> 03:39:35,319
scanning message hey there John for bad
5184
03:39:35,319 --> 03:39:39,080
words index negative one that means none
5185
03:39:39,080 --> 03:39:42,040
were found right which makes sense we
5186
03:39:42,040 --> 03:39:44,720
didn't have any scanning message uh oh
5187
03:39:44,720 --> 03:39:47,479
my freck for bad words brick is a bad
5188
03:39:47,479 --> 03:39:50,040
word index 3 okay this is looking good
5189
03:39:50,040 --> 03:39:52,800
to me I'm going to go ahead and submit
5190
03:39:52,800 --> 03:39:55,279
that if you're familiar with object
5191
03:39:55,279 --> 03:39:57,720
literals in JavaScript or python
5192
03:39:57,720 --> 03:39:59,880
dictionaries then maps and go are
5193
03:39:59,880 --> 03:40:01,760
essentially the same thing maps are just
5194
03:40:01,760 --> 03:40:05,199
a way to associate a key with a value so
5195
03:40:05,199 --> 03:40:07,600
let's take a look at this example we
5196
03:40:07,600 --> 03:40:10,760
create a new map with this syntax here
5197
03:40:10,760 --> 03:40:12,800
we're going to use this built-in make
5198
03:40:12,800 --> 03:40:14,960
function and then pass in the type of
5199
03:40:14,960 --> 03:40:18,279
the map so map of string to integer so
5200
03:40:18,279 --> 03:40:21,520
we're mapping strings to integers and
5201
03:40:21,520 --> 03:40:23,479
we're going to say inside of the ages
5202
03:40:23,479 --> 03:40:27,239
map we're going to set the key John to
5203
03:40:27,239 --> 03:40:31,040
the integer 37 so again we're mapping
5204
03:40:31,040 --> 03:40:34,120
that name John to the value 37 rather
5205
03:40:34,120 --> 03:40:36,640
than creating an empty map and then kind
5206
03:40:36,640 --> 03:40:39,120
of adding key value pairs one at a time
5207
03:40:39,120 --> 03:40:41,439
we can also declare the entire map up
5208
03:40:41,439 --> 03:40:43,640
front and use kind of this colon syntax
5209
03:40:43,640 --> 03:40:45,800
to separate the keys and the values
5210
03:40:45,800 --> 03:40:49,000
and then we can also check how many keys
5211
03:40:49,000 --> 03:40:51,439
I guess keys and values are in the map
5212
03:40:51,439 --> 03:40:53,920
by using the built-in length function
5213
03:40:53,920 --> 03:40:55,600
similarly to how you would use it on a
5214
03:40:55,600 --> 03:40:58,359
slice um so in this case we create a new
5215
03:40:58,359 --> 03:41:00,840
map we create two keys each with their
5216
03:41:00,840 --> 03:41:02,640
Associated values and then by printing
5217
03:41:02,640 --> 03:41:04,160
the length we'll just print the number
5218
03:41:04,160 --> 03:41:06,000
two so let's jump right into the
5219
03:41:06,000 --> 03:41:08,080
assignment that's usually the best way
5220
03:41:08,080 --> 03:41:10,040
um to get an idea for how all the syntax
5221
03:41:10,040 --> 03:41:12,399
Works assignment says we can speed up
5222
03:41:12,399 --> 03:41:15,000
our contact info lookups by using a map
5223
03:41:15,000 --> 03:41:17,800
look up a value in a map by its key is
5224
03:41:17,800 --> 03:41:19,640
much faster than searching through a
5225
03:41:19,640 --> 03:41:22,359
slice so when we look up something in a
5226
03:41:22,359 --> 03:41:25,080
map by a given key that's going to be an
5227
03:41:25,080 --> 03:41:26,399
instant
5228
03:41:26,399 --> 03:41:29,000
lookup if we had stored it in a slice
5229
03:41:29,000 --> 03:41:30,520
then we'd have to search through the
5230
03:41:30,520 --> 03:41:32,840
entire slice sort of index by index
5231
03:41:32,840 --> 03:41:35,279
looking for the value that we want so
5232
03:41:35,279 --> 03:41:37,359
Maps can be a great way to make our code
5233
03:41:37,359 --> 03:41:38,359
more
5234
03:41:38,359 --> 03:41:40,399
efficient the assignment says complete
5235
03:41:40,399 --> 03:41:42,239
the get user map function it takes a
5236
03:41:42,239 --> 03:41:43,960
slice of names and a slice of phone
5237
03:41:43,960 --> 03:41:46,120
numbers and returns a map of of name to
5238
03:41:46,120 --> 03:41:49,080
user structs and potentially an error
5239
03:41:49,080 --> 03:41:53,040
okay so let me expand our coding window
5240
03:41:53,040 --> 03:41:55,199
here okay so we're returning a map of
5241
03:41:55,199 --> 03:41:56,840
string to user structs looks like the
5242
03:41:56,840 --> 03:41:59,600
user struct is defined right here if the
5243
03:41:59,600 --> 03:42:01,399
length of names and phone numbers is not
5244
03:42:01,399 --> 03:42:02,680
equal return error with the string
5245
03:42:02,680 --> 03:42:04,600
invalid sizes the first name in the name
5246
03:42:04,600 --> 03:42:07,439
slice matches the first number and so on
5247
03:42:07,439 --> 03:42:09,640
Okay cool so first things first we're
5248
03:42:09,640 --> 03:42:11,560
going to have to create a new map so
5249
03:42:11,560 --> 03:42:16,279
we'll do um user map
5250
03:42:16,279 --> 03:42:18,640
colon equals and I'm just going to
5251
03:42:18,640 --> 03:42:21,359
create a literal a new map literal
5252
03:42:21,359 --> 03:42:22,800
actually no I won't I'll do I'll use the
5253
03:42:22,800 --> 03:42:25,520
syntax from up here this works just fine
5254
03:42:25,520 --> 03:42:28,640
so we'll use the make function so make
5255
03:42:28,640 --> 03:42:31,640
map of string to
5256
03:42:31,640 --> 03:42:35,120
user right so that's now an empty
5257
03:42:35,120 --> 03:42:37,720
map and then what we're going to do is
5258
03:42:37,720 --> 03:42:38,880
check and make sure that these are the
5259
03:42:38,880 --> 03:42:42,800
same length so if the length of names
5260
03:42:42,800 --> 03:42:45,680
does not equal the length
5261
03:42:45,680 --> 03:42:48,239
of phone
5262
03:42:48,359 --> 03:42:52,040
numbers then we'll return nil so nil is
5263
03:42:52,040 --> 03:42:54,680
the zero value of a
5264
03:42:54,680 --> 03:42:57,760
map we could also return an empty map of
5265
03:42:57,760 --> 03:42:59,640
the same type but I'd say you should
5266
03:42:59,640 --> 03:43:02,199
prefer nil um for slices and maps and
5267
03:43:02,199 --> 03:43:04,279
things um and then the
5268
03:43:04,279 --> 03:43:06,920
error should say invalid sizes so
5269
03:43:06,920 --> 03:43:09,960
errors. new
5270
03:43:09,960 --> 03:43:12,000
invalid
5271
03:43:12,000 --> 03:43:16,760
sizes we'll import the errors package
5272
03:43:16,760 --> 03:43:18,800
Okay cool so if we get down to line 13
5273
03:43:18,800 --> 03:43:20,439
now we should know that both of these
5274
03:43:20,439 --> 03:43:22,760
slices names and phone numbers are of
5275
03:43:22,760 --> 03:43:25,640
the same size which means we can Loop um
5276
03:43:25,640 --> 03:43:29,199
like this so four I starting at zero and
5277
03:43:29,199 --> 03:43:31,479
I is less than the length of it doesn't
5278
03:43:31,479 --> 03:43:32,840
matter because they'll be the same right
5279
03:43:32,840 --> 03:43:34,080
length of
5280
03:43:34,080 --> 03:43:36,479
names
5281
03:43:36,479 --> 03:43:38,640
i++ then we can say
5282
03:43:38,640 --> 03:43:43,040
name is names at
5283
03:43:43,040 --> 03:43:47,199
I and we can say fun phone
5284
03:43:47,199 --> 03:43:50,040
number phone
5285
03:43:50,040 --> 03:43:52,760
numbers at
5286
03:43:52,760 --> 03:43:54,560
I
5287
03:43:54,560 --> 03:43:56,720
okay and then we're going to want to
5288
03:43:56,720 --> 03:43:58,760
insert values into the user map so we'll
5289
03:43:58,760 --> 03:44:04,000
do user map at the key in this case the
5290
03:44:04,000 --> 03:44:07,479
key is the name right so key is the name
5291
03:44:07,479 --> 03:44:09,640
and we'll set it equal to a new instance
5292
03:44:09,640 --> 03:44:13,239
of a user struct so
5293
03:44:13,359 --> 03:44:16,000
user and the user ruct has two Fields
5294
03:44:16,000 --> 03:44:18,880
name which will just again be the name
5295
03:44:18,880 --> 03:44:21,479
and the phone
5296
03:44:22,279 --> 03:44:24,680
number uh which will just be this phone
5297
03:44:24,680 --> 03:44:25,600
number
5298
03:44:25,600 --> 03:44:28,600
here
5299
03:44:28,920 --> 03:44:31,560
cool so that should fill the entire user
5300
03:44:31,560 --> 03:44:32,960
map with all of the names and phone
5301
03:44:32,960 --> 03:44:34,600
numbers and then by the end we should
5302
03:44:34,600 --> 03:44:36,000
just be able to
5303
03:44:36,000 --> 03:44:39,080
return user map
5304
03:44:39,080 --> 03:44:41,840
nil okay cool I think we got everything
5305
03:44:41,840 --> 03:44:45,640
let's go ahead and run that
5306
03:44:45,640 --> 03:44:48,479
and see what we get so creating map key
5307
03:44:48,479 --> 03:44:52,080
John value name number key Bob value
5308
03:44:52,080 --> 03:44:53,960
name number this is looking this is
5309
03:44:53,960 --> 03:44:55,199
looking correct to me here we have
5310
03:44:55,199 --> 03:44:57,000
creating map with invalid
5311
03:44:57,000 --> 03:45:00,319
sizes um if we take a look at the
5312
03:45:00,319 --> 03:45:02,640
tests uh yep that makes sense the second
5313
03:45:02,640 --> 03:45:04,880
test has two names but three numbers so
5314
03:45:04,880 --> 03:45:06,960
I would expect it to get that invalid
5315
03:45:06,960 --> 03:45:10,680
sizes error cool let's uh let's submit
5316
03:45:10,680 --> 03:45:13,600
that so the primary way you interact
5317
03:45:13,600 --> 03:45:15,600
with maps is just by setting and
5318
03:45:15,600 --> 03:45:18,120
deleting uh values at a given key right
5319
03:45:18,120 --> 03:45:20,399
they're very associative right a value
5320
03:45:20,399 --> 03:45:21,960
maps to a key but there's no other
5321
03:45:21,960 --> 03:45:24,120
ordering Maps aren't ordered from you
5322
03:45:24,120 --> 03:45:27,880
know index 0 1 2 3 uh like a slice is
5323
03:45:27,880 --> 03:45:29,560
everything's unordered you're literally
5324
03:45:29,560 --> 03:45:32,000
just mapping values to Keys Okay cool so
5325
03:45:32,000 --> 03:45:33,159
let's take a look at some of the
5326
03:45:33,159 --> 03:45:34,560
different syntax that we can use to
5327
03:45:34,560 --> 03:45:36,840
interact with maps so we can insert an
5328
03:45:36,840 --> 03:45:39,920
element by just setting the key equal to
5329
03:45:39,920 --> 03:45:43,080
the value um we can get an element out
5330
03:45:43,080 --> 03:45:45,840
just by accessing it directly at its key
5331
03:45:45,840 --> 03:45:47,640
we can delete Elements by using the
5332
03:45:47,640 --> 03:45:49,720
built-in delete function where we're
5333
03:45:49,720 --> 03:45:51,840
passing in the map itself and the key
5334
03:45:51,840 --> 03:45:53,520
that we want to delete notice that we're
5335
03:45:53,520 --> 03:45:55,040
not passing in the value at all we're
5336
03:45:55,040 --> 03:45:57,439
just passing in the key and then we can
5337
03:45:57,439 --> 03:46:02,080
also check if a key exists by parsing
5338
03:46:02,080 --> 03:46:04,600
the return value of kind of this access
5339
03:46:04,600 --> 03:46:07,279
syntax into two separate values where
5340
03:46:07,279 --> 03:46:09,279
the first value will be the element
5341
03:46:09,279 --> 03:46:13,000
itself and the second value is a Boolean
5342
03:46:13,000 --> 03:46:15,920
if the Boolean is true then the element
5343
03:46:15,920 --> 03:46:18,040
will be whatever element was stored of
5344
03:46:18,040 --> 03:46:22,040
that key however if the Boolean is false
5345
03:46:22,040 --> 03:46:23,560
that tells you that that key didn't
5346
03:46:23,560 --> 03:46:25,479
exist in the map and the element will
5347
03:46:25,479 --> 03:46:28,159
just be the zero value for its type
5348
03:46:28,159 --> 03:46:30,640
let's jump into the assignment so it
5349
03:46:30,640 --> 03:46:33,040
says in fact let me uh let me resize
5350
03:46:33,040 --> 03:46:33,960
this a
5351
03:46:33,960 --> 03:46:36,319
bit says it's important to keep up with
5352
03:46:36,319 --> 03:46:37,760
privacy regulations and to respect our
5353
03:46:37,760 --> 03:46:39,560
users data we need a function that will
5354
03:46:39,560 --> 03:46:42,080
delete user records okay complete the
5355
03:46:42,080 --> 03:46:44,640
delete if necessary function um it takes
5356
03:46:44,640 --> 03:46:47,800
a a map of users and a name which I'm
5357
03:46:47,800 --> 03:46:51,000
going to guess is the key in the map and
5358
03:46:51,000 --> 03:46:53,239
it will return a Boolean saying whether
5359
03:46:53,239 --> 03:46:56,080
or not the user was deleted and then an
5360
03:46:56,080 --> 03:46:58,399
error if something went wrong okay cool
5361
03:46:58,399 --> 03:47:00,120
so if the user does not exist in the map
5362
03:47:00,120 --> 03:47:01,840
return the error not found oh
5363
03:47:01,840 --> 03:47:03,080
interesting so if we're trying to delete
5364
03:47:03,080 --> 03:47:04,720
something and it's not there um that's
5365
03:47:04,720 --> 03:47:07,560
an error if they exist but aren't
5366
03:47:07,560 --> 03:47:10,479
scheduled for deletion then return
5367
03:47:10,479 --> 03:47:13,120
deleted as false so we this will be
5368
03:47:13,120 --> 03:47:15,040
false um and there won't be any errors
5369
03:47:15,040 --> 03:47:17,040
um but if they exist and are scheduled
5370
03:47:17,040 --> 03:47:19,760
for deletion then we'll return uh the
5371
03:47:19,760 --> 03:47:22,279
deleted Boolean as true with no other
5372
03:47:22,279 --> 03:47:25,080
errors okay that's making sense to me
5373
03:47:25,080 --> 03:47:27,560
and then a note on how maps are passed
5374
03:47:27,560 --> 03:47:30,520
into functions is that like slices maps
5375
03:47:30,520 --> 03:47:32,680
are actually passed by reference so even
5376
03:47:32,680 --> 03:47:35,199
though this function delete if necessary
5377
03:47:35,199 --> 03:47:39,479
does not return a map if we mutate this
5378
03:47:39,479 --> 03:47:42,040
users map it will be mutated for the
5379
03:47:42,040 --> 03:47:43,399
color of the function so that's how
5380
03:47:43,399 --> 03:47:45,319
we're able to delete something from the
5381
03:47:45,319 --> 03:47:47,040
map even though we're not returning the
5382
03:47:47,040 --> 03:47:49,120
map once we're done with it so the first
5383
03:47:49,120 --> 03:47:50,720
thing we need to do is just check and
5384
03:47:50,720 --> 03:47:52,319
see if the name that we're trying to
5385
03:47:52,319 --> 03:47:57,279
delete exists so let's do this if blank
5386
03:47:57,279 --> 03:48:00,399
okay colon equals
5387
03:48:00,399 --> 03:48:02,760
users at
5388
03:48:02,760 --> 03:48:07,880
name not not okay so uh this is that
5389
03:48:07,880 --> 03:48:10,720
kind of special if statement syntax
5390
03:48:10,720 --> 03:48:13,399
right um where we're uh actually
5391
03:48:13,399 --> 03:48:16,159
ignoring the value at self um we're just
5392
03:48:16,159 --> 03:48:18,120
interested in that Boolean value telling
5393
03:48:18,120 --> 03:48:21,680
us whether or not this um this key
5394
03:48:21,680 --> 03:48:23,840
exists in the map and if it does not
5395
03:48:23,840 --> 03:48:26,120
then we're going to go ahead and return
5396
03:48:26,120 --> 03:48:28,199
uh return the error not found so false
5397
03:48:28,199 --> 03:48:29,640
because we always do zero values for
5398
03:48:29,640 --> 03:48:30,880
everything besides the error and then
5399
03:48:30,880 --> 03:48:33,040
errors.
5400
03:48:33,040 --> 03:48:36,159
new not found and we'll make sure to
5401
03:48:36,159 --> 03:48:38,319
import that errors
5402
03:48:38,319 --> 03:48:40,920
package okay cool and again I'm just I'm
5403
03:48:40,920 --> 03:48:43,840
just uh using this syntax here to check
5404
03:48:43,840 --> 03:48:45,760
if a key exists
5405
03:48:45,760 --> 03:48:47,960
cool moving on okay so if we get past uh
5406
03:48:47,960 --> 03:48:49,920
past that guard Clause to line 12 then
5407
03:48:49,920 --> 03:48:54,159
we know um that the user exists so um at
5408
03:48:54,159 --> 03:48:55,840
this point ah we need to check if
5409
03:48:55,840 --> 03:48:57,359
they're scheduled for deletion so I'm
5410
03:48:57,359 --> 03:48:58,600
actually going to switch up my syntax
5411
03:48:58,600 --> 03:49:01,239
here the user struct has the scheduled
5412
03:49:01,239 --> 03:49:03,239
for deletion Boolean so I'm going to go
5413
03:49:03,239 --> 03:49:06,279
ahead and do this on a separate
5414
03:49:06,279 --> 03:49:10,120
line and I will save that user so I'll
5415
03:49:10,120 --> 03:49:15,720
do um existing user
5416
03:49:16,840 --> 03:49:18,760
and then we'll just do if not
5417
03:49:18,760 --> 03:49:21,520
okay so that down here now I can use
5418
03:49:21,520 --> 03:49:23,399
that existing user struct so I can say
5419
03:49:23,399 --> 03:49:28,479
if existing user. scheduled for
5420
03:49:28,479 --> 03:49:30,520
deletion so if they exist and are
5421
03:49:30,520 --> 03:49:32,239
schedul for deletion return deleted as
5422
03:49:32,239 --> 03:49:33,279
true with no errors and delete the
5423
03:49:33,279 --> 03:49:34,560
record from the map so we need to use
5424
03:49:34,560 --> 03:49:38,920
this built-in delete function so we'll
5425
03:49:38,960 --> 03:49:40,479
delete
5426
03:49:40,479 --> 03:49:45,920
users name and then we'll return true
5427
03:49:45,920 --> 03:49:48,000
n all right so if they are scheduled for
5428
03:49:48,000 --> 03:49:50,359
deletion we'll delete them and report
5429
03:49:50,359 --> 03:49:54,319
back that we deleted them cool um
5430
03:49:54,319 --> 03:49:57,800
otherwise if they're not scheduled for
5431
03:49:57,800 --> 03:49:59,880
deletion return deleted as false with no
5432
03:49:59,880 --> 03:50:01,040
errors so
5433
03:50:01,040 --> 03:50:03,359
return false
5434
03:50:03,359 --> 03:50:05,800
no okay that looks right to me let's go
5435
03:50:05,800 --> 03:50:08,439
ahead and run
5436
03:50:09,279 --> 03:50:11,960
that attempting to delete John deleted
5437
03:50:11,960 --> 03:50:14,960
JN attempting to delete musk not found
5438
03:50:14,960 --> 03:50:16,720
Santa not found attempt to delete Kade
5439
03:50:16,720 --> 03:50:18,159
did not delete Kade Okay cool so I mean
5440
03:50:18,159 --> 03:50:19,520
all that look it looks like all the
5441
03:50:19,520 --> 03:50:21,439
cases were covered let's just come down
5442
03:50:21,439 --> 03:50:22,600
here and take a
5443
03:50:22,600 --> 03:50:25,800
look okay so we had a John and JN was
5444
03:50:25,800 --> 03:50:27,880
deleted and then attempting to delete
5445
03:50:27,880 --> 03:50:30,040
musk there's not actually a musk in the
5446
03:50:30,040 --> 03:50:32,600
map so not found makes sense um there's
5447
03:50:32,600 --> 03:50:36,159
also not a Santa and Cade was not
5448
03:50:36,159 --> 03:50:38,720
scheduled for deletion so he did not get
5449
03:50:38,720 --> 03:50:41,520
deleted and then the final map still has
5450
03:50:41,520 --> 03:50:44,520
those keys that looks correct to me in
5451
03:50:44,520 --> 03:50:46,159
the this next section we're going to be
5452
03:50:46,159 --> 03:50:48,399
covering some of the material from the
5453
03:50:48,399 --> 03:50:51,000
go blog now I'm not going to read all of
5454
03:50:51,000 --> 03:50:53,760
this out uh that would be a little dry
5455
03:50:53,760 --> 03:50:56,040
but I definitely recommend reading this
5456
03:50:56,040 --> 03:50:58,040
over if you have the time otherwise I'm
5457
03:50:58,040 --> 03:51:00,520
going to cover kind of the key points so
5458
03:51:00,520 --> 03:51:02,680
the first question is what makes a type
5459
03:51:02,680 --> 03:51:05,319
qualify to be able to be used as a map
5460
03:51:05,319 --> 03:51:08,279
key okay so any type can be used as a
5461
03:51:08,279 --> 03:51:10,800
map value but not every type can be used
5462
03:51:10,800 --> 03:51:14,359
as a map key and that's because map Keys
5463
03:51:14,359 --> 03:51:16,080
make may be of any type that is
5464
03:51:16,080 --> 03:51:18,760
comparable so things like strings
5465
03:51:18,760 --> 03:51:21,520
booleans um numbers all those can be
5466
03:51:21,520 --> 03:51:24,399
compared for a quality what cannot be
5467
03:51:24,399 --> 03:51:28,159
compared for equality are slices maps
5468
03:51:28,159 --> 03:51:30,279
and functions and kind of one of the
5469
03:51:30,279 --> 03:51:32,439
reasons for that is slices and maps and
5470
03:51:32,439 --> 03:51:34,359
functions they're kind of just pointers
5471
03:51:34,359 --> 03:51:37,880
to addresses in memory so if you compare
5472
03:51:37,880 --> 03:51:40,199
one slice to another slice you're not
5473
03:51:40,199 --> 03:51:42,640
really comparing the underlying values
5474
03:51:42,640 --> 03:51:45,000
you're actually comparing kind of where
5475
03:51:45,000 --> 03:51:47,600
those two slices are stored in your
5476
03:51:47,600 --> 03:51:49,000
computer's
5477
03:51:49,000 --> 03:51:51,159
RAM and because they're stored in
5478
03:51:51,159 --> 03:51:53,479
different places you'll actually get two
5479
03:51:53,479 --> 03:51:55,560
slices with maybe the exact same values
5480
03:51:55,560 --> 03:51:57,880
stored in them say slice one has the
5481
03:51:57,880 --> 03:51:59,960
numbers one two three in the first three
5482
03:51:59,960 --> 03:52:01,920
indexes and the second slice has the
5483
03:52:01,920 --> 03:52:04,880
same they might still be compared as
5484
03:52:04,880 --> 03:52:06,840
unequal because they're stored in
5485
03:52:06,840 --> 03:52:09,880
different addresses in memory so I mean
5486
03:52:09,880 --> 03:52:12,159
all that being said long story short you
5487
03:52:12,159 --> 03:52:15,040
just can't use slices and maps maps and
5488
03:52:15,040 --> 03:52:18,279
functions as map keys so to answer the
5489
03:52:18,279 --> 03:52:19,560
question what makes type qualifi to be
5490
03:52:19,560 --> 03:52:23,399
used as a map key the type is comparable
5491
03:52:23,399 --> 03:52:25,479
this next question is interesting and
5492
03:52:25,479 --> 03:52:28,120
kind of plays on the idea that we can
5493
03:52:28,120 --> 03:52:30,600
Nest Maps um kind of one inside the
5494
03:52:30,600 --> 03:52:32,120
other or we could do something that's
5495
03:52:32,120 --> 03:52:33,880
arguably simpler let me show you what I
5496
03:52:33,880 --> 03:52:38,560
mean so here is an example of a map of
5497
03:52:38,560 --> 03:52:43,279
strings that maps to another map which
5498
03:52:43,279 --> 03:52:46,359
maps from strings to integers so like
5499
03:52:46,359 --> 03:52:47,880
the first string kind of maps to the
5500
03:52:47,880 --> 03:52:49,720
second string which maps to an integer
5501
03:52:49,720 --> 03:52:51,399
if you want to think about it that way
5502
03:52:51,399 --> 03:52:53,319
if you're familiar with Json objects
5503
03:52:53,319 --> 03:52:55,760
this would be like mapping Json objects
5504
03:52:55,760 --> 03:52:59,120
kind of down multiple uh levels of keys
5505
03:52:59,120 --> 03:53:02,040
so in the example given in the go blog
5506
03:53:02,040 --> 03:53:03,399
essentially what's being said is we're
5507
03:53:03,399 --> 03:53:07,439
mapping um two strings to a count and so
5508
03:53:07,439 --> 03:53:09,319
what that looks like in code is if we
5509
03:53:09,319 --> 03:53:11,040
want to get access to the count we
5510
03:53:11,040 --> 03:53:14,520
actually have to go to the map index the
5511
03:53:14,520 --> 03:53:17,800
nested map with a key and then index
5512
03:53:17,800 --> 03:53:20,239
into that next map with another key
5513
03:53:20,239 --> 03:53:22,040
before we get the value out now this
5514
03:53:22,040 --> 03:53:24,640
looks simple on the surface but what
5515
03:53:24,640 --> 03:53:26,640
actually happens is when you need when
5516
03:53:26,640 --> 03:53:29,040
you go down those nested levels you
5517
03:53:29,040 --> 03:53:31,319
actually can't be sure that the inner
5518
03:53:31,319 --> 03:53:34,920
map exists and So to avoid panicking
5519
03:53:34,920 --> 03:53:36,880
your code will actually Panic by the way
5520
03:53:36,880 --> 03:53:39,560
if you try to access a key in a map that
5521
03:53:39,560 --> 03:53:42,439
is nil So to avoid panicking you have to
5522
03:53:42,439 --> 03:53:44,120
check and make sure that those nested
5523
03:53:44,120 --> 03:53:47,399
Maps actually exist which just results
5524
03:53:47,399 --> 03:53:50,640
in a lot of extra code so while nesting
5525
03:53:50,640 --> 03:53:52,760
Maps definitely works and I've used it
5526
03:53:52,760 --> 03:53:55,279
quite a bit there can in some instances
5527
03:53:55,279 --> 03:53:57,359
be a simpler way which is to actually
5528
03:53:57,359 --> 03:54:01,279
use a struct as a key notice that a
5529
03:54:01,279 --> 03:54:03,880
struct was not named as one of the
5530
03:54:03,880 --> 03:54:06,359
non-comparable types structs are
5531
03:54:06,359 --> 03:54:09,479
comparable so if you want to create a
5532
03:54:09,479 --> 03:54:11,760
map that kind of has multiple keys that
5533
03:54:11,760 --> 03:54:13,880
kind of combine together to form a
5534
03:54:13,880 --> 03:54:16,880
composite key then just create a new
5535
03:54:16,880 --> 03:54:19,600
struct right with two values inside of
5536
03:54:19,600 --> 03:54:22,520
it and those two values kind of unique
5537
03:54:22,520 --> 03:54:25,520
together create their own key so this
5538
03:54:25,520 --> 03:54:27,159
simplifies a lot of things where now we
5539
03:54:27,159 --> 03:54:29,600
can have one map and we can use that
5540
03:54:29,600 --> 03:54:32,199
struct key to create kind of uniqueness
5541
03:54:32,199 --> 03:54:33,920
across two different values this might
5542
03:54:33,920 --> 03:54:35,279
be useful for example if you're trying
5543
03:54:35,279 --> 03:54:38,640
to create a map That's Unique for first
5544
03:54:38,640 --> 03:54:40,680
last name combinations right you want
5545
03:54:40,680 --> 03:54:42,439
Lane Wagner stored in two different
5546
03:54:42,439 --> 03:54:44,640
fields first name and last name to be
5547
03:54:44,640 --> 03:54:47,159
unique together so to answer the
5548
03:54:47,159 --> 03:54:49,080
question which is simpler to use a
5549
03:54:49,080 --> 03:54:52,080
struct directly as a key or to Nest maps
5550
03:54:52,080 --> 03:54:54,560
and um the authors of the go blog and I
5551
03:54:54,560 --> 03:54:57,680
would agree argue that using a struct
5552
03:54:57,680 --> 03:54:59,640
directly is going to be simpler let's
5553
03:54:59,640 --> 03:55:01,520
jump right into this next assignment
5554
03:55:01,520 --> 03:55:04,120
says we have a slice of user IDs okay so
5555
03:55:04,120 --> 03:55:06,199
those are strings and each instance of
5556
03:55:06,199 --> 03:55:07,960
an ID in the slice indicates that a
5557
03:55:07,960 --> 03:55:10,080
message was sent to that user we need to
5558
03:55:10,080 --> 03:55:12,680
count up how many times each user's ID
5559
03:55:12,680 --> 03:55:14,439
appears in the slice to track how how
5560
03:55:14,439 --> 03:55:16,840
many messages they received implement
5561
03:55:16,840 --> 03:55:19,120
the get counts function okay so that's
5562
03:55:19,120 --> 03:55:20,920
this one it should return a map of
5563
03:55:20,920 --> 03:55:23,120
string to int so that each int is a
5564
03:55:23,120 --> 03:55:24,600
count of how many times each string was
5565
03:55:24,600 --> 03:55:26,800
found in the slice okay cool simple
5566
03:55:26,800 --> 03:55:29,920
enough so let's create a new map so this
5567
03:55:29,920 --> 03:55:33,000
will be the counts map and it's going to
5568
03:55:33,000 --> 03:55:37,040
be a map of string to
5569
03:55:37,479 --> 03:55:40,359
integer and then let's Loop over all of
5570
03:55:40,359 --> 03:55:46,080
the user IDs so four blank user ID
5571
03:55:46,080 --> 03:55:48,439
in range user
5572
03:55:48,439 --> 03:55:50,680
IDs we're just we're going to ignore the
5573
03:55:50,680 --> 03:55:53,040
index because we don't care about
5574
03:55:53,040 --> 03:55:55,439
it and the first thing we're going to do
5575
03:55:55,439 --> 03:55:59,600
is check to see if um a value in the map
5576
03:55:59,600 --> 03:56:02,880
for the given user ID already exists so
5577
03:56:02,880 --> 03:56:05,520
count okay colon
5578
03:56:05,520 --> 03:56:08,760
equals user
5579
03:56:08,760 --> 03:56:12,080
IDs sorry
5580
03:56:12,080 --> 03:56:16,239
counts at user ID
5581
03:56:17,199 --> 03:56:21,600
right cool um in fact now like now that
5582
03:56:21,600 --> 03:56:22,880
I type that out I'm not actually sure
5583
03:56:22,880 --> 03:56:26,399
that I need this because if I don't use
5584
03:56:26,399 --> 03:56:29,080
this this access will still work it's
5585
03:56:29,080 --> 03:56:31,239
just if if the key didn't exist count
5586
03:56:31,239 --> 03:56:33,920
will be zero which is fine so actually I
5587
03:56:33,920 --> 03:56:37,560
I don't even think I care um cool so we
5588
03:56:37,560 --> 03:56:39,520
get the count it'll be zero if it didn't
5589
03:56:39,520 --> 03:56:41,120
yet exist and then we just increment it
5590
03:56:41,120 --> 03:56:44,600
by one so count Plus+
5591
03:56:44,600 --> 03:56:46,239
and then we'll save it back into the map
5592
03:56:46,239 --> 03:56:50,000
so counts at user ID equals count so
5593
03:56:50,000 --> 03:56:51,680
we're just grabbing it out incrementing
5594
03:56:51,680 --> 03:56:55,560
it by one and putting it back that seems
5595
03:56:55,560 --> 03:56:57,600
like what we want to do right and then
5596
03:56:57,600 --> 03:57:00,720
at the end we'll just return
5597
03:57:00,720 --> 03:57:02,239
counts
5598
03:57:02,239 --> 03:57:04,199
cool let's go ahead and run that and see
5599
03:57:04,199 --> 03:57:06,479
what we
5600
03:57:07,920 --> 03:57:11,279
get Jing counts for 10,000 user IDs
5601
03:57:11,279 --> 03:57:14,439
Counts from selected IDs 0 0 has 31 f F
5602
03:57:14,439 --> 03:57:19,239
has 27 DD has 37 okay and if I look down
5603
03:57:19,239 --> 03:57:22,359
here it looks like the IDS are being
5604
03:57:22,359 --> 03:57:23,920
generated
5605
03:57:23,920 --> 03:57:28,040
randomly cool so let's go ahead and
5606
03:57:28,040 --> 03:57:32,000
submit it because this feels
5607
03:57:32,520 --> 03:57:35,439
right cool we're good to go this next
5608
03:57:35,439 --> 03:57:39,159
section is about a piece or an excerpt
5609
03:57:39,159 --> 03:57:42,239
from the effective go book um that is a
5610
03:57:42,239 --> 03:57:44,239
book that i' highly recommend reading um
5611
03:57:44,239 --> 03:57:45,680
some of the stuff's a bit outdated
5612
03:57:45,680 --> 03:57:47,080
they've made the decision not to
5613
03:57:47,080 --> 03:57:49,640
continuously update effective go but it
5614
03:57:49,640 --> 03:57:52,000
is an open-source book you can go read
5615
03:57:52,000 --> 03:57:53,880
the whole thing for free um and the link
5616
03:57:53,880 --> 03:57:55,640
is right there so go check that out if
5617
03:57:55,640 --> 03:57:57,720
you're interested um that said you don't
5618
03:57:57,720 --> 03:57:59,560
need to I'll be talking through um the
5619
03:57:59,560 --> 03:58:01,800
parts that we care about here so Maps
5620
03:58:01,800 --> 03:58:04,640
can have at most blank values associated
5621
03:58:04,640 --> 03:58:06,399
with the same key the answers are one
5622
03:58:06,399 --> 03:58:09,159
any number of three and two well maps
5623
03:58:09,159 --> 03:58:11,479
are associative right they map a single
5624
03:58:11,479 --> 03:58:14,120
key to a single value and you can't have
5625
03:58:14,120 --> 03:58:16,720
duplicates of the same key in a map that
5626
03:58:16,720 --> 03:58:18,080
wouldn't make any sense right then when
5627
03:58:18,080 --> 03:58:19,680
you put in a key you would maybe get
5628
03:58:19,680 --> 03:58:21,239
back a slice like that doesn't quite
5629
03:58:21,239 --> 03:58:23,720
work so the answer is Maps can have at
5630
03:58:23,720 --> 03:58:26,359
most one value associated with the same
5631
03:58:26,359 --> 03:58:28,359
key the next question says attempting to
5632
03:58:28,359 --> 03:58:29,840
get a value from a map where the key
5633
03:58:29,840 --> 03:58:32,159
does not exist Returns the closest Value
5634
03:58:32,159 --> 03:58:35,000
panics or Returns the zero value um
5635
03:58:35,000 --> 03:58:36,520
that's covered here in the section on
5636
03:58:36,520 --> 03:58:39,439
missing keys but basically to summarize
5637
03:58:39,439 --> 03:58:41,800
if you attempt to get a I mean we
5638
03:58:41,800 --> 03:58:43,359
actually covered this in the last um the
5639
03:58:43,359 --> 03:58:44,960
last coding assignment but if you
5640
03:58:44,960 --> 03:58:48,199
attempt to access a key in a map where
5641
03:58:48,199 --> 03:58:49,720
the key doesn't exist you'll just get
5642
03:58:49,720 --> 03:58:52,000
back the zero value so for example if
5643
03:58:52,000 --> 03:58:55,960
it's a map of strings to integers and
5644
03:58:55,960 --> 03:58:58,560
you access a string that doesn't exist
5645
03:58:58,560 --> 03:59:01,720
you'll get back as the value zero and
5646
03:59:01,720 --> 03:59:03,399
that's kind of nice just because
5647
03:59:03,399 --> 03:59:06,040
accessing values in a map is a safe
5648
03:59:06,040 --> 03:59:08,520
operation your code will not will not
5649
03:59:08,520 --> 03:59:10,560
panic so to answer the question it
5650
03:59:10,560 --> 03:59:13,159
Returns the zero value and it's also
5651
03:59:13,159 --> 03:59:15,279
worth pointing out really quickly that
5652
03:59:15,279 --> 03:59:18,520
if the map doesn't exist so not that the
5653
03:59:18,520 --> 03:59:20,120
key that you're trying to access doesn't
5654
03:59:20,120 --> 03:59:21,840
exist but if the map itself doesn't
5655
03:59:21,840 --> 03:59:24,520
exist if it's a nil map then your code
5656
03:59:24,520 --> 03:59:26,279
will Panic so that is a dangerous
5657
03:59:26,279 --> 03:59:27,680
operation you want to make sure you're
5658
03:59:27,680 --> 03:59:29,960
always accessing values in maps that
5659
03:59:29,960 --> 03:59:32,399
have been initialized the next question
5660
03:59:32,399 --> 03:59:34,319
is a function can mutate the values
5661
03:59:34,319 --> 03:59:37,319
stored in a map and those changes blank
5662
03:59:37,319 --> 03:59:40,640
the colar affect or do not affect the
5663
03:59:40,640 --> 03:59:43,640
collar now the answer to this one is in
5664
03:59:43,640 --> 03:59:46,479
this first section that Maps like slices
5665
03:59:46,479 --> 03:59:48,960
are references so when we pass a map
5666
03:59:48,960 --> 03:59:52,239
into a function that function can change
5667
03:59:52,239 --> 03:59:54,560
what's in the map and those changes will
5668
03:59:54,560 --> 03:59:56,720
be visible outside of the function this
5669
03:59:56,720 --> 03:59:58,120
is different from Primitives right
5670
03:59:58,120 --> 04:00:01,040
strings integers um booleans those are
5671
04:00:01,040 --> 04:00:02,920
all passed into functions by value if
5672
04:00:02,920 --> 04:00:05,040
you mutate them within a function uh the
5673
04:00:05,040 --> 04:00:06,520
the the CER of that function will not
5674
04:00:06,520 --> 04:00:08,720
see those changes unless you return
5675
04:00:08,720 --> 04:00:11,279
those values but the same does not hold
5676
04:00:11,279 --> 04:00:14,720
true for slices and maps so to answer
5677
04:00:14,720 --> 04:00:16,720
the question uh a function can mutate
5678
04:00:16,720 --> 04:00:18,720
the values uh stored in a map and those
5679
04:00:18,720 --> 04:00:22,120
changes they do affect the CER the next
5680
04:00:22,120 --> 04:00:23,920
question says what does the second
5681
04:00:23,920 --> 04:00:26,199
return value from a retrieve operation
5682
04:00:26,199 --> 04:00:29,840
in a map indicate so let's take a look
5683
04:00:29,840 --> 04:00:32,000
at this code example here so we've got
5684
04:00:32,000 --> 04:00:34,479
this time zone map where we're accessing
5685
04:00:34,479 --> 04:00:37,720
the map at a given a given key and it
5686
04:00:37,720 --> 04:00:42,159
can return two values the first value is
5687
04:00:42,159 --> 04:00:43,560
the value associated with the key and
5688
04:00:43,560 --> 04:00:46,000
the second value is a Boolean right we
5689
04:00:46,000 --> 04:00:47,439
used this in the last coding assignment
5690
04:00:47,439 --> 04:00:49,080
so a Boolean that indicates whether the
5691
04:00:49,080 --> 04:00:51,239
value at the key is a nil value nope
5692
04:00:51,239 --> 04:00:52,880
that's not accurate a Boolean that
5693
04:00:52,880 --> 04:00:55,040
indicates whether the key exists that's
5694
04:00:55,040 --> 04:00:56,080
the
5695
04:00:56,080 --> 04:00:59,960
one let's practice with some nested Maps
5696
04:00:59,960 --> 04:01:02,279
so like we talked about earlier Maps can
5697
04:01:02,279 --> 04:01:05,199
contain other Maps as their values not
5698
04:01:05,199 --> 04:01:07,319
as not as their keys right so let's jump
5699
04:01:07,319 --> 04:01:09,600
into the assignment says because texo is
5700
04:01:09,600 --> 04:01:11,319
a glorified customer database right I
5701
04:01:11,319 --> 04:01:13,960
mean we're sending sms and email
5702
04:01:13,960 --> 04:01:15,880
messages to a giant list of customers or
5703
04:01:15,880 --> 04:01:17,960
basically just a big customer database
5704
04:01:17,960 --> 04:01:19,560
um we have a lot of internal Logic for
5705
04:01:19,560 --> 04:01:21,880
sorting and dealing with customer names
5706
04:01:21,880 --> 04:01:23,960
complete the get name counts function it
5707
04:01:23,960 --> 04:01:26,279
takes a slice of strings
5708
04:01:26,279 --> 04:01:29,000
names and returns a nested map this is
5709
04:01:29,000 --> 04:01:30,199
going to be very similar to the last
5710
04:01:30,199 --> 04:01:33,000
assignment we did um but this time it's
5711
04:01:33,000 --> 04:01:34,560
going to be a nested map where the first
5712
04:01:34,560 --> 04:01:36,279
key is all the unique First characters
5713
04:01:36,279 --> 04:01:38,560
of the names and the second key is all
5714
04:01:38,560 --> 04:01:40,560
of the names themselves so this could be
5715
04:01:40,560 --> 04:01:42,279
useful if for some reason we wanted to
5716
04:01:42,279 --> 04:01:44,279
get access to all of the names that
5717
04:01:44,279 --> 04:01:47,040
start with a very quickly so to kind of
5718
04:01:47,040 --> 04:01:49,120
visualize this we've got this example if
5719
04:01:49,120 --> 04:01:52,399
the input names slice is this slice here
5720
04:01:52,399 --> 04:01:54,560
Billy Billy Bob Joe it would create the
5721
04:01:54,560 --> 04:01:57,600
following nested map so the first key is
5722
04:01:57,600 --> 04:01:59,239
just a
5723
04:01:59,239 --> 04:02:03,199
letter the second key is the full name
5724
04:02:03,199 --> 04:02:06,840
and then the value is um the number of
5725
04:02:06,840 --> 04:02:08,600
times that name showed up in the
5726
04:02:08,600 --> 04:02:10,600
original list and then it's worth
5727
04:02:10,600 --> 04:02:13,040
pointing out here that the return value
5728
04:02:13,040 --> 04:02:16,760
is a map of runes to a map of strings
5729
04:02:16,760 --> 04:02:19,199
and integers in go we often just
5730
04:02:19,199 --> 04:02:22,640
represent individual characters as runes
5731
04:02:22,640 --> 04:02:24,880
rather than strings of length one it
5732
04:02:24,880 --> 04:02:26,960
just gives us a little more um kind of
5733
04:02:26,960 --> 04:02:29,319
assurity in our type system okay so
5734
04:02:29,319 --> 04:02:32,720
let's start by creating a new top level
5735
04:02:32,720 --> 04:02:35,279
map so we'll call it counts and we'll
5736
04:02:35,279 --> 04:02:39,199
make that full map now it's important to
5737
04:02:39,199 --> 04:02:42,399
understand because this map contains
5738
04:02:42,399 --> 04:02:44,439
Maps inside of it we we will need to
5739
04:02:44,439 --> 04:02:46,640
continuously initialize new maps I'll
5740
04:02:46,640 --> 04:02:49,439
show you what that looks like so now
5741
04:02:49,439 --> 04:02:51,000
let's just uh loop over all these names
5742
04:02:51,000 --> 04:02:51,760
so
5743
04:02:51,760 --> 04:02:54,840
for um we don't care about the index
5744
04:02:54,840 --> 04:02:57,680
name and range
5745
04:02:57,680 --> 04:03:00,680
names Okay so we've got a name the first
5746
04:03:00,680 --> 04:03:03,239
thing we need to do is actually check
5747
04:03:03,239 --> 04:03:06,279
and see if we already have a map
5748
04:03:06,279 --> 04:03:07,920
associated with the first character of
5749
04:03:07,920 --> 04:03:10,399
this name so let's get that first
5750
04:03:10,399 --> 04:03:14,359
character let's do um if we probably
5751
04:03:14,359 --> 04:03:16,159
need to do some safety checking so like
5752
04:03:16,159 --> 04:03:18,800
if length of
5753
04:03:18,800 --> 04:03:20,920
name actually the easiest thing to do
5754
04:03:20,920 --> 04:03:24,319
would just be if name is the empty
5755
04:03:24,319 --> 04:03:26,720
string then we'll
5756
04:03:26,720 --> 04:03:29,279
continue we don't care about blank names
5757
04:03:29,279 --> 04:03:30,800
they they don't do anything for us right
5758
04:03:30,800 --> 04:03:33,520
so we'll just we'll just skip them great
5759
04:03:33,520 --> 04:03:36,199
if it's not the empty string then we can
5760
04:03:36,199 --> 04:03:41,840
say first character is name zero okay so
5761
04:03:41,840 --> 04:03:44,399
that gives us the Rune at
5762
04:03:44,399 --> 04:03:47,199
um the first index in the
5763
04:03:47,199 --> 04:03:50,359
name and then what we can do is look up
5764
04:03:50,359 --> 04:03:54,359
in our map so counts at first oops
5765
04:03:54,359 --> 04:03:56,720
counts at first
5766
04:03:56,720 --> 04:04:01,560
character um we can see if the inner
5767
04:04:01,560 --> 04:04:03,479
map
5768
04:04:03,479 --> 04:04:07,439
exists so if it does not exist not if
5769
04:04:07,439 --> 04:04:09,720
not
5770
04:04:09,720 --> 04:04:11,920
okay let's just keep it simple if it
5771
04:04:11,920 --> 04:04:14,279
doesn't exist we'll just initialize it
5772
04:04:14,279 --> 04:04:16,399
so if it does not exist we'll say counts
5773
04:04:16,399 --> 04:04:17,520
at first
5774
04:04:17,520 --> 04:04:20,080
character equals and we'll initialize
5775
04:04:20,080 --> 04:04:23,479
the new inner map so we just need a new
5776
04:04:23,479 --> 04:04:26,279
map of string to
5777
04:04:26,279 --> 04:04:30,920
integer at that first character key
5778
04:04:30,920 --> 04:04:34,960
right right in fact to be explicit I'm
5779
04:04:34,960 --> 04:04:37,560
going to ignore the inner map
5780
04:04:37,560 --> 04:04:41,040
there so by the time we get down here to
5781
04:04:41,040 --> 04:04:44,399
line 18 we should be 100% certain that
5782
04:04:44,399 --> 04:04:47,239
counts at first character contains an
5783
04:04:47,239 --> 04:04:49,920
initialized map so then we can just
5784
04:04:49,920 --> 04:04:53,080
simply do counts at first character
5785
04:04:53,080 --> 04:04:56,080
at
5786
04:04:57,880 --> 04:04:59,920
name
5787
04:04:59,920 --> 04:05:01,600
Plus+
5788
04:05:01,600 --> 04:05:04,000
right because we've we've made sure that
5789
04:05:04,000 --> 04:05:09,399
the inner map exists and if the name key
5790
04:05:09,399 --> 04:05:11,840
doesn't exist it will return a zero
5791
04:05:11,840 --> 04:05:14,279
which we could then increment and save
5792
04:05:14,279 --> 04:05:16,960
back into the map so that should work
5793
04:05:16,960 --> 04:05:17,840
just
5794
04:05:17,840 --> 04:05:21,520
fine at the end we can return
5795
04:05:21,520 --> 04:05:25,319
counts cool hopefully that makes
5796
04:05:25,319 --> 04:05:28,760
sense and we've got some test cases down
5797
04:05:28,760 --> 04:05:31,520
here Matthew George Drew Philip Bryant
5798
04:05:31,520 --> 04:05:33,159
and then a big list okay cool let's run
5799
04:05:33,159 --> 04:05:35,159
it and see what
5800
04:05:35,159 --> 04:05:38,960
happens whoops cannot use first Char
5801
04:05:38,960 --> 04:05:41,560
variable of type bite as Rune
5802
04:05:41,560 --> 04:05:45,640
value right so when you you index into a
5803
04:05:45,640 --> 04:05:48,720
string right so name is a single string
5804
04:05:48,720 --> 04:05:52,720
in go then it is a bite type um but we
5805
04:05:52,720 --> 04:05:54,439
want a rune type
5806
04:05:54,439 --> 04:05:56,840
so going go ahead and cast
5807
04:05:56,840 --> 04:06:00,399
it and run it
5808
04:06:01,720 --> 04:06:05,159
again cool uh Jing counts for 50 for the
5809
04:06:05,159 --> 04:06:08,720
first 50 names count for M Matthew is
5810
04:06:08,720 --> 04:06:12,680
three G George is One D Drew is four we
5811
04:06:12,680 --> 04:06:16,080
don't have any pan X so these counts
5812
04:06:16,080 --> 04:06:19,040
look totally plausible to me let's go
5813
04:06:19,040 --> 04:06:21,760
ahead and submit it it's time to talk
5814
04:06:21,760 --> 04:06:23,840
about first class and higher order
5815
04:06:23,840 --> 04:06:25,439
functions which are just really kind of
5816
04:06:25,439 --> 04:06:28,159
confusing complex terms for a much
5817
04:06:28,159 --> 04:06:32,279
simpler idea which is functions as data
5818
04:06:32,279 --> 04:06:33,840
a programming language is said to
5819
04:06:33,840 --> 04:06:36,319
support first class functions if it
5820
04:06:36,319 --> 04:06:39,080
allows you to pass around functions just
5821
04:06:39,080 --> 04:06:41,000
like you pass around any other variable
5822
04:06:41,000 --> 04:06:43,359
storing essentially an entire function
5823
04:06:43,359 --> 04:06:46,520
at as a value and then a function that
5824
04:06:46,520 --> 04:06:49,199
uses that first class function so a
5825
04:06:49,199 --> 04:06:51,479
function that accepts another function
5826
04:06:51,479 --> 04:06:54,399
as a parameter or returns a function as
5827
04:06:54,399 --> 04:06:56,760
a return value is said to be called a
5828
04:06:56,760 --> 04:06:59,239
higher order function let's take a look
5829
04:06:59,239 --> 04:07:02,080
at a concrete example okay so here we
5830
04:07:02,080 --> 04:07:04,840
have two functions add and multiply um
5831
04:07:04,840 --> 04:07:06,399
these are very simple functions you
5832
04:07:06,399 --> 04:07:08,359
should be able to understand uh what
5833
04:07:08,359 --> 04:07:10,560
they do just by looking at them for a
5834
04:07:10,560 --> 04:07:13,720
second um but here we have kind of an
5835
04:07:13,720 --> 04:07:15,159
interesting function it's called
5836
04:07:15,159 --> 04:07:19,720
Aggregate and it takes as input three
5837
04:07:19,720 --> 04:07:24,279
integers a b and c and it takes as input
5838
04:07:24,279 --> 04:07:27,159
an entire function right so it takes a
5839
04:07:27,159 --> 04:07:29,040
function and we're calling it here
5840
04:07:29,040 --> 04:07:31,680
arithmetic it's the fourth parameter to
5841
04:07:31,680 --> 04:07:34,279
the aggregate function and this function
5842
04:07:34,279 --> 04:07:36,800
has a specific signature this function
5843
04:07:36,800 --> 04:07:40,159
arithmetic must take as its parameters
5844
04:07:40,159 --> 04:07:41,159
two
5845
04:07:41,159 --> 04:07:43,920
integers right and return return an
5846
04:07:43,920 --> 04:07:46,159
integer itself and then the aggregate
5847
04:07:46,159 --> 04:07:48,479
function just returns an integer so what
5848
04:07:48,479 --> 04:07:51,520
does the aggregate function do well it
5849
04:07:51,520 --> 04:07:54,960
calls the function it was given Twice
5850
04:07:54,960 --> 04:07:58,199
first it calls it once with A and B and
5851
04:07:58,199 --> 04:08:00,880
then it calls it again with the results
5852
04:08:00,880 --> 04:08:04,159
of A and B and C so for example if we
5853
04:08:04,159 --> 04:08:07,880
call aggregate with the numbers 2 3 4
5854
04:08:07,880 --> 04:08:10,880
and the function add then it will add
5855
04:08:10,880 --> 04:08:12,560
all three of those numbers together
5856
04:08:12,560 --> 04:08:15,680
right which would in this case print n
5857
04:08:15,680 --> 04:08:17,239
and then we can also use that same
5858
04:08:17,239 --> 04:08:18,840
aggregate function with the same numbers
5859
04:08:18,840 --> 04:08:21,720
2 3 and four but this time pass in that
5860
04:08:21,720 --> 04:08:24,520
multiply function and here we'll get 24
5861
04:08:24,520 --> 04:08:26,520
right because we're multiplying um all
5862
04:08:26,520 --> 04:08:27,960
of the variables together instead of
5863
04:08:27,960 --> 04:08:30,159
adding them it's okay if this is a bit
5864
04:08:30,159 --> 04:08:32,359
confusing uh if this is the first time
5865
04:08:32,359 --> 04:08:35,040
you've worked with functions as data
5866
04:08:35,040 --> 04:08:36,960
take a second to really kind of stare at
5867
04:08:36,960 --> 04:08:39,680
this code and and figure out these this
5868
04:08:39,680 --> 04:08:41,880
crazy function signature um it's
5869
04:08:41,880 --> 04:08:43,640
actually not that complex once you kind
5870
04:08:43,640 --> 04:08:46,840
of get past the scary syntax um but but
5871
04:08:46,840 --> 04:08:48,119
don't feel bad if you have to pause the
5872
04:08:48,119 --> 04:08:50,399
video and take a good look let's get our
5873
04:08:50,399 --> 04:08:52,720
hands dirty with this assignment says
5874
04:08:52,720 --> 04:08:54,560
texo is launching a new email messaging
5875
04:08:54,560 --> 04:08:55,880
product
5876
04:08:55,880 --> 04:09:00,479
maleo I guess uh SMS and email right um
5877
04:09:00,479 --> 04:09:02,399
fix the compile time bug in the get
5878
04:09:02,399 --> 04:09:05,159
formatted messages function the function
5879
04:09:05,159 --> 04:09:06,560
body is correct but the function
5880
04:09:06,560 --> 04:09:09,439
signature is not okay so this formatter
5881
04:09:09,439 --> 04:09:12,000
function here looks like it will be a
5882
04:09:12,000 --> 04:09:13,560
problem let's go ahead and run the code
5883
04:09:13,560 --> 04:09:15,239
and see what kind of an error we get so
5884
04:09:15,239 --> 04:09:17,600
this is a compile time error uh saying
5885
04:09:17,600 --> 04:09:20,159
we have a syntax problem and that makes
5886
04:09:20,159 --> 04:09:21,640
sense because here we're we're basically
5887
04:09:21,640 --> 04:09:24,319
saying well the formatter input is a
5888
04:09:24,319 --> 04:09:26,560
function but we're not saying what type
5889
04:09:26,560 --> 04:09:29,359
of function it is and that doesn't work
5890
04:09:29,359 --> 04:09:31,080
because get formatted messages is going
5891
04:09:31,080 --> 04:09:33,000
to use the formatter function so it
5892
04:09:33,000 --> 04:09:34,720
needs to know essentially what
5893
04:09:34,720 --> 04:09:37,199
parameters it takes as input and what
5894
04:09:37,199 --> 04:09:39,560
it's going to return right uh kind of
5895
04:09:39,560 --> 04:09:41,960
like uh the arithmetic function here
5896
04:09:41,960 --> 04:09:44,159
takes two integers and returns an
5897
04:09:44,159 --> 04:09:46,279
integer uh we need to update this
5898
04:09:46,279 --> 04:09:49,000
function signature to kind of inform the
5899
04:09:49,000 --> 04:09:51,199
get formatted messages function what
5900
04:09:51,199 --> 04:09:53,399
this formatter function actually does so
5901
04:09:53,399 --> 04:09:55,960
if we look at the code because we know
5902
04:09:55,960 --> 04:09:59,920
the function body um is correct it looks
5903
04:09:59,920 --> 04:10:03,479
like formatter accepts a messages input
5904
04:10:03,479 --> 04:10:04,439
which is a
5905
04:10:04,439 --> 04:10:07,399
string and it's going to return whatever
5906
04:10:07,399 --> 04:10:09,239
should be appended to this formatted
5907
04:10:09,239 --> 04:10:10,840
messages slice which is a string so it
5908
04:10:10,840 --> 04:10:12,399
it looks like it takes one string as
5909
04:10:12,399 --> 04:10:14,720
input and and returns one string as
5910
04:10:14,720 --> 04:10:16,279
output that kind of makes sense for a
5911
04:10:16,279 --> 04:10:20,279
formatter function um so we say takes a
5912
04:10:20,279 --> 04:10:22,840
string and it returns a
5913
04:10:22,840 --> 04:10:24,960
string let's go ahead and run that and
5914
04:10:24,960 --> 04:10:27,960
see what we get cool at least it
5915
04:10:27,960 --> 04:10:30,080
compiled says thanks for getting back to
5916
04:10:30,080 --> 04:10:32,680
me which return thanks for getting back
5917
04:10:32,680 --> 04:10:34,119
to me kind
5918
04:10:34,119 --> 04:10:36,640
regards Okay cool so the ad signature
5919
04:10:36,640 --> 04:10:41,640
ads kinds to the end and add greeting
5920
04:10:41,640 --> 04:10:43,479
thanks for getting back to me hello
5921
04:10:43,479 --> 04:10:45,199
thanks for getting back to me cool let's
5922
04:10:45,199 --> 04:10:48,040
go ahead and run
5923
04:10:49,720 --> 04:10:53,800
that awesome so this might seem like an
5924
04:10:53,800 --> 04:10:56,560
exercise in complexity right like why do
5925
04:10:56,560 --> 04:10:58,520
I need to pass around functions as data
5926
04:10:58,520 --> 04:11:00,560
that just seems to add a bunch of well
5927
04:11:00,560 --> 04:11:02,439
needless complexity and for the most
5928
04:11:02,439 --> 04:11:04,960
part you're right you really should only
5929
04:11:04,960 --> 04:11:06,520
use higher order and first class
5930
04:11:06,520 --> 04:11:08,279
functions if you have a very good reason
5931
04:11:08,279 --> 04:11:10,479
to do so so the question is kind of what
5932
04:11:10,479 --> 04:11:13,920
are the good reasons to do so well first
5933
04:11:13,920 --> 04:11:15,239
class and higher order functions are
5934
04:11:15,239 --> 04:11:17,720
very often used for um on the back end
5935
04:11:17,720 --> 04:11:20,560
side of the stack HTTP handlers right so
5936
04:11:20,560 --> 04:11:21,960
if you have some front-end code that
5937
04:11:21,960 --> 04:11:23,920
needs to reach out to a backend server
5938
04:11:23,920 --> 04:11:26,720
and get some data those handlers are
5939
04:11:26,720 --> 04:11:29,439
typically first class or higher order
5940
04:11:29,439 --> 04:11:32,800
functions because we need some code
5941
04:11:32,800 --> 04:11:35,000
right the Handler function to run like
5942
04:11:35,000 --> 04:11:36,600
in the future we don't want to call it
5943
04:11:36,600 --> 04:11:38,359
now right we want to call it when
5944
04:11:38,359 --> 04:11:40,960
something happens in the UI World kind
5945
04:11:40,960 --> 04:11:42,640
of on the on the front end side of the
5946
04:11:42,640 --> 04:11:45,239
stack uh they're often used in onclick
5947
04:11:45,239 --> 04:11:47,479
handlers right so I write a function and
5948
04:11:47,479 --> 04:11:49,199
I don't necessarily call it when my
5949
04:11:49,199 --> 04:11:51,399
program starts but I call it when
5950
04:11:51,399 --> 04:11:52,800
something interesting happens like the
5951
04:11:52,800 --> 04:11:55,520
user clicks a button right when a button
5952
04:11:55,520 --> 04:11:58,080
click happens I want to call you know
5953
04:11:58,080 --> 04:12:00,760
this function and so typically in code
5954
04:12:00,760 --> 04:12:02,319
we can represent that with a higher
5955
04:12:02,319 --> 04:12:05,880
order function we say onclick do this
5956
04:12:05,880 --> 04:12:07,800
and then we kind of give it the name of
5957
04:12:07,800 --> 04:12:09,720
a function to call and then just to
5958
04:12:09,720 --> 04:12:12,040
review the definitions uh very quickly a
5959
04:12:12,040 --> 04:12:14,600
first class function is a function that
5960
04:12:14,600 --> 04:12:16,920
is kind of being passed around as data
5961
04:12:16,920 --> 04:12:19,439
and a higher order function is the
5962
04:12:19,439 --> 04:12:21,359
function that's using that first class
5963
04:12:21,359 --> 04:12:22,479
function right it's a function that
5964
04:12:22,479 --> 04:12:24,680
accepts a function as input or returns
5965
04:12:24,680 --> 04:12:27,159
it um as one of its return values so the
5966
04:12:27,159 --> 04:12:28,760
question is what is a higher order
5967
04:12:28,760 --> 04:12:31,000
function um it is a function that takes
5968
04:12:31,000 --> 04:12:33,439
another function as an argument or or
5969
04:12:33,439 --> 04:12:35,119
returns a function um but it's not a
5970
04:12:35,119 --> 04:12:36,560
function that is first in the call stack
5971
04:12:36,560 --> 04:12:40,399
or a function with Superior
5972
04:12:40,960 --> 04:12:43,720
logic so the next question is what is a
5973
04:12:43,720 --> 04:12:46,720
first class function um it is a function
5974
04:12:46,720 --> 04:12:48,720
that is treated like any other variable
5975
04:12:48,720 --> 04:12:49,920
right it's a function that we're going
5976
04:12:49,920 --> 04:12:53,000
to pass around as as data to probably be
5977
04:12:53,000 --> 04:12:55,439
called sometime in the future function
5978
04:12:55,439 --> 04:12:58,319
currying is kind of like a special kind
5979
04:12:58,319 --> 04:13:01,760
of higher order function it's a function
5980
04:13:01,760 --> 04:13:03,760
that accepts another function as input
5981
04:13:03,760 --> 04:13:05,720
we're kind of familiar with that idea
5982
04:13:05,720 --> 04:13:09,279
but that also returns a new function as
5983
04:13:09,279 --> 04:13:11,680
its output so it's kind of a way of like
5984
04:13:11,680 --> 04:13:14,760
enhancing a function with new Behavior
5985
04:13:14,760 --> 04:13:16,560
it's kind of a weird concept to think
5986
04:13:16,560 --> 04:13:18,720
about abstractly so let's jump into this
5987
04:13:18,720 --> 04:13:21,840
example okay so here we have a function
5988
04:13:21,840 --> 04:13:25,399
called self math and self math is the
5989
04:13:25,399 --> 04:13:27,239
curried function it takes a math
5990
04:13:27,239 --> 04:13:29,800
function as input that accepts two
5991
04:13:29,800 --> 04:13:32,479
integers and returns an integer and it
5992
04:13:32,479 --> 04:13:35,840
returns a new function that only takes a
5993
04:13:35,840 --> 04:13:38,000
single integer as input and returns an
5994
04:13:38,000 --> 04:13:40,479
integer and then what it does again it
5995
04:13:40,479 --> 04:13:42,119
returns a function right that takes a
5996
04:13:42,119 --> 04:13:44,359
single integer an input and returns an
5997
04:13:44,359 --> 04:13:46,479
integer and it calls the math function
5998
04:13:46,479 --> 04:13:49,880
that it was given with the same input
5999
04:13:49,880 --> 04:13:52,479
twice right so we're kind of mapping a
6000
04:13:52,479 --> 04:13:54,960
function that accepts two uh different
6001
04:13:54,960 --> 04:13:57,319
integers into a function that kind of
6002
04:13:57,319 --> 04:13:59,680
forces both of those integers to be the
6003
04:13:59,680 --> 04:14:02,439
same integer so like what does that do
6004
04:14:02,439 --> 04:14:04,680
in practice well basically we can use
6005
04:14:04,680 --> 04:14:08,439
our self math function to convert a
6006
04:14:08,439 --> 04:14:11,880
multiply function into a square function
6007
04:14:11,880 --> 04:14:14,040
right so multiply takes X and Y and
6008
04:14:14,040 --> 04:14:16,319
multiplies them together this new Square
6009
04:14:16,319 --> 04:14:18,600
function that we created dynamically
6010
04:14:18,600 --> 04:14:21,520
only takes a single value and multiplies
6011
04:14:21,520 --> 04:14:24,520
it by itself right um same with the add
6012
04:14:24,520 --> 04:14:26,600
function we can kind of use the self
6013
04:14:26,600 --> 04:14:28,720
maath function to convert it into a
6014
04:14:28,720 --> 04:14:31,080
function that just doubles its input
6015
04:14:31,080 --> 04:14:33,720
right so we Square Five we get 25 we
6016
04:14:33,720 --> 04:14:36,680
double five and we get 10 so when would
6017
04:14:36,680 --> 04:14:39,000
currying be used in the real world uh to
6018
04:14:39,000 --> 04:14:41,159
be honest I don't use it very often um
6019
04:14:41,159 --> 04:14:43,560
but in backend server land I do
6020
04:14:43,560 --> 04:14:45,399
sometimes use it for middleware
6021
04:14:45,399 --> 04:14:48,319
functions so a middleware function is a
6022
04:14:48,319 --> 04:14:50,840
function that basically changes the HTTP
6023
04:14:50,840 --> 04:14:53,760
Handler of a backend server um and just
6024
04:14:53,760 --> 04:14:56,000
as a spoiler we will be covering this in
6025
04:14:56,000 --> 04:14:58,600
the project at the end of this course um
6026
04:14:58,600 --> 04:15:01,000
but it's for kind of injecting some
6027
04:15:01,000 --> 04:15:03,399
additional logic into a function so say
6028
04:15:03,399 --> 04:15:06,199
we have an HTTP Handler that accepts as
6029
04:15:06,199 --> 04:15:09,159
input a user ID and returns an entire
6030
04:15:09,159 --> 04:15:11,080
user object with you know say their
6031
04:15:11,080 --> 04:15:12,720
first name their last name that sort of
6032
04:15:12,720 --> 04:15:13,640
thing
6033
04:15:13,640 --> 04:15:15,960
um a middleware function might do
6034
04:15:15,960 --> 04:15:18,159
something like require an authentication
6035
04:15:18,159 --> 04:15:20,520
token right so we can write all of our
6036
04:15:20,520 --> 04:15:23,119
HTTP handlers that serve different data
6037
04:15:23,119 --> 04:15:25,119
sort of independently and then we can
6038
04:15:25,119 --> 04:15:27,960
use a curried function to kind of
6039
04:15:27,960 --> 04:15:30,560
require authentication Logic on all of
6040
04:15:30,560 --> 04:15:34,119
our HTTP handlers um in fact in go
6041
04:15:34,119 --> 04:15:36,760
currying is very often used to handle
6042
04:15:36,760 --> 04:15:39,319
the sort of middleware problem now if
6043
04:15:39,319 --> 04:15:41,239
all of that went straight over your head
6044
04:15:41,239 --> 04:15:43,319
again that's okay it's kind of hard to
6045
04:15:43,319 --> 04:15:45,479
talk about um something that we're not
6046
04:15:45,479 --> 04:15:47,520
working on at the moment so again we're
6047
04:15:47,520 --> 04:15:49,920
going to cover middleware and HTTP
6048
04:15:49,920 --> 04:15:51,520
handlers in the project at the end of
6049
04:15:51,520 --> 04:15:53,600
this course so stick around for that so
6050
04:15:53,600 --> 04:15:55,640
jumping into the assignment it says the
6051
04:15:55,640 --> 04:15:58,399
maleo API needs a very robust error
6052
04:15:58,399 --> 04:16:00,119
logging system so we can see when things
6053
04:16:00,119 --> 04:16:02,560
are going arai in the back end we need a
6054
04:16:02,560 --> 04:16:05,159
function that can create a custom logger
6055
04:16:05,159 --> 04:16:07,359
a function that prints to the console
6056
04:16:07,359 --> 04:16:10,199
given a specific formatter Okay cool so
6057
04:16:10,199 --> 04:16:13,359
this function get logger should return a
6058
04:16:13,359 --> 04:16:15,880
logger which is a function right it's a
6059
04:16:15,880 --> 04:16:19,199
function that takes two strings as input
6060
04:16:19,199 --> 04:16:21,399
and apparently prints them because it
6061
04:16:21,399 --> 04:16:24,560
doesn't return anything right and get
6062
04:16:24,560 --> 04:16:27,040
logger takes as input a formatter which
6063
04:16:27,040 --> 04:16:29,680
accepts two strings as input and returns
6064
04:16:29,680 --> 04:16:31,040
a single
6065
04:16:31,040 --> 04:16:32,960
string okay so it says complete the get
6066
04:16:32,960 --> 04:16:34,279
logger function it should return a new
6067
04:16:34,279 --> 04:16:36,439
function um the inputs should be passed
6068
04:16:36,439 --> 04:16:37,760
into the format or function the order
6069
04:16:37,760 --> 04:16:40,159
they given to the loger function okay
6070
04:16:40,159 --> 04:16:42,960
so let's start writing this so we're
6071
04:16:42,960 --> 04:16:44,840
going to return a
6072
04:16:44,840 --> 04:16:49,439
function that takes two strings as input
6073
04:16:49,439 --> 04:16:52,680
right and I'm going to reference up here
6074
04:16:52,680 --> 04:16:54,720
for the syntax we're interested in so
6075
04:16:54,720 --> 04:16:56,840
I'm going to do a
6076
04:16:56,840 --> 04:17:02,319
string B string all right and this
6077
04:17:02,319 --> 04:17:04,279
function should return nothing so we can
6078
04:17:04,279 --> 04:17:05,680
just go straight into the
6079
04:17:05,680 --> 04:17:07,800
body and it
6080
04:17:07,800 --> 04:17:10,399
says this function prints the formatted
6081
04:17:10,399 --> 04:17:13,199
inputs so formatter returns a single
6082
04:17:13,199 --> 04:17:16,040
string so we can just do fmt do print
6083
04:17:16,040 --> 04:17:18,279
line and we're going to need to oh we
6084
04:17:18,279 --> 04:17:21,720
already have fmt imported perfect so we
6085
04:17:21,720 --> 04:17:24,000
need to print the result of the
6086
04:17:24,000 --> 04:17:25,760
formatter functions it's going to be
6087
04:17:25,760 --> 04:17:29,760
formatter and we'll pass into the format
6088
04:17:29,760 --> 04:17:32,680
A and
6089
04:17:33,560 --> 04:17:35,840
B right so we're returning a new
6090
04:17:35,840 --> 04:17:39,119
function a logger that accepts two
6091
04:17:39,119 --> 04:17:42,960
inputs formats them given the formatter
6092
04:17:42,960 --> 04:17:45,000
that we were given right and then just
6093
04:17:45,000 --> 04:17:47,199
prints it to the console cool let's go
6094
04:17:47,199 --> 04:17:49,680
ahead and run
6095
04:17:51,040 --> 04:17:53,439
that error on database server out of
6096
04:17:53,439 --> 04:17:55,800
memory error on database server CPU is
6097
04:17:55,800 --> 04:17:58,319
pegged this all looks good let's see how
6098
04:17:58,319 --> 04:17:59,960
the test site actually
6099
04:17:59,960 --> 04:18:02,159
works it looks like these are the
6100
04:18:02,159 --> 04:18:04,439
formatters colon delimit and comma
6101
04:18:04,439 --> 04:18:06,239
delimit and if you take a look at our
6102
04:18:06,239 --> 04:18:08,800
messages some are delimited by a colon
6103
04:18:08,800 --> 04:18:11,520
some are delimited by a
6104
04:18:11,520 --> 04:18:15,680
comma so that's how that is working very
6105
04:18:15,680 --> 04:18:16,960
cool all right I'm going to go ahead and
6106
04:18:16,960 --> 04:18:19,000
submit that I think this is
6107
04:18:19,000 --> 04:18:21,279
correct time to talk about the defer
6108
04:18:21,279 --> 04:18:23,920
keyword uh this is a really kind of
6109
04:18:23,920 --> 04:18:26,800
unique thing to go um if you're familiar
6110
04:18:26,800 --> 04:18:28,319
with any other programming languages
6111
04:18:28,319 --> 04:18:30,800
it's unlikely um that you're familiar
6112
04:18:30,800 --> 04:18:33,040
with something similar to the defer
6113
04:18:33,040 --> 04:18:35,680
keyword um at least I've never used it
6114
04:18:35,680 --> 04:18:39,040
or used a concept uh that is similar to
6115
04:18:39,040 --> 04:18:41,640
the defer keyword in another language um
6116
04:18:41,640 --> 04:18:43,399
fairly go specific
6117
04:18:43,399 --> 04:18:46,359
okay so the defer keyword allows us to
6118
04:18:46,359 --> 04:18:50,040
execute some function at the end of the
6119
04:18:50,040 --> 04:18:51,720
current function or when the current
6120
04:18:51,720 --> 04:18:55,080
function exits the defer keyword is very
6121
04:18:55,080 --> 04:18:57,800
often used as sort of a cleanup step um
6122
04:18:57,800 --> 04:19:00,119
for example in this in this function
6123
04:19:00,119 --> 04:19:01,520
here copy
6124
04:19:01,520 --> 04:19:05,000
file we open a source file from the file
6125
04:19:05,000 --> 04:19:08,279
system and then we defer closing the
6126
04:19:08,279 --> 04:19:11,359
file right so every time you open access
6127
04:19:11,359 --> 04:19:13,040
to a file in the file system you need to
6128
04:19:13,040 --> 04:19:15,520
remember to close that file otherwise
6129
04:19:15,520 --> 04:19:17,319
you're sort of wasting Computer
6130
04:19:17,319 --> 04:19:21,560
Resources um the problem is closing the
6131
04:19:21,560 --> 04:19:23,399
file at the end of the function is a
6132
04:19:23,399 --> 04:19:25,239
little tedious because we have multiple
6133
04:19:25,239 --> 04:19:26,880
return statements here so we'd kind of
6134
04:19:26,880 --> 04:19:28,880
have to close it before both of them if
6135
04:19:28,880 --> 04:19:30,640
that makes sense by using the defer
6136
04:19:30,640 --> 04:19:32,560
keyword we can just tell the go
6137
04:19:32,560 --> 04:19:34,680
programming language hey I want to call
6138
04:19:34,680 --> 04:19:35,880
source.
6139
04:19:35,880 --> 04:19:38,600
close right before the copy file
6140
04:19:38,600 --> 04:19:41,359
function ends and just defers it kind of
6141
04:19:41,359 --> 04:19:43,319
until the end and it will only call it
6142
04:19:43,319 --> 04:19:46,040
once um no matter where the function
6143
04:19:46,040 --> 04:19:48,439
actually returns from on to the
6144
04:19:48,439 --> 04:19:50,439
assignment it says there is a bug in the
6145
04:19:50,439 --> 04:19:52,640
log and delete function fix it let me
6146
04:19:52,640 --> 04:19:54,239
expand this a little bit so we can see
6147
04:19:54,239 --> 04:19:56,560
it this function should always delete
6148
04:19:56,560 --> 04:19:58,720
the user from the users map Okay cool so
6149
04:19:58,720 --> 04:20:00,399
we're given a user's map we're given a
6150
04:20:00,399 --> 04:20:03,520
name and we know that Maps uh are passed
6151
04:20:03,520 --> 04:20:06,159
by reference so if we delete a map uh it
6152
04:20:06,159 --> 04:20:10,760
will be deleted in the callers code as
6153
04:20:10,760 --> 04:20:13,359
well um it should return log string that
6154
04:20:13,359 --> 04:20:14,720
indicates to the caller some information
6155
04:20:14,720 --> 04:20:17,359
about the user's deletion okay so delete
6156
04:20:17,359 --> 04:20:19,279
should always happen and then the kind
6157
04:20:19,279 --> 04:20:22,720
of the appropriate log message should be
6158
04:20:22,720 --> 04:20:24,760
returned from the function that makes
6159
04:20:24,760 --> 04:20:26,920
sense um but it looks like there's a bug
6160
04:20:26,920 --> 04:20:28,000
okay so let's go ahead and run the code
6161
04:20:28,000 --> 04:20:30,520
and see what we
6162
04:20:31,119 --> 04:20:34,279
get so initial users Brianna Elon John
6163
04:20:34,279 --> 04:20:37,600
Cade attempting to delete John deleting
6164
04:20:37,600 --> 04:20:39,760
Santa deleting
6165
04:20:39,760 --> 04:20:42,680
Cade okay so John's still there the
6166
04:20:42,680 --> 04:20:45,080
problem is that we're trying to delete
6167
04:20:45,080 --> 04:20:47,439
JN but Jon's not actually getting
6168
04:20:47,439 --> 04:20:49,800
deleted right so we need to fix that
6169
04:20:49,800 --> 04:20:55,199
bug and if we take a look John is an
6170
04:20:55,199 --> 04:20:59,439
admin and here we are returning log
6171
04:20:59,439 --> 04:21:02,199
admin but we're not deleting admins so
6172
04:21:02,199 --> 04:21:03,880
so that's that's the real problem right
6173
04:21:03,880 --> 04:21:05,760
the users should always be
6174
04:21:05,760 --> 04:21:09,600
deleted now here's the problem we can do
6175
04:21:09,600 --> 04:21:14,600
this um this will work if I run this my
6176
04:21:14,600 --> 04:21:16,840
guess is this should fix the bug yep JN
6177
04:21:16,840 --> 04:21:18,920
is no longer there he was deleted
6178
04:21:18,920 --> 04:21:21,800
successfully but this is kind of gross
6179
04:21:21,800 --> 04:21:23,520
right we we're calling delete three
6180
04:21:23,520 --> 04:21:26,720
different times um what if in the future
6181
04:21:26,720 --> 04:21:29,399
we add another case and we forget we
6182
04:21:29,399 --> 04:21:30,920
forget to add the delete again we'll
6183
04:21:30,920 --> 04:21:34,319
have another bug um well what we could
6184
04:21:34,319 --> 04:21:37,479
do what we could do is just delete at
6185
04:21:37,479 --> 04:21:38,560
the top
6186
04:21:38,560 --> 04:21:40,680
once
6187
04:21:40,680 --> 04:21:44,199
right but the problem is if we do
6188
04:21:44,199 --> 04:21:47,239
that we delete the user from the users
6189
04:21:47,239 --> 04:21:50,680
map too soon and now this okay variable
6190
04:21:50,680 --> 04:21:52,359
that's checking for existence so it can
6191
04:21:52,359 --> 04:21:54,840
change which log is returned like that
6192
04:21:54,840 --> 04:21:57,159
logic won't work it will just always be
6193
04:21:57,159 --> 04:21:59,479
not okay so we'll always just return log
6194
04:21:59,479 --> 04:22:02,600
not found so that's a problem what we
6195
04:22:02,600 --> 04:22:06,880
can do is defer the deletion so this
6196
04:22:06,880 --> 04:22:08,840
code says we'll call this delete
6197
04:22:08,840 --> 04:22:11,600
function right before login delete
6198
04:22:11,600 --> 04:22:14,640
returns so it it's almost like um the
6199
04:22:14,640 --> 04:22:17,119
equivalent of you know adding this at
6200
04:22:17,119 --> 04:22:18,880
every step of the way so let's go ahead
6201
04:22:18,880 --> 04:22:21,800
and run that make sure it
6202
04:22:22,119 --> 04:22:25,720
works John's there John's gone perfect
6203
04:22:25,720 --> 04:22:28,760
and we have different logs getting
6204
04:22:28,760 --> 04:22:29,800
returned so that looks good I'm going to
6205
04:22:29,800 --> 04:22:32,159
go ahead and submit that this chapter is
6206
04:22:32,159 --> 04:22:35,359
not called Advanced functions uh for no
6207
04:22:35,359 --> 04:22:37,600
reason let's talk about closures
6208
04:22:37,600 --> 04:22:40,239
closures are um I don't want to like
6209
04:22:40,239 --> 04:22:41,560
intimidate you and say they're really
6210
04:22:41,560 --> 04:22:43,479
hard but they're a little weird so let's
6211
04:22:43,479 --> 04:22:45,840
let's take a second to understand uh how
6212
04:22:45,840 --> 04:22:48,119
they work okay a closure is a function
6213
04:22:48,119 --> 04:22:49,960
that references variables from outside
6214
04:22:49,960 --> 04:22:52,199
its own function body the function May
6215
04:22:52,199 --> 04:22:53,600
access and assign to the referenced
6216
04:22:53,600 --> 04:22:57,960
variables so in this example the concat
6217
04:22:57,960 --> 04:23:00,080
function returns a function that has a
6218
04:23:00,080 --> 04:23:02,319
reference to the enclosed doc value okay
6219
04:23:02,319 --> 04:23:06,159
so concat is a function it returns a new
6220
04:23:06,159 --> 04:23:07,960
function right and that's what's
6221
04:23:07,960 --> 04:23:10,359
happening
6222
04:23:10,479 --> 04:23:14,960
here and it's enclosed using this doc
6223
04:23:14,960 --> 04:23:17,239
string within the function so it's
6224
04:23:17,239 --> 04:23:19,040
getting initialized outside of the
6225
04:23:19,040 --> 04:23:20,760
function and then getting used within
6226
04:23:20,760 --> 04:23:24,359
the function and what happens is
6227
04:23:24,359 --> 04:23:27,920
basically when we call concat to to make
6228
04:23:27,920 --> 04:23:30,960
this new like concat
6229
04:23:30,960 --> 04:23:33,600
function we're saving a reference to
6230
04:23:33,600 --> 04:23:36,840
this doc variable so every kind of
6231
04:23:36,840 --> 04:23:39,640
concurrent not concurrent every uh
6232
04:23:39,640 --> 04:23:43,000
subsequent call to this function that is
6233
04:23:43,000 --> 04:23:46,600
returned we'll keep adding on right plus
6234
04:23:46,600 --> 04:23:49,359
equals word we'll keep adding on to the
6235
04:23:49,359 --> 04:23:51,720
same doc variable so let's look at what
6236
04:23:51,720 --> 04:23:54,760
that uh kind of looks like in usage so
6237
04:23:54,760 --> 04:23:57,040
we're calling concat and we're getting
6238
04:23:57,040 --> 04:23:59,359
back this Harry Potter aggregator right
6239
04:23:59,359 --> 04:24:02,199
that's what we're assigning this
6240
04:24:02,199 --> 04:24:04,600
function we're assigning this function
6241
04:24:04,600 --> 04:24:06,720
into this variable so Harry Potter
6242
04:24:06,720 --> 04:24:09,159
aggregator is a function right it's it's
6243
04:24:09,159 --> 04:24:10,560
specifically it's this function right
6244
04:24:10,560 --> 04:24:12,640
here cool and then we're going to call
6245
04:24:12,640 --> 04:24:15,279
it with mis and then we'll call it again
6246
04:24:15,279 --> 04:24:18,040
with and and Mrs dersley Right we're
6247
04:24:18,040 --> 04:24:19,520
calling it over and over and over and
6248
04:24:19,520 --> 04:24:21,080
what's happening under the hood is we
6249
04:24:21,080 --> 04:24:24,920
are appending those words Mr and Mrs
6250
04:24:24,920 --> 04:24:27,760
onto that doc variable so at the end
6251
04:24:27,760 --> 04:24:29,560
when we finally
6252
04:24:29,560 --> 04:24:32,479
print what's being returned which is the
6253
04:24:32,479 --> 04:24:35,119
doc variable itself we get the full
6254
04:24:35,119 --> 04:24:37,279
sentence Mr and Mrs Durley of number
6255
04:24:37,279 --> 04:24:39,680
four privet drive now closures are one
6256
04:24:39,680 --> 04:24:42,040
of those Advanced things that you to be
6257
04:24:42,040 --> 04:24:44,479
honest again don't usually use in
6258
04:24:44,479 --> 04:24:46,319
production code maybe every once in a
6259
04:24:46,319 --> 04:24:48,560
while um but they're very important to
6260
04:24:48,560 --> 04:24:51,199
understand because it is very common to
6261
04:24:51,199 --> 04:24:54,000
have kind of bugs surrounding closures
6262
04:24:54,000 --> 04:24:55,359
so if you don't understand what's going
6263
04:24:55,359 --> 04:24:57,000
on under the hood it can be really hard
6264
04:24:57,000 --> 04:25:00,000
to debug kind of complex code that might
6265
04:25:00,000 --> 04:25:02,840
even be using closures by accident so
6266
04:25:02,840 --> 04:25:04,880
the assignment says keeping track of how
6267
04:25:04,880 --> 04:25:06,960
many emails we send is Mission critical
6268
04:25:06,960 --> 04:25:10,040
at maleo complete the adder function
6269
04:25:10,040 --> 04:25:11,960
it's return a function that adds its
6270
04:25:11,960 --> 04:25:14,840
input an integer to an enclosed sum
6271
04:25:14,840 --> 04:25:16,960
value and then Returns the new sum in
6272
04:25:16,960 --> 04:25:18,399
other words it keeps a running total of
6273
04:25:18,399 --> 04:25:20,760
the sum variable uh within a closure
6274
04:25:20,760 --> 04:25:21,920
Okay cool so it's going to be very
6275
04:25:21,920 --> 04:25:24,119
similar to this right so we'll start by
6276
04:25:24,119 --> 04:25:26,760
creating a sum value so sum colon equals
6277
04:25:26,760 --> 04:25:28,279
zero right we're we're working with
6278
04:25:28,279 --> 04:25:31,040
integers not flows and then we need to
6279
04:25:31,040 --> 04:25:33,640
return a function with the signature so
6280
04:25:33,640 --> 04:25:39,720
return Funk X int returns an
6281
04:25:39,720 --> 04:25:42,920
INT oh not not returns an X returns an
6282
04:25:42,920 --> 04:25:47,279
INT and then here we need to add X to
6283
04:25:47,279 --> 04:25:50,560
sum right so sum plus equals
6284
04:25:50,560 --> 04:25:53,159
X and then we need to
6285
04:25:53,159 --> 04:25:55,199
return the new
6286
04:25:55,199 --> 04:25:57,920
sum right and then if we go take a look
6287
04:25:57,920 --> 04:26:02,760
at this test case let's
6288
04:26:03,800 --> 04:26:07,760
see okay so we're adding these email
6289
04:26:07,760 --> 04:26:10,279
bills with a bunch of different
6290
04:26:10,279 --> 04:26:14,119
numbers the test Ates over the bills ah
6291
04:26:14,119 --> 04:26:15,840
okay so we're creating two adders here
6292
04:26:15,840 --> 04:26:17,840
so we're creating a count adder and a
6293
04:26:17,840 --> 04:26:19,319
cost
6294
04:26:19,319 --> 04:26:22,840
adder and then let me expand
6295
04:26:22,840 --> 04:26:25,119
this going to just make that basically
6296
04:26:25,119 --> 04:26:26,399
full
6297
04:26:26,399 --> 04:26:29,119
screen so the test actually creates two
6298
04:26:29,119 --> 04:26:31,159
different adders two different instances
6299
04:26:31,159 --> 04:26:33,720
of our Adder function right and one of
6300
04:26:33,720 --> 04:26:36,479
them is going to count how many bills
6301
04:26:36,479 --> 04:26:38,800
there are and the other one will keep a
6302
04:26:38,800 --> 04:26:42,040
running total of the cost of all of the
6303
04:26:42,040 --> 04:26:43,119
builds
6304
04:26:43,119 --> 04:26:45,199
right so we're actually using our
6305
04:26:45,199 --> 04:26:47,319
function twice for two different things
6306
04:26:47,319 --> 04:26:50,600
and they'll each have their own enclosed
6307
04:26:50,600 --> 04:26:53,279
some count that they keep track of
6308
04:26:53,279 --> 04:26:54,560
differently right the count will have
6309
04:26:54,560 --> 04:26:56,239
its own the cost will have its own the
6310
04:26:56,239 --> 04:26:58,000
count is simple it just adds one every
6311
04:26:58,000 --> 04:27:00,119
time the cost will add the actual cost
6312
04:27:00,119 --> 04:27:04,319
in pennies cool let's go ahead and run
6313
04:27:05,080 --> 04:27:08,080
this so um and these values are getting
6314
04:27:08,080 --> 04:27:10,040
interpolated into this message so youve
6315
04:27:10,040 --> 04:27:13,080
sent one email cost 45 cents two emails
6316
04:27:13,080 --> 04:27:16,479
77 cents three emails 120 cents so like
6317
04:27:16,479 --> 04:27:18,000
all of these are going up that makes
6318
04:27:18,000 --> 04:27:19,439
sense I mean we could even go verify
6319
04:27:19,439 --> 04:27:23,840
right 45 + 32 77 that looks right to me
6320
04:27:23,840 --> 04:27:26,319
let's go ahead and submit it all right
6321
04:27:26,319 --> 04:27:28,560
we're on to a little quiz about closures
6322
04:27:28,560 --> 04:27:31,000
can a closure mutate a variable outside
6323
04:27:31,000 --> 04:27:34,199
of its body uh yes that's basically the
6324
04:27:34,199 --> 04:27:36,760
entire point of a closure another little
6325
04:27:36,760 --> 04:27:38,800
review question here says when a
6326
04:27:38,800 --> 04:27:40,960
variable is enclosed in a closure the
6327
04:27:40,960 --> 04:27:44,479
enclosing function has access to blank a
6328
04:27:44,479 --> 04:27:47,159
copy of the value or a mutable reference
6329
04:27:47,159 --> 04:27:49,720
to the original value well if it was a
6330
04:27:49,720 --> 04:27:51,800
copy then our sum never would have
6331
04:27:51,800 --> 04:27:53,000
worked right because we'd be working
6332
04:27:53,000 --> 04:27:54,560
with a new copy of the sum variable
6333
04:27:54,560 --> 04:27:56,439
every time so it's actually a mutable
6334
04:27:56,439 --> 04:27:58,720
reference to the original value we've
6335
04:27:58,720 --> 04:28:00,880
already been using Anonymous functions
6336
04:28:00,880 --> 04:28:02,840
kind of all throughout this chapter um
6337
04:28:02,840 --> 04:28:04,199
now let's kind of just talk about what
6338
04:28:04,199 --> 04:28:06,359
they are so Anonymous functions are
6339
04:28:06,359 --> 04:28:07,560
exactly what they sound like they're
6340
04:28:07,560 --> 04:28:09,880
just functions that do not have a name
6341
04:28:09,880 --> 04:28:12,840
they have no name um Anonymous functions
6342
04:28:12,840 --> 04:28:14,080
are really useful when you're kind of
6343
04:28:14,080 --> 04:28:16,800
just oneoff maybe creating a closure
6344
04:28:16,800 --> 04:28:19,119
you're returning a new type of function
6345
04:28:19,119 --> 04:28:21,800
um if if you're not defining the
6346
04:28:21,800 --> 04:28:23,720
function for like use across the entire
6347
04:28:23,720 --> 04:28:25,199
program but you're more using it as a
6348
04:28:25,199 --> 04:28:27,279
value using it as a first class function
6349
04:28:27,279 --> 04:28:28,520
um that's when you're going to see
6350
04:28:28,520 --> 04:28:31,119
Anonymous functions use the most so as
6351
04:28:31,119 --> 04:28:35,720
an example um here we have an anonymous
6352
04:28:35,720 --> 04:28:37,640
function declaration right we're
6353
04:28:37,640 --> 04:28:39,600
creating a new function we're defining
6354
04:28:39,600 --> 04:28:41,560
its internal logic it's its function
6355
04:28:41,560 --> 04:28:44,080
body um but we're not giving it a name
6356
04:28:44,080 --> 04:28:45,960
right there's no name uh for this
6357
04:28:45,960 --> 04:28:48,439
function that we're passing into do math
6358
04:28:48,439 --> 04:28:50,399
it is an anonymous function the
6359
04:28:50,399 --> 04:28:52,399
assignment says complete the print
6360
04:28:52,399 --> 04:28:55,359
reports function call Print cost report
6361
04:28:55,359 --> 04:28:57,600
once for each message okay let's take a
6362
04:28:57,600 --> 04:29:00,560
look print cost report looks like it
6363
04:29:00,560 --> 04:29:04,119
takes as input a function cost
6364
04:29:04,119 --> 04:29:08,119
calculator great okay um call Print cost
6365
04:29:08,119 --> 04:29:09,760
report once for each message pass an
6366
04:29:09,760 --> 04:29:11,040
anonymous function as the cost
6367
04:29:11,040 --> 04:29:13,040
calculator that returns an int equal to
6368
04:29:13,040 --> 04:29:15,279
twice the length of the input message
6369
04:29:15,279 --> 04:29:18,239
okay let's go ahead and do that
6370
04:29:18,239 --> 04:29:20,359
so um it says to do it once for each
6371
04:29:20,359 --> 04:29:21,840
message yeah so
6372
04:29:21,840 --> 04:29:24,000
four
6373
04:29:24,000 --> 04:29:27,800
message range
6374
04:29:30,040 --> 04:29:33,119
messages call Print cost report print
6375
04:29:33,119 --> 04:29:34,800
cost
6376
04:29:34,800 --> 04:29:37,840
report and print cost report takes a
6377
04:29:37,840 --> 04:29:41,600
cost calculator which is a function that
6378
04:29:41,600 --> 04:29:43,640
takes us string and returns an
6379
04:29:43,640 --> 04:29:46,319
INT said to use an anonymous function
6380
04:29:46,319 --> 04:29:48,239
right so funks we need to actually
6381
04:29:48,239 --> 04:29:52,040
Define our X string int we need to
6382
04:29:52,040 --> 04:29:55,119
define the body um that returns an INT
6383
04:29:55,119 --> 04:29:56,840
equal to twice the length of the input
6384
04:29:56,840 --> 04:29:59,080
message so X is a string in fact I'm
6385
04:29:59,080 --> 04:30:02,960
going to name this um message and we'll
6386
04:30:02,960 --> 04:30:05,119
return the length of
6387
04:30:05,119 --> 04:30:07,439
message time
6388
04:30:07,439 --> 04:30:09,840
2 right twice the length of the input
6389
04:30:09,840 --> 04:30:11,840
message and then print cost report takes
6390
04:30:11,840 --> 04:30:15,000
us second parameter which is the message
6391
04:30:15,000 --> 04:30:18,000
itself
6392
04:30:18,520 --> 04:30:20,920
right I think am I am I reading this
6393
04:30:20,920 --> 04:30:24,359
correctly cost report FES the calculator
6394
04:30:24,359 --> 04:30:25,920
and the message itself yep because it's
6395
04:30:25,920 --> 04:30:27,199
going to it's then going to call the
6396
04:30:27,199 --> 04:30:29,199
cost calculator and then and then print
6397
04:30:29,199 --> 04:30:32,800
kind of a little report okay cool um
6398
04:30:32,800 --> 04:30:36,279
that's looking pretty good to me we
6399
04:30:36,279 --> 04:30:38,720
don't return anything from print reports
6400
04:30:38,720 --> 04:30:42,680
okay let's go ahead and run this
6401
04:30:43,399 --> 04:30:46,920
so message here's Johnny cost 28 cents
6402
04:30:46,920 --> 04:30:49,359
go ahead make my day 42 cents you had me
6403
04:30:49,359 --> 04:30:51,640
at hello 38 cents that's looking correct
6404
04:30:51,640 --> 04:30:53,359
right there's
6405
04:30:53,359 --> 04:30:54,880
19
6406
04:30:54,880 --> 04:30:58,239
28 not 19 what's half of 28 14 14
6407
04:30:58,239 --> 04:31:00,760
characters there looks good to me okay
6408
04:31:00,760 --> 04:31:02,720
let's go ahead and submit
6409
04:31:02,720 --> 04:31:05,640
that let's talk about pointers and in
6410
04:31:05,640 --> 04:31:07,800
order to understand pointers we need to
6411
04:31:07,800 --> 04:31:10,920
um talk a little bit about Ram or memory
6412
04:31:10,920 --> 04:31:12,920
right Random Access memory which is
6413
04:31:12,920 --> 04:31:14,680
basically the part of the hardware in
6414
04:31:14,680 --> 04:31:17,520
our computer that stores data right
6415
04:31:17,520 --> 04:31:19,680
because pointers and variables are all
6416
04:31:19,680 --> 04:31:22,680
about kind of how we store data in the
6417
04:31:22,680 --> 04:31:24,640
memory of our computer let's start with
6418
04:31:24,640 --> 04:31:25,800
something
6419
04:31:25,800 --> 04:31:29,000
simple let's create a new variable in
6420
04:31:29,000 --> 04:31:30,359
our
6421
04:31:30,359 --> 04:31:33,479
program and let's call it X and we'll
6422
04:31:33,479 --> 04:31:35,080
set x equal to
6423
04:31:35,080 --> 04:31:37,560
5 under the hood what happens
6424
04:31:37,560 --> 04:31:38,960
automatically when we create a new
6425
04:31:38,960 --> 04:31:41,279
variable uh and set it equal to five is
6426
04:31:41,279 --> 04:31:44,920
somewhere in our computer's memory that
6427
04:31:44,920 --> 04:31:47,080
variable's value is going to get stored
6428
04:31:47,080 --> 04:31:49,560
so let's say uh for the sake of the
6429
04:31:49,560 --> 04:31:52,119
example that it's stored here in memory
6430
04:31:52,119 --> 04:31:55,520
address 169 Now Memory in your computer
6431
04:31:55,520 --> 04:31:58,239
you could think of it as fairly simply a
6432
04:31:58,239 --> 04:32:00,880
memory address that stores a value so
6433
04:32:00,880 --> 04:32:02,720
we've got kind of you know millions of
6434
04:32:02,720 --> 04:32:04,239
different memory addresses in which we
6435
04:32:04,239 --> 04:32:08,479
can store data and somewhere in memory
6436
04:32:08,479 --> 04:32:10,239
uh that value needs to live so let's
6437
04:32:10,239 --> 04:32:11,880
just say it gets assigned again automat
6438
04:32:11,880 --> 04:32:17,119
aut atically um to address 169 great now
6439
04:32:17,119 --> 04:32:19,359
what happens if I create a new variable
6440
04:32:19,359 --> 04:32:22,680
let's call it Y and set it equal to the
6441
04:32:22,680 --> 04:32:24,720
current value of
6442
04:32:24,720 --> 04:32:29,600
x y actually gets a new copy of the
6443
04:32:29,600 --> 04:32:34,359
value so X lives here at address 169 y
6444
04:32:34,359 --> 04:32:35,800
let's just say is going to live at
6445
04:32:35,800 --> 04:32:38,319
address 170 and we get a copy of that
6446
04:32:38,319 --> 04:32:40,439
five so down here in this table this is
6447
04:32:40,439 --> 04:32:42,279
where we're going to keep track of all
6448
04:32:42,279 --> 04:32:46,159
of our variables we'll say that X so X
6449
04:32:46,159 --> 04:32:50,119
is the variable name lives at address
6450
04:32:50,119 --> 04:32:53,840
169 and it stores the value
6451
04:32:53,840 --> 04:32:55,720
five now
6452
04:32:55,720 --> 04:32:59,399
y lives at address
6453
04:32:59,399 --> 04:33:04,320
170 and stores also the value five at
6454
04:33:04,320 --> 04:33:07,879
its most basic a pointer is just a
6455
04:33:07,879 --> 04:33:11,959
variable that stores a memory address so
6456
04:33:11,959 --> 04:33:14,799
let's say for example that we create a
6457
04:33:14,799 --> 04:33:16,561
new variable called
6458
04:33:16,561 --> 04:33:20,879
Z and we set it to point which is uh
6459
04:33:20,879 --> 04:33:23,199
which uses the Ampersand I can't draw an
6460
04:33:23,199 --> 04:33:25,119
ampersand pretend that that's an
6461
04:33:25,119 --> 04:33:28,320
ampersand uh the the the a reference to
6462
04:33:28,320 --> 04:33:32,320
X right it points to x what that does is
6463
04:33:32,320 --> 04:33:33,719
that we're creating a new variable
6464
04:33:33,719 --> 04:33:34,920
called
6465
04:33:34,920 --> 04:33:37,920
Z it's going to get a new address
6466
04:33:37,920 --> 04:33:39,480
anytime we create a new variable it's
6467
04:33:39,480 --> 04:33:41,439
going to live in a new address in memory
6468
04:33:41,439 --> 04:33:44,000
let's say it lives at address
6469
04:33:44,000 --> 04:33:47,039
171 but its value instead of being five
6470
04:33:47,039 --> 04:33:49,279
instead of being a copy of X because we
6471
04:33:49,279 --> 04:33:51,680
used kind of the pointer syntax the
6472
04:33:51,680 --> 04:33:53,080
reference
6473
04:33:53,080 --> 04:33:56,160
syntax the value is going to be the
6474
04:33:56,160 --> 04:33:58,320
address of
6475
04:33:58,320 --> 04:34:00,520
X so we're going to
6476
04:34:00,520 --> 04:34:03,680
store 169 which is the again the address
6477
04:34:03,680 --> 04:34:07,799
of X as the value and Z is going to be a
6478
04:34:07,799 --> 04:34:10,760
pointer type so kind of the way the go
6479
04:34:10,760 --> 04:34:12,160
programming language works works is it
6480
04:34:12,160 --> 04:34:15,680
knows that Z is effectively pointing to
6481
04:34:15,680 --> 04:34:17,799
the value five right because its address
6482
04:34:17,799 --> 04:34:18,719
is
6483
04:34:18,719 --> 04:34:22,359
171 which stores a pointer to 169 so we
6484
04:34:22,359 --> 04:34:25,600
can look up the value five at address
6485
04:34:25,600 --> 04:34:29,279
169 so what this means is if we update
6486
04:34:29,279 --> 04:34:32,279
the value that Z points to under the
6487
04:34:32,279 --> 04:34:35,561
hood we're updating X so we can do
6488
04:34:35,561 --> 04:34:38,439
things like pass pointers into functions
6489
04:34:38,439 --> 04:34:41,240
change the underlying value and the
6490
04:34:41,240 --> 04:34:43,639
value outside of that function is also
6491
04:34:43,639 --> 04:34:45,561
changed which again in a language like
6492
04:34:45,561 --> 04:34:47,320
go doesn't happen normally because
6493
04:34:47,320 --> 04:34:49,680
typically if you pass a variable like X
6494
04:34:49,680 --> 04:34:52,199
into a function and then change it those
6495
04:34:52,199 --> 04:34:54,639
changes are not seen outside of the
6496
04:34:54,639 --> 04:34:56,439
function you would need to return the
6497
04:34:56,439 --> 04:34:57,959
updated value and then assign it into a
6498
04:34:57,959 --> 04:35:00,240
new variable so pointers basically allow
6499
04:35:00,240 --> 04:35:02,959
us to change the value of something from
6500
04:35:02,959 --> 04:35:04,600
within a function right from within a
6501
04:35:04,600 --> 04:35:07,080
different scope let me show you what
6502
04:35:07,080 --> 04:35:09,039
that looks like in a quick example so
6503
04:35:09,039 --> 04:35:12,879
remember that Z stores the value
6504
04:35:12,879 --> 04:35:15,680
169 which points to this
6505
04:35:15,680 --> 04:35:18,240
address which stores the value
6506
04:35:18,240 --> 04:35:21,680
five so if we want to update the value
6507
04:35:21,680 --> 04:35:24,119
of x without having access to the
6508
04:35:24,119 --> 04:35:27,240
original variable x what we can do is
6509
04:35:27,240 --> 04:35:29,561
use the dfference operator which is an
6510
04:35:29,561 --> 04:35:33,240
asterisk we can dreference Z now this
6511
04:35:33,240 --> 04:35:35,359
dfference operator essentially follows
6512
04:35:35,359 --> 04:35:37,840
this chain and finds the value right and
6513
04:35:37,840 --> 04:35:41,119
we reassign into it let's say the value
6514
04:35:41,119 --> 04:35:45,080
six so this becomes six and this
6515
04:35:45,080 --> 04:35:47,639
location and memory is updated now to
6516
04:35:47,639 --> 04:35:51,160
hold the value six so we've updated the
6517
04:35:51,160 --> 04:35:54,799
value of x without even without even
6518
04:35:54,799 --> 04:35:58,080
using right the name X so now that we've
6519
04:35:58,080 --> 04:36:00,039
kind of covered what a pointer is let's
6520
04:36:00,039 --> 04:36:01,840
look at just a little bit more of the
6521
04:36:01,840 --> 04:36:06,600
syntax in code so the type of a pointer
6522
04:36:06,600 --> 04:36:09,160
is not the type of the underlying value
6523
04:36:09,160 --> 04:36:11,600
alone so if I want a pointer to an
6524
04:36:11,600 --> 04:36:14,000
integer um I actually have to use this
6525
04:36:14,000 --> 04:36:16,039
syntax here I'm creating a new variable
6526
04:36:16,039 --> 04:36:19,279
called p and it's being initialized as a
6527
04:36:19,279 --> 04:36:22,199
pointer to an integer so a pointer is a
6528
04:36:22,199 --> 04:36:26,439
specific type in go now to be fair um
6529
04:36:26,439 --> 04:36:27,879
it's not super common that you're
6530
04:36:27,879 --> 04:36:30,240
creating blank pointers and the zero
6531
04:36:30,240 --> 04:36:33,959
value for a pointer is nil um more often
6532
04:36:33,959 --> 04:36:35,719
than not what you're going to do is have
6533
04:36:35,719 --> 04:36:38,600
a concrete value like this my string
6534
04:36:38,600 --> 04:36:41,080
hello and then you'll create a pointer
6535
04:36:41,080 --> 04:36:44,400
to that value by using the Ampersand
6536
04:36:44,400 --> 04:36:47,520
like we talked about so in this case the
6537
04:36:47,520 --> 04:36:51,240
type of my string is string and the type
6538
04:36:51,240 --> 04:36:54,160
of my string pointer is a pointer to a
6539
04:36:54,160 --> 04:36:57,561
string which would be syntactically star
6540
04:36:57,561 --> 04:37:00,480
string there kind of two primary reasons
6541
04:37:00,480 --> 04:37:02,840
that you would use a pointer in the go
6542
04:37:02,840 --> 04:37:04,879
programming language the first is the
6543
04:37:04,879 --> 04:37:06,760
more common reason which is you want to
6544
04:37:06,760 --> 04:37:09,400
be able to pass a value into a function
6545
04:37:09,400 --> 04:37:11,719
and change the value and have those
6546
04:37:11,719 --> 04:37:13,920
changes kind of persist outside of the
6547
04:37:13,920 --> 04:37:15,480
function right because normally when you
6548
04:37:15,480 --> 04:37:18,719
pass a value into a function a copy is
6549
04:37:18,719 --> 04:37:20,240
passed in so if you want to pass in sort
6550
04:37:20,240 --> 04:37:21,840
of the original value so it can be
6551
04:37:21,840 --> 04:37:24,240
changed and updated uh you might use a
6552
04:37:24,240 --> 04:37:26,600
pointer the second reason is if you're
6553
04:37:26,600 --> 04:37:28,439
very concerned about the performance of
6554
04:37:28,439 --> 04:37:31,039
your program every time you create a
6555
04:37:31,039 --> 04:37:34,000
copy of a variable in memory you have to
6556
04:37:34,000 --> 04:37:36,240
copy that variable in memory right which
6557
04:37:36,240 --> 04:37:39,199
takes some time so if you're dealing
6558
04:37:39,199 --> 04:37:40,799
with lots and lots of data and you're
6559
04:37:40,799 --> 04:37:42,959
trying to be very performant you can
6560
04:37:42,959 --> 04:37:45,439
make micro optimizations and kind of use
6561
04:37:45,439 --> 04:37:47,959
pointers under the hood if you want to
6562
04:37:47,959 --> 04:37:50,680
avoid all of that memory copying now I
6563
04:37:50,680 --> 04:37:52,561
will say that you usually won't want to
6564
04:37:52,561 --> 04:37:54,840
do this upfront because pointers are
6565
04:37:54,840 --> 04:37:57,840
dangerous and they can lead to bugs if
6566
04:37:57,840 --> 04:38:00,160
not used properly so generally speaking
6567
04:38:00,160 --> 04:38:02,400
I would recommend against making those
6568
04:38:02,400 --> 04:38:04,160
performance optimizations unless you
6569
04:38:04,160 --> 04:38:06,199
really need them let's jump into the
6570
04:38:06,199 --> 04:38:08,439
assignment says fix the bug in the send
6571
04:38:08,439 --> 04:38:10,320
message function it's supposed to print
6572
04:38:10,320 --> 04:38:11,840
a nicely formatted message to the
6573
04:38:11,840 --> 04:38:14,359
console containing an sms's uh recipient
6574
04:38:14,359 --> 04:38:15,799
and message body however it's not
6575
04:38:15,799 --> 04:38:18,000
working as expected okay so let's run
6576
04:38:18,000 --> 04:38:20,160
the
6577
04:38:20,160 --> 04:38:23,359
code and we get these kind of weird
6578
04:38:23,359 --> 04:38:25,840
weird looking values that are getting
6579
04:38:25,840 --> 04:38:29,359
printed here in the two and the message
6580
04:38:29,359 --> 04:38:32,840
Fields now this is heximal it's not
6581
04:38:32,840 --> 04:38:36,039
binary it's not decimal it's hexadecimal
6582
04:38:36,039 --> 04:38:38,520
and this is the default formatting for a
6583
04:38:38,520 --> 04:38:41,480
memory address so we have these amp
6584
04:38:41,480 --> 04:38:44,799
perents here they're creating pointers
6585
04:38:44,799 --> 04:38:48,320
to the underlying values that's not what
6586
04:38:48,320 --> 04:38:50,240
we want it's not what we want here right
6587
04:38:50,240 --> 04:38:52,320
that's why this looks disgusting uh we
6588
04:38:52,320 --> 04:38:55,000
need to dreference or or sorry we need
6589
04:38:55,000 --> 04:38:57,400
to remove the reference so I guess D
6590
04:38:57,400 --> 04:38:59,039
reference
6591
04:38:59,039 --> 04:39:01,520
um we need to remove the amperian so
6592
04:39:01,520 --> 04:39:03,359
that we are no longer creating pointers
6593
04:39:03,359 --> 04:39:07,240
so run it again and we get the values
6594
04:39:07,240 --> 04:39:09,561
themselves which is what what we've been
6595
04:39:09,561 --> 04:39:12,520
asked to do
6596
04:39:12,520 --> 04:39:14,799
let's recap some syntax sometimes it can
6597
04:39:14,799 --> 04:39:16,240
get a little confusing between the
6598
04:39:16,240 --> 04:39:18,439
asterisk and the Ampersand what each of
6599
04:39:18,439 --> 04:39:20,760
them mean and in what context so when
6600
04:39:20,760 --> 04:39:23,240
we're talking about the type of a
6601
04:39:23,240 --> 04:39:29,039
variable in go a Pointer's type is star
6602
04:39:29,039 --> 04:39:30,639
and then you know the type of the
6603
04:39:30,639 --> 04:39:32,480
underlying value so a pointer to an INT
6604
04:39:32,480 --> 04:39:36,680
is star int an ampersand is used to
6605
04:39:36,680 --> 04:39:38,920
reference a value so if we want to
6606
04:39:38,920 --> 04:39:43,040
create a pointer to the my string
6607
04:39:43,040 --> 04:39:45,798
variable or the my string value then we
6608
04:39:45,798 --> 04:39:48,878
use an ampersand so the Ampersand
6609
04:39:48,878 --> 04:39:51,440
followed by the name of a variable
6610
04:39:51,440 --> 04:39:54,840
creates a pointer to that variable now
6611
04:39:54,840 --> 04:39:56,160
here's where it can get just a little
6612
04:39:56,160 --> 04:40:00,440
bit tricky the asterisk is again used to
6613
04:40:00,440 --> 04:40:03,440
dreference a pointer so the asterisk is
6614
04:40:03,440 --> 04:40:07,360
used in a Pointer's type it's also used
6615
04:40:07,360 --> 04:40:10,600
as an operator to dreference a pointer
6616
04:40:10,600 --> 04:40:14,360
so when we say say asterisk my string
6617
04:40:14,360 --> 04:40:17,798
pointer this refers to the underlying
6618
04:40:17,798 --> 04:40:19,798
value so we can actually change the
6619
04:40:19,798 --> 04:40:22,638
underlying value Say by assigning it to
6620
04:40:22,638 --> 04:40:25,920
in this case a new string so in short
6621
04:40:25,920 --> 04:40:28,958
ampersands to create new references or
6622
04:40:28,958 --> 04:40:31,840
new pointers to a value and the asterisk
6623
04:40:31,840 --> 04:40:35,080
is used to dreference a pointer and get
6624
04:40:35,080 --> 04:40:37,958
back at that underlying value let's hop
6625
04:40:37,958 --> 04:40:40,120
into the assignment it says complete the
6626
04:40:40,120 --> 04:40:42,480
remove profanity function it should use
6627
04:40:42,480 --> 04:40:44,920
the strings. replace all function so
6628
04:40:44,920 --> 04:40:47,280
this is a a built-in uh function in the
6629
04:40:47,280 --> 04:40:49,360
standard library in the strings package
6630
04:40:49,360 --> 04:40:51,200
uh to replace all instances of the
6631
04:40:51,200 --> 04:40:54,280
following words in the input message
6632
04:40:54,280 --> 04:40:57,400
with asterisks it should mutate the
6633
04:40:57,400 --> 04:40:59,080
value in the pointer and return nothing
6634
04:40:59,080 --> 04:41:01,040
do not alter the function signature Okay
6635
04:41:01,040 --> 04:41:04,400
cool so remove profanity takes as input
6636
04:41:04,400 --> 04:41:08,240
a a a a message variable which is a
6637
04:41:08,240 --> 04:41:10,920
pointer to a string so because it's a
6638
04:41:10,920 --> 04:41:13,440
pointer we're going to be able to mutate
6639
04:41:13,440 --> 04:41:17,280
it without returning anything explicitly
6640
04:41:17,280 --> 04:41:19,480
okay let's jump into it so first thing
6641
04:41:19,480 --> 04:41:22,120
we're going to do is dreference
6642
04:41:22,120 --> 04:41:26,680
the message pointer and store its value
6643
04:41:26,680 --> 04:41:29,440
in a new variable called message value
6644
04:41:29,440 --> 04:41:31,760
and then we'll just update
6645
04:41:31,760 --> 04:41:34,920
this um by using that strings. replace
6646
04:41:34,920 --> 04:41:38,480
all functions strings. replace
6647
04:41:38,480 --> 04:41:41,360
all we want to replace the values in
6648
04:41:41,360 --> 04:41:44,200
message value we want to or I should say
6649
04:41:44,200 --> 04:41:46,080
we want to replace subrings from message
6650
04:41:46,080 --> 04:41:49,280
value uh we'll look for the word dang
6651
04:41:49,280 --> 04:41:52,718
and we'll replace it with four
6652
04:41:53,160 --> 04:41:55,440
asterisks and we want to do the same
6653
04:41:55,440 --> 04:41:58,920
thing twice more with shoot which has
6654
04:41:58,920 --> 04:42:01,440
five letters so let's add an asterisk
6655
04:42:01,440 --> 04:42:04,200
and heck which has four so that should
6656
04:42:04,200 --> 04:42:07,560
be good cool let's let's run this I need
6657
04:42:07,560 --> 04:42:09,080
to import the strings package before I
6658
04:42:09,080 --> 04:42:11,878
forget and see what happens
6659
04:42:11,878 --> 04:42:15,360
so in its current state we actually did
6660
04:42:15,360 --> 04:42:17,560
not update anything right shoot is still
6661
04:42:17,560 --> 04:42:19,638
there dang is still there that's because
6662
04:42:19,638 --> 04:42:21,320
we actually need
6663
04:42:21,320 --> 04:42:24,280
to point the
6664
04:42:24,280 --> 04:42:27,958
message pointer to a string back at the
6665
04:42:27,958 --> 04:42:31,480
updated value so we can do dereferenced
6666
04:42:31,480 --> 04:42:32,920
message
6667
04:42:32,920 --> 04:42:37,520
equals message value let's run
6668
04:42:37,520 --> 04:42:42,400
that perfect let's submit it
6669
04:42:42,400 --> 04:42:44,520
now we've got a pointer quiz so the
6670
04:42:44,520 --> 04:42:47,240
question is what is the value of
6671
04:42:47,240 --> 04:42:50,000
Ampersand y after the code on the left
6672
04:42:50,000 --> 04:42:54,718
executes so we've got X set to 50 Y is a
6673
04:42:54,718 --> 04:42:56,280
pointer to an
6674
04:42:56,280 --> 04:42:58,840
integer okay well in this case it's just
6675
04:42:58,840 --> 04:43:00,798
going to be 100 because we're explicitly
6676
04:43:00,798 --> 04:43:02,440
setting it to 100 on the last line of
6677
04:43:02,440 --> 04:43:05,360
the code so that one was pretty easy now
6678
04:43:05,360 --> 04:43:07,200
this question is a little trickier says
6679
04:43:07,200 --> 04:43:09,920
what is the value of x after the code on
6680
04:43:09,920 --> 04:43:11,878
the left executes
6681
04:43:11,878 --> 04:43:13,718
well X is set to
6682
04:43:13,718 --> 04:43:17,840
50 Y is a pointer to X and then we
6683
04:43:17,840 --> 04:43:21,400
dreference y instead of equal to 100 so
6684
04:43:21,400 --> 04:43:24,718
that's actually also going to be 100
6685
04:43:24,718 --> 04:43:28,280
because we're setting X through Y which
6686
04:43:28,280 --> 04:43:31,160
is a pointer to X I mentioned earlier
6687
04:43:31,160 --> 04:43:33,638
that pointers can be dangerous and that
6688
04:43:33,638 --> 04:43:36,120
is definitely the case um if a pointer
6689
04:43:36,120 --> 04:43:40,400
points to nothing then its zero value is
6690
04:43:40,400 --> 04:43:42,320
nil right so this is the same for
6691
04:43:42,320 --> 04:43:45,798
interfaces or errors right in go fairly
6692
04:43:45,798 --> 04:43:48,840
often you'll be checking at runtime if a
6693
04:43:48,840 --> 04:43:51,798
value is nil or not and the thing about
6694
04:43:51,798 --> 04:43:53,320
pointers is if you ever try to
6695
04:43:53,320 --> 04:43:56,680
dreference a pointer that doesn't point
6696
04:43:56,680 --> 04:43:59,760
to anything your code will Panic so
6697
04:43:59,760 --> 04:44:01,440
pretty much any time you dreference
6698
04:44:01,440 --> 04:44:03,560
something you should be checking before
6699
04:44:03,560 --> 04:44:05,878
you dreference it to make sure that the
6700
04:44:05,878 --> 04:44:08,160
pointer actually points to a valid
6701
04:44:08,160 --> 04:44:10,080
location in memory so this assignment
6702
04:44:10,080 --> 04:44:11,400
says let's make our Prof profanity
6703
04:44:11,400 --> 04:44:13,798
Checker safe update the remove profanity
6704
04:44:13,798 --> 04:44:15,680
function If the message is nil return
6705
04:44:15,680 --> 04:44:17,480
early to avoid a panic okay so let me
6706
04:44:17,480 --> 04:44:20,120
run it in its current state and you'll
6707
04:44:20,120 --> 04:44:22,680
see we get this nasty Panic here it says
6708
04:44:22,680 --> 04:44:25,480
invalid memory address or
6709
04:44:25,480 --> 04:44:29,480
nil okay so what we need to do here is
6710
04:44:29,480 --> 04:44:30,600
if
6711
04:44:30,600 --> 04:44:33,120
message equals equals
6712
04:44:33,120 --> 04:44:37,600
nil return nothing right if we've been
6713
04:44:37,600 --> 04:44:39,798
given an invalid input we'll just bail
6714
04:44:39,798 --> 04:44:42,480
early um another way to do this um if
6715
04:44:42,480 --> 04:44:44,560
the assignment expected something
6716
04:44:44,560 --> 04:44:46,840
different we could return an error here
6717
04:44:46,840 --> 04:44:48,560
right we might do something like return
6718
04:44:48,560 --> 04:44:51,840
errors. new uh invalid input I think
6719
04:44:51,840 --> 04:44:53,400
that would also be a good way to write
6720
04:44:53,400 --> 04:44:55,440
this function uh but we've been asked to
6721
04:44:55,440 --> 04:44:57,480
just do a naked return so we will do
6722
04:44:57,480 --> 04:45:01,000
that let's submit it so let's talk about
6723
04:45:01,000 --> 04:45:03,760
how pointers are used in conjunction
6724
04:45:03,760 --> 04:45:07,200
with methods so you'll very frequently
6725
04:45:07,200 --> 04:45:10,638
see that methods actually take a pointer
6726
04:45:10,638 --> 04:45:11,798
receip
6727
04:45:11,798 --> 04:45:14,920
rather than a non-pointer receiver and
6728
04:45:14,920 --> 04:45:17,320
typically that's done because the method
6729
04:45:17,320 --> 04:45:20,200
will be making changes to the instance
6730
04:45:20,200 --> 04:45:22,520
of the type itself in this case a struct
6731
04:45:22,520 --> 04:45:24,280
right so we have this car with a color
6732
04:45:24,280 --> 04:45:26,798
field and the set color method on the
6733
04:45:26,798 --> 04:45:29,840
car is going to change the color right
6734
04:45:29,840 --> 04:45:32,000
and so here if we create a new car we
6735
04:45:32,000 --> 04:45:34,280
set the color to blue and then print it
6736
04:45:34,280 --> 04:45:36,120
you can see it's been updated to Blue
6737
04:45:36,120 --> 04:45:38,958
instead of white now contrast that with
6738
04:45:38,958 --> 04:45:42,080
a non-pointer receiver
6739
04:45:42,080 --> 04:45:43,798
this acts like a normal function right
6740
04:45:43,798 --> 04:45:45,400
we don't have a pointer so we don't have
6741
04:45:45,400 --> 04:45:47,958
a reference to the location in memory so
6742
04:45:47,958 --> 04:45:50,920
if we update the cars color to Blue it
6743
04:45:50,920 --> 04:45:53,440
actually just stays white it doesn't
6744
04:45:53,440 --> 04:45:56,360
persist that change so that's why I say
6745
04:45:56,360 --> 04:45:58,718
that it's uh more common that you'll see
6746
04:45:58,718 --> 04:46:01,360
pointer receivers on methods than
6747
04:46:01,360 --> 04:46:03,200
non-pointer receivers but but you will
6748
04:46:03,200 --> 04:46:05,120
definitely see both so uh the question
6749
04:46:05,120 --> 04:46:07,320
is which is more widely used in go and
6750
04:46:07,320 --> 04:46:10,000
the answer is pointer receivers now when
6751
04:46:10,000 --> 04:46:12,080
it comes to pointer to receivers one
6752
04:46:12,080 --> 04:46:13,280
thing that's important to understand
6753
04:46:13,280 --> 04:46:15,440
from like a syntactic point of view is
6754
04:46:15,440 --> 04:46:19,240
that even though the uh the input on the
6755
04:46:19,240 --> 04:46:21,120
left hand side right the receiver is a
6756
04:46:21,120 --> 04:46:23,600
pointer when you actually call the
6757
04:46:23,600 --> 04:46:27,000
method you can call in this case right
6758
04:46:27,000 --> 04:46:29,040
the grow method you can actually call it
6759
04:46:29,040 --> 04:46:31,680
on just a normal value or a pointer it
6760
04:46:31,680 --> 04:46:33,920
will sort of cast the value under the
6761
04:46:33,920 --> 04:46:35,558
hood to a pointer if it isn't one
6762
04:46:35,558 --> 04:46:38,558
already right so C in this case is just
6763
04:46:38,558 --> 04:46:41,558
a circle it's not a pointer to a circle
6764
04:46:41,558 --> 04:46:44,680
but when we call c. grow the pointer to
6765
04:46:44,680 --> 04:46:46,878
the circle is passed into the method so
6766
04:46:46,878 --> 04:46:49,120
we didn't need to kind of explicitly you
6767
04:46:49,120 --> 04:46:51,520
know cast c to a pointer to a circle by
6768
04:46:51,520 --> 04:46:54,520
you know adding an Amper sand right here
6769
04:46:54,520 --> 04:46:56,680
okay so with that understood um let's
6770
04:46:56,680 --> 04:46:58,320
move on to the assignment so the
6771
04:46:58,320 --> 04:46:59,798
assignment says fix the bug and the
6772
04:46:59,798 --> 04:47:01,638
codes that set message sets the message
6773
04:47:01,638 --> 04:47:03,600
field of the given email structure and
6774
04:47:03,600 --> 04:47:05,040
the new value persists outside the scope
6775
04:47:05,040 --> 04:47:07,000
of the set message method Okay so we've
6776
04:47:07,000 --> 04:47:09,638
got this email struct we've got the set
6777
04:47:09,638 --> 04:47:11,600
message uh
6778
04:47:11,600 --> 04:47:15,080
the set message method if I run the code
6779
04:47:15,080 --> 04:47:17,320
in its current
6780
04:47:17,320 --> 04:47:20,600
state we've got before message this my
6781
04:47:20,600 --> 04:47:24,440
first draft Sandra Bullock after looks
6782
04:47:24,440 --> 04:47:26,320
identical right and if we go and take a
6783
04:47:26,320 --> 04:47:29,798
look at the test Suite then we can
6784
04:47:29,798 --> 04:47:31,360
see
6785
04:47:31,360 --> 04:47:34,680
that set message is being called this is
6786
04:47:34,680 --> 04:47:37,160
my second draft so we would have
6787
04:47:37,160 --> 04:47:39,520
expected this message to say this is my
6788
04:47:39,520 --> 04:47:40,958
second draft instead of this is my my
6789
04:47:40,958 --> 04:47:42,240
first draft the reason it's not
6790
04:47:42,240 --> 04:47:45,240
happening is because this function
6791
04:47:45,240 --> 04:47:46,558
essentially doesn't do anything this
6792
04:47:46,558 --> 04:47:50,160
method does nothing because this is not
6793
04:47:50,160 --> 04:47:52,480
a pointer to an email let's go ahead and
6794
04:47:52,480 --> 04:47:54,840
run that
6795
04:47:55,200 --> 04:47:59,638
again first draft second draft perfect
6796
04:47:59,638 --> 04:48:00,878
let's submit
6797
04:48:00,878 --> 04:48:03,440
that everything we've done up to this
6798
04:48:03,440 --> 04:48:05,440
point in the course has been in the
6799
04:48:05,440 --> 04:48:07,798
browser we've been writing code right in
6800
04:48:07,798 --> 04:48:10,840
our text editor on boot Dev now we're
6801
04:48:10,840 --> 04:48:12,798
going to break out of that environment
6802
04:48:12,798 --> 04:48:14,920
and do some local development on our own
6803
04:48:14,920 --> 04:48:16,280
machine we're going to figure out how to
6804
04:48:16,280 --> 04:48:19,080
use the go tool chain to build real
6805
04:48:19,080 --> 04:48:20,878
production go
6806
04:48:20,878 --> 04:48:23,600
programs but before we do that let's
6807
04:48:23,600 --> 04:48:26,160
talk a little bit about packages we need
6808
04:48:26,160 --> 04:48:28,360
to understand packages in order to build
6809
04:48:28,360 --> 04:48:30,840
our own go programs now you've probably
6810
04:48:30,840 --> 04:48:32,400
noticed that up until this point in the
6811
04:48:32,400 --> 04:48:34,440
course every coding assignment has had
6812
04:48:34,440 --> 04:48:37,400
the words package main at the top of the
6813
04:48:37,400 --> 04:48:39,040
file that just means that we've been
6814
04:48:39,040 --> 04:48:41,400
writing code within the main
6815
04:48:41,400 --> 04:48:43,320
package and that's actually really
6816
04:48:43,320 --> 04:48:46,638
important the main package is a special
6817
04:48:46,638 --> 04:48:49,320
type of package it's a package that runs
6818
04:48:49,320 --> 04:48:52,280
as a standalone program so anytime
6819
04:48:52,280 --> 04:48:54,520
you're writing an actual application
6820
04:48:54,520 --> 04:48:56,320
that you need to run say on the command
6821
04:48:56,320 --> 04:48:58,360
line or as a server you'll be writing
6822
04:48:58,360 --> 04:49:01,558
code within the main package a package
6823
04:49:01,558 --> 04:49:05,280
with any other name so any name besides
6824
04:49:05,280 --> 04:49:08,840
main is a library package and basically
6825
04:49:08,840 --> 04:49:11,280
what that means is it's imported by
6826
04:49:11,280 --> 04:49:14,680
other libraries and application code so
6827
04:49:14,680 --> 04:49:16,798
some oftentimes it's just imported by a
6828
04:49:16,798 --> 04:49:19,320
main package so that it can use it if
6829
04:49:19,320 --> 04:49:21,878
you're familiar with npm from JavaScript
6830
04:49:21,878 --> 04:49:24,600
or pip from python that's effectively
6831
04:49:24,600 --> 04:49:27,280
what a non-main package is in go it's
6832
04:49:27,280 --> 04:49:29,520
just some code that you can publish as
6833
04:49:29,520 --> 04:49:31,920
kind of a standalone library that then
6834
04:49:31,920 --> 04:49:35,200
other developers can use in their main
6835
04:49:35,200 --> 04:49:38,160
packages in their actual applications so
6836
04:49:38,160 --> 04:49:40,718
let's take a look at an example here so
6837
04:49:40,718 --> 04:49:42,440
you're probably familiar with this style
6838
04:49:42,440 --> 04:49:44,440
of code it's what we've been writing uh
6839
04:49:44,440 --> 04:49:46,280
all throughout this course we've been
6840
04:49:46,280 --> 04:49:48,000
writing within the main package because
6841
04:49:48,000 --> 04:49:50,558
we've been writing executable scripts
6842
04:49:50,558 --> 04:49:53,240
right code that actually runs and does
6843
04:49:53,240 --> 04:49:55,760
something and then we have this import
6844
04:49:55,760 --> 04:49:57,480
statement where we've typically just
6845
04:49:57,480 --> 04:49:59,200
been importing from the standard library
6846
04:49:59,200 --> 04:50:02,400
but the standard library is made up of
6847
04:50:02,400 --> 04:50:04,958
Library packages right like the fmt
6848
04:50:04,958 --> 04:50:08,600
package or the math SL random package
6849
04:50:08,600 --> 04:50:10,080
the interesting thing about the main
6850
04:50:10,080 --> 04:50:13,000
package is it always has a main function
6851
04:50:13,000 --> 04:50:15,000
and that main function serves as the
6852
04:50:15,000 --> 04:50:17,680
entry point to the program so packages
6853
04:50:17,680 --> 04:50:20,680
that are not main packages their Library
6854
04:50:20,680 --> 04:50:23,280
packages will just export functions
6855
04:50:23,280 --> 04:50:26,040
named functions to be used Again by
6856
04:50:26,040 --> 04:50:28,878
other libraries and application code
6857
04:50:28,878 --> 04:50:31,558
only main packages will have a main
6858
04:50:31,558 --> 04:50:33,360
function that runs when the program
6859
04:50:33,360 --> 04:50:35,320
starts so to jump into the coding
6860
04:50:35,320 --> 04:50:37,120
assignment it just says fix the bug in
6861
04:50:37,120 --> 04:50:38,440
the code so let's go ahead and run the
6862
04:50:38,440 --> 04:50:42,600
code and see what happens
6863
04:50:46,798 --> 04:50:49,360
nothing happens right we're stuck in
6864
04:50:49,360 --> 04:50:52,240
this infinite Loop apparently apparently
6865
04:50:52,240 --> 04:50:55,400
this code compiles and then does nothing
6866
04:50:55,400 --> 04:50:58,400
it's kind of a weird Behavior right um
6867
04:50:58,400 --> 04:51:01,000
in order to fix this all we need to do
6868
04:51:01,000 --> 04:51:02,240
is update
6869
04:51:02,240 --> 04:51:05,320
this to be a main package so that we get
6870
04:51:05,320 --> 04:51:08,200
as output for our code a runnable
6871
04:51:08,200 --> 04:51:09,840
executable a script that we can actually
6872
04:51:09,840 --> 04:51:11,080
execute in the browser so let's go ahead
6873
04:51:11,080 --> 04:51:14,080
and run that and we get starting maleo
6874
04:51:14,080 --> 04:51:16,760
server stopping maleo server kind of as
6875
04:51:16,760 --> 04:51:20,360
we would expect uh based on uh based on
6876
04:51:20,360 --> 04:51:21,558
this code here so I'm going to go ahead
6877
04:51:21,558 --> 04:51:23,958
and submit that so we're familiar with
6878
04:51:23,958 --> 04:51:25,958
main packages but what about Library
6879
04:51:25,958 --> 04:51:29,120
packages well by convention a package's
6880
04:51:29,120 --> 04:51:31,798
name is the same as the last element of
6881
04:51:31,798 --> 04:51:33,878
its import path so for example the math
6882
04:51:33,878 --> 04:51:37,360
Rand or math SL Rand package from the
6883
04:51:37,360 --> 04:51:40,638
ghost standard Library um has files that
6884
04:51:40,638 --> 04:51:43,878
begin with package Rand so the Rand
6885
04:51:43,878 --> 04:51:47,360
package lives at math SL Rand now it's
6886
04:51:47,360 --> 04:51:48,798
important to point out that the standard
6887
04:51:48,798 --> 04:51:50,680
Library actually has another Rand
6888
04:51:50,680 --> 04:51:54,160
package at crypto Rand so they're both
6889
04:51:54,160 --> 04:51:55,958
kind of the Rand package but they have
6890
04:51:55,958 --> 04:51:59,200
different import paths when a package
6891
04:51:59,200 --> 04:52:01,920
isn't part of the standard Library when
6892
04:52:01,920 --> 04:52:04,240
for example you make your own Library
6893
04:52:04,240 --> 04:52:08,080
package the import path is typically the
6894
04:52:08,080 --> 04:52:10,680
same as the remote URL that you you'd
6895
04:52:10,680 --> 04:52:13,000
use to go look at that library's source
6896
04:52:13,000 --> 04:52:16,440
code so for example in our fictitious
6897
04:52:16,440 --> 04:52:19,080
maleo products right part of the textio
6898
04:52:19,080 --> 04:52:22,200
conglomerate of messaging products uh
6899
04:52:22,200 --> 04:52:23,638
they might have their own GitHub
6900
04:52:23,638 --> 04:52:26,798
namespace it's slmo so github.com is
6901
04:52:26,798 --> 04:52:28,760
their GitHub organization and then maybe
6902
04:52:28,760 --> 04:52:30,878
they create their own package or their
6903
04:52:30,878 --> 04:52:33,520
own excuse me repository on GitHub
6904
04:52:33,520 --> 04:52:36,160
called Rand and that's where the
6905
04:52:36,160 --> 04:52:38,280
repository for their Rand package lives
6906
04:52:38,280 --> 04:52:39,760
that's where the source code lives on
6907
04:52:39,760 --> 04:52:42,080
the internet right github.com
6908
04:52:42,080 --> 04:52:44,878
Rand now that package's name by
6909
04:52:44,878 --> 04:52:47,680
convention should be Rand because that's
6910
04:52:47,680 --> 04:52:52,080
the last section of the import path but
6911
04:52:52,080 --> 04:52:53,958
that's just a convention they could if
6912
04:52:53,958 --> 04:52:56,000
they wanted to change the name of the
6913
04:52:56,000 --> 04:52:58,240
package to say random and then all of
6914
04:52:58,240 --> 04:53:01,040
the files in their source code would say
6915
04:53:01,040 --> 04:53:04,200
package random now again it is possible
6916
04:53:04,200 --> 04:53:06,878
to use a different package name one
6917
04:53:06,878 --> 04:53:09,040
that's not the same as the last section
6918
04:53:09,040 --> 04:53:11,040
of the import path but I highly
6919
04:53:11,040 --> 04:53:13,680
discourage it um it is best practice to
6920
04:53:13,680 --> 04:53:15,480
just use the convention and keep
6921
04:53:15,480 --> 04:53:17,680
everything consistent now one last thing
6922
04:53:17,680 --> 04:53:20,520
to point out here is that in go packages
6923
04:53:20,520 --> 04:53:23,280
live at the directory level rather than
6924
04:53:23,280 --> 04:53:26,120
the file level so if you're used to say
6925
04:53:26,120 --> 04:53:28,920
python or JavaScript you might be used
6926
04:53:28,920 --> 04:53:31,160
to importing code directly from other
6927
04:53:31,160 --> 04:53:35,080
files in go if all of the code lives
6928
04:53:35,080 --> 04:53:37,240
within the same directory then it's part
6929
04:53:37,240 --> 04:53:39,040
of the same package and you don't need
6930
04:53:39,040 --> 04:53:41,878
to Import and Export code between files
6931
04:53:41,878 --> 04:53:43,798
in the same package or in the same
6932
04:53:43,798 --> 04:53:46,798
directory so in go you would only need
6933
04:53:46,798 --> 04:53:48,920
to import code if it lives in a
6934
04:53:48,920 --> 04:53:51,360
different directory or a different
6935
04:53:51,360 --> 04:53:53,638
package and packages and directories are
6936
04:53:53,638 --> 04:53:55,840
one and the same you can't have multiple
6937
04:53:55,840 --> 04:53:58,638
packages in the same directory so the
6938
04:53:58,638 --> 04:54:00,520
quiz question for this section is what
6939
04:54:00,520 --> 04:54:02,600
would be the conventional package name
6940
04:54:02,600 --> 04:54:06,000
of a package with the path github.com
6941
04:54:06,000 --> 04:54:09,878
waglan parser and the answer is going to
6942
04:54:09,878 --> 04:54:12,080
be parer because it should match the
6943
04:54:12,080 --> 04:54:14,840
last section of the import path the next
6944
04:54:14,840 --> 04:54:17,480
question on the topic of package naming
6945
04:54:17,480 --> 04:54:21,718
is given the import path of path to Rand
6946
04:54:21,718 --> 04:54:25,320
path2 Rand which of these is a valid
6947
04:54:25,320 --> 04:54:27,600
package name so notice it's not asking
6948
04:54:27,600 --> 04:54:29,160
which is a conventional it's asking
6949
04:54:29,160 --> 04:54:31,240
which one is actually valid we've got
6950
04:54:31,240 --> 04:54:33,920
random Rand spam any of these path well
6951
04:54:33,920 --> 04:54:36,440
Rand would be the conventional name but
6952
04:54:36,440 --> 04:54:38,878
actually any of these could technically
6953
04:54:38,878 --> 04:54:42,040
be used okay it's time to write some go
6954
04:54:42,040 --> 04:54:43,798
code on our local machines and you're
6955
04:54:43,798 --> 04:54:45,718
going to need three things in order to
6956
04:54:45,718 --> 04:54:47,878
make it through the rest of this chapter
6957
04:54:47,878 --> 04:54:50,040
the first thing is you're going to need
6958
04:54:50,040 --> 04:54:52,760
an editor I'll be using VSS code
6959
04:54:52,760 --> 04:54:54,160
throughout the rest of this chapter to
6960
04:54:54,160 --> 04:54:55,798
do all of our local development stuff
6961
04:54:55,798 --> 04:54:57,600
you can use vs code or you can use
6962
04:54:57,600 --> 04:54:59,520
something else uh that you're more
6963
04:54:59,520 --> 04:55:01,840
familiar with if you do use vs code
6964
04:55:01,840 --> 04:55:03,320
you'll probably want to install the
6965
04:55:03,320 --> 04:55:06,160
official goang plug-in the next thing
6966
04:55:06,160 --> 04:55:09,160
you'll need is a Unix like or sh like
6967
04:55:09,160 --> 04:55:11,600
terminal so if you're on Mac or Linux
6968
04:55:11,600 --> 04:55:13,240
then the built-in terminal will work
6969
04:55:13,240 --> 04:55:15,558
just fine if you're on Windows you have
6970
04:55:15,558 --> 04:55:17,400
a few different options personally I
6971
04:55:17,400 --> 04:55:19,718
would recommend installing Ubuntu in
6972
04:55:19,718 --> 04:55:22,240
wsl2 I'll link uh in the description
6973
04:55:22,240 --> 04:55:24,360
down below how to do that uh but you
6974
04:55:24,360 --> 04:55:26,440
will need to have a terminal in order to
6975
04:55:26,440 --> 04:55:28,440
follow along with these instructions if
6976
04:55:28,440 --> 04:55:29,840
you choose to use something like the
6977
04:55:29,840 --> 04:55:31,280
default Windows command line you're
6978
04:55:31,280 --> 04:55:32,718
going to have to change some of the
6979
04:55:32,718 --> 04:55:34,600
instructions in the terminal uh to kind
6980
04:55:34,600 --> 04:55:36,760
of translate them to your own machine
6981
04:55:36,760 --> 04:55:38,200
the last thing you'll need is just to
6982
04:55:38,200 --> 04:55:40,280
install the go tool chain on your local
6983
04:55:40,280 --> 04:55:42,120
machine and I would recommend one of two
6984
04:55:42,120 --> 04:55:44,400
different ways the first is to use uh
6985
04:55:44,400 --> 04:55:46,440
the official download page and the
6986
04:55:46,440 --> 04:55:49,280
second is to use um the Webby download
6987
04:55:49,280 --> 04:55:51,240
script either of them will work and I've
6988
04:55:51,240 --> 04:55:53,040
linked them both on this page so you can
6989
04:55:53,040 --> 04:55:55,320
go check them out and get go downloaded
6990
04:55:55,320 --> 04:55:57,600
now once you've downloaded and installed
6991
04:55:57,600 --> 04:55:59,280
go the way you can test to make sure
6992
04:55:59,280 --> 04:56:00,958
that everything is working correctly is
6993
04:56:00,958 --> 04:56:04,320
type Go version in your terminal if you
6994
04:56:04,320 --> 04:56:07,360
get back a valid Go version of at least
6995
04:56:07,360 --> 04:56:08,280
version
6996
04:56:08,280 --> 04:56:10,558
1.20 which is what I'm using at the time
6997
04:56:10,558 --> 04:56:12,320
of recording this video uh then you
6998
04:56:12,320 --> 04:56:14,320
should be good to go now I need to point
6999
04:56:14,320 --> 04:56:15,760
out at this point that some people get
7000
04:56:15,760 --> 04:56:18,040
confused and think this is Go version
7001
04:56:18,040 --> 04:56:21,798
1.2 it's not it's Go version 1.20 which
7002
04:56:21,798 --> 04:56:25,200
is the same as Go version 1.20 which is
7003
04:56:25,200 --> 04:56:28,958
one version greater than go 1.19 or go
7004
04:56:28,958 --> 04:56:31,080
1.19 so make sure that you're not on Go
7005
04:56:31,080 --> 04:56:34,160
1.2 that would be very very old if
7006
04:56:34,160 --> 04:56:35,958
you're having trouble getting go
7007
04:56:35,958 --> 04:56:37,638
installed so that you can use it within
7008
04:56:37,638 --> 04:56:39,280
your terminal uh the first thing I'll
7009
04:56:39,280 --> 04:56:41,280
have you do is definitely to try closing
7010
04:56:41,280 --> 04:56:43,878
your shell session and restarting it um
7011
04:56:43,878 --> 04:56:45,360
a lot of times that can help just
7012
04:56:45,360 --> 04:56:48,400
getting go into your path uh if that
7013
04:56:48,400 --> 04:56:51,080
doesn't work then Googling around uh C
7014
04:56:51,080 --> 04:56:53,320
can can be one method to kind of try to
7015
04:56:53,320 --> 04:56:54,400
figure out what's going on on your
7016
04:56:54,400 --> 04:56:55,840
machine it's really hard for me to kind
7017
04:56:55,840 --> 04:56:58,680
of predict what issues you might have
7018
04:56:58,680 --> 04:57:00,638
especially considering the fact that Mac
7019
04:57:00,638 --> 04:57:02,718
OS windows and Linux can all be a little
7020
04:57:02,718 --> 04:57:05,000
different but what I will recommend is
7021
04:57:05,000 --> 04:57:06,958
that if you are having trouble jump into
7022
04:57:06,958 --> 04:57:09,798
the bootd Discord and ask a specific
7023
04:57:09,798 --> 04:57:11,520
question about the trouble you're having
7024
04:57:11,520 --> 04:57:13,558
and we'll be happy to help you out so
7025
04:57:13,558 --> 04:57:15,080
the question for this step really just
7026
04:57:15,080 --> 04:57:16,638
to confirm that we installed go
7027
04:57:16,638 --> 04:57:19,040
correctly and that we can use it uh asks
7028
04:57:19,040 --> 04:57:21,320
what does the Go version command print
7029
04:57:21,320 --> 04:57:23,080
and if we check the output we can see it
7030
04:57:23,080 --> 04:57:26,760
says Go version go 1.20 so that's the
7031
04:57:26,760 --> 04:57:28,638
that's the version of the go tool chain
7032
04:57:28,638 --> 04:57:31,200
we have uh Darwin I'm on a Mac so this
7033
04:57:31,200 --> 04:57:33,798
is like the core Unix operating system
7034
04:57:33,798 --> 04:57:36,360
and then amd64 which is my CPU
7035
04:57:36,360 --> 04:57:38,958
architecture so it's going to be this
7036
04:57:38,958 --> 04:57:41,520
bottom one so we've talked about
7037
04:57:41,520 --> 04:57:42,920
packages and we've talked about how
7038
04:57:42,920 --> 04:57:44,440
packages exist basically at the
7039
04:57:44,440 --> 04:57:47,000
directory level and go now we need to
7040
04:57:47,000 --> 04:57:50,958
talk about modules a module is a bigger
7041
04:57:50,958 --> 04:57:54,000
idea than just a package a module is
7042
04:57:54,000 --> 04:57:57,000
kind of a releasable collection of go
7043
04:57:57,000 --> 04:57:59,160
packages so sometimes it's just a single
7044
04:57:59,160 --> 04:58:00,718
package right you have a single package
7045
04:58:00,718 --> 04:58:03,600
a single module and you release it um as
7046
04:58:03,600 --> 04:58:05,638
one package but other times you might
7047
04:58:05,638 --> 04:58:08,958
break that main package up into sub
7048
04:58:08,958 --> 04:58:11,638
packages and you'd release all of those
7049
04:58:11,638 --> 04:58:15,760
packages together as one go module now a
7050
04:58:15,760 --> 04:58:18,840
repository is not a unique idea to go
7051
04:58:18,840 --> 04:58:21,680
but it's sort of even greater than just
7052
04:58:21,680 --> 04:58:25,680
a module repository or a git repository
7053
04:58:25,680 --> 04:58:27,718
is just a collection of code that you
7054
04:58:27,718 --> 04:58:29,840
kind of keep in Source control all at
7055
04:58:29,840 --> 04:58:32,558
the same level and it can contain one or
7056
04:58:32,558 --> 04:58:34,958
more modules though it's actually really
7057
04:58:34,958 --> 04:58:37,520
common for a single repository to just
7058
04:58:37,520 --> 04:58:40,558
have a single go module with within it
7059
04:58:40,558 --> 04:58:43,760
so while one monor repo can have many
7060
04:58:43,760 --> 04:58:45,680
different go modules inside of it I
7061
04:58:45,680 --> 04:58:47,798
would argue that's not usually the case
7062
04:58:47,798 --> 04:58:50,000
typically you'll have one go module
7063
04:58:50,000 --> 04:58:52,480
living in one repository that's not a
7064
04:58:52,480 --> 04:58:54,200
convention that's just the way I've seen
7065
04:58:54,200 --> 04:58:56,440
it more often than not so for the sake
7066
04:58:56,440 --> 04:58:59,760
of example let's assume a git repository
7067
04:58:59,760 --> 04:59:02,600
that contains a single module and that
7068
04:59:02,600 --> 04:59:03,958
means that at the root of the git
7069
04:59:03,958 --> 04:59:06,440
repository we'd have a single go dood
7070
04:59:06,440 --> 04:59:09,400
file that looks something like this the
7071
04:59:09,400 --> 04:59:12,440
first line contains the path prefix for
7072
04:59:12,440 --> 04:59:14,520
the entire module so remember a module
7073
04:59:14,520 --> 04:59:17,760
can contain multiple packages and every
7074
04:59:17,760 --> 04:59:20,798
package in that module its import path
7075
04:59:20,798 --> 04:59:23,280
is going to be prefixed with the path of
7076
04:59:23,280 --> 04:59:25,320
the entire module uh the next line just
7077
04:59:25,320 --> 04:59:28,040
specifies the Go version um and the last
7078
04:59:28,040 --> 04:59:31,320
line will specify any dependencies that
7079
04:59:31,320 --> 04:59:35,000
this module depends on so to answer the
7080
04:59:35,000 --> 04:59:37,920
question what is a go module an
7081
04:59:37,920 --> 04:59:40,798
executable main package um no that could
7082
04:59:40,798 --> 04:59:43,440
be part of a go module but it's not a go
7083
04:59:43,440 --> 04:59:44,480
module
7084
04:59:44,480 --> 04:59:46,680
itself a collection of packages that are
7085
04:59:46,680 --> 04:59:49,360
released together that is accurate a
7086
04:59:49,360 --> 04:59:52,160
file of go code no a module will contain
7087
04:59:52,160 --> 04:59:55,000
many many files of go code um or a
7088
04:59:55,000 --> 04:59:57,520
library package and again no not
7089
04:59:57,520 --> 04:59:59,080
necessarily you could have a module
7090
04:59:59,080 --> 05:00:01,400
that's just a single Library package but
7091
05:00:01,400 --> 05:00:03,600
a go module can be many more packages
7092
05:00:03,600 --> 05:00:05,280
than that or it could be a main package
7093
05:00:05,280 --> 05:00:06,600
for example so it's going to be a
7094
05:00:06,600 --> 05:00:08,958
collection of packages that are released
7095
05:00:08,958 --> 05:00:11,360
together so we need to talk just a
7096
05:00:11,360 --> 05:00:14,680
little bit more about these import paths
7097
05:00:14,680 --> 05:00:16,798
now if you're familiar with npm from the
7098
05:00:16,798 --> 05:00:19,520
JavaScript e ecosystem uh cargo from the
7099
05:00:19,520 --> 05:00:21,958
rust ecosystem or pip from the python
7100
05:00:21,958 --> 05:00:23,718
ecosystem then you're probably familiar
7101
05:00:23,718 --> 05:00:26,160
with the idea of a namespace for a third
7102
05:00:26,160 --> 05:00:28,680
party package for example I might make a
7103
05:00:28,680 --> 05:00:32,160
package called Left pad publish it up to
7104
05:00:32,160 --> 05:00:35,000
npms uh Central repository and now
7105
05:00:35,000 --> 05:00:36,920
anyone in the world just knowing my kind
7106
05:00:36,920 --> 05:00:39,400
of namespace name uh leftpad can
7107
05:00:39,400 --> 05:00:42,920
download use my code as a dependency the
7108
05:00:42,920 --> 05:00:44,920
interesting thing about the go ecosystem
7109
05:00:44,920 --> 05:00:47,440
is that there is no central location for
7110
05:00:47,440 --> 05:00:51,920
thirdparty packages like npmjs.com in
7111
05:00:51,920 --> 05:00:55,280
JavaScript land instead the gotool chain
7112
05:00:55,280 --> 05:00:58,440
sort of works on top of git and actually
7113
05:00:58,440 --> 05:01:02,200
uses the import path as the remote URL
7114
05:01:02,200 --> 05:01:04,718
and it looks to that import path for
7115
05:01:04,718 --> 05:01:07,320
where it can go download code so more
7116
05:01:07,320 --> 05:01:09,558
often than not you'll see modules with
7117
05:01:09,558 --> 05:01:11,760
import paths that start with github.com
7118
05:01:11,760 --> 05:01:14,558
or gitlab.com because that's where the
7119
05:01:14,558 --> 05:01:17,280
code itself is hosted an important
7120
05:01:17,280 --> 05:01:19,480
exception to this rule that the import
7121
05:01:19,480 --> 05:01:20,798
path is where you go to download the
7122
05:01:20,798 --> 05:01:22,760
code is the standard Library you don't
7123
05:01:22,760 --> 05:01:25,160
need to download standard Library code
7124
05:01:25,160 --> 05:01:28,200
it comes packaged with the go tool chain
7125
05:01:28,200 --> 05:01:29,920
so the question is do packages in the
7126
05:01:29,920 --> 05:01:31,878
standard Library have a module path
7127
05:01:31,878 --> 05:01:34,718
prefix the answer is
7128
05:01:34,718 --> 05:01:37,638
no the next question is what is an
7129
05:01:37,638 --> 05:01:39,000
import path and I know we've already
7130
05:01:39,000 --> 05:01:40,558
talked about this but I to show you a
7131
05:01:40,558 --> 05:01:42,878
more concrete example so this is the
7132
05:01:42,878 --> 05:01:44,280
github.com
7133
05:01:44,280 --> 05:01:48,680
waglan go- rabbitmq GitHub repository so
7134
05:01:48,680 --> 05:01:50,320
this is a GitHub repository that I
7135
05:01:50,320 --> 05:01:52,480
maintain it's just a little package for
7136
05:01:52,480 --> 05:01:55,200
Rabbid mq users a little go client for
7137
05:01:55,200 --> 05:01:58,200
Rabbid mq so this is a library module
7138
05:01:58,200 --> 05:02:00,760
and a library package it's intended for
7139
05:02:00,760 --> 05:02:03,160
other developers to actually import this
7140
05:02:03,160 --> 05:02:05,680
code into their applications it's not a
7141
05:02:05,680 --> 05:02:08,878
standalone you know main package so
7142
05:02:08,878 --> 05:02:12,280
let's take a look at the file structure
7143
05:02:12,280 --> 05:02:13,878
at the very root of the repository we
7144
05:02:13,878 --> 05:02:17,120
have the go dood file now this is that
7145
05:02:17,120 --> 05:02:20,080
kind of simple standard setup where one
7146
05:02:20,080 --> 05:02:22,600
git repository happens to have one go
7147
05:02:22,600 --> 05:02:26,080
modable or one sort of releasable unit
7148
05:02:26,080 --> 05:02:29,958
of code and if we take a peek inside we
7149
05:02:29,958 --> 05:02:33,400
can see that the go dood file uh
7150
05:02:33,400 --> 05:02:37,120
specifies the import path github.com
7151
05:02:37,120 --> 05:02:41,760
waglan go- rabbitmq Q so this matches
7152
05:02:41,760 --> 05:02:45,280
the URL of the git repository hosted on
7153
05:02:45,280 --> 05:02:48,160
GitHub now here's the interesting thing
7154
05:02:48,160 --> 05:02:52,600
this module only has one package that's
7155
05:02:52,600 --> 05:02:54,160
exported to the outside world and it
7156
05:02:54,160 --> 05:02:55,520
exists here at this top level so you can
7157
05:02:55,520 --> 05:02:58,080
see all of these go files consume. Go
7158
05:02:58,080 --> 05:03:00,400
consumer options. go they exist at the
7159
05:03:00,400 --> 05:03:03,320
top level of the repository so when you
7160
05:03:03,320 --> 05:03:06,680
import this package to use it you just
7161
05:03:06,680 --> 05:03:10,120
import from this root path because the
7162
05:03:10,120 --> 05:03:13,080
root package is what you're importing
7163
05:03:13,080 --> 05:03:16,040
there are no sub packages to import here
7164
05:03:16,040 --> 05:03:17,520
but let's pretend for a second that we
7165
05:03:17,520 --> 05:03:20,400
did want to export another package in
7166
05:03:20,400 --> 05:03:23,000
the same go module so we have our top
7167
05:03:23,000 --> 05:03:26,000
level go module G rabbit mq and the top
7168
05:03:26,000 --> 05:03:28,638
level package that can be accessed at
7169
05:03:28,638 --> 05:03:31,798
the same import path as the module let's
7170
05:03:31,798 --> 05:03:34,240
say we added another directory we could
7171
05:03:34,240 --> 05:03:36,718
call it maybe networks and inside it
7172
05:03:36,718 --> 05:03:39,360
would be the networks package if someone
7173
05:03:39,360 --> 05:03:42,160
wanted to import that package then they
7174
05:03:42,160 --> 05:03:44,160
would take the import path for the
7175
05:03:44,160 --> 05:03:46,520
entire module github.com
7176
05:03:46,520 --> 05:03:49,718
waglan rabbitmq which points to the root
7177
05:03:49,718 --> 05:03:51,558
package like we already talked about and
7178
05:03:51,558 --> 05:03:53,520
it would just append another slash
7179
05:03:53,520 --> 05:03:56,160
networks onto the end right so the
7180
05:03:56,160 --> 05:03:59,558
module path serves as a prefix for any
7181
05:03:59,558 --> 05:04:02,680
nested packages so to answer the
7182
05:04:02,680 --> 05:04:05,200
original question what is an import path
7183
05:04:05,200 --> 05:04:07,040
well it's not an HTTP connection and
7184
05:04:07,040 --> 05:04:09,440
it's not a restful server it's a module
7185
05:04:09,440 --> 05:04:10,440
path
7186
05:04:10,440 --> 05:04:14,558
plus an optional package subdirectory so
7187
05:04:14,558 --> 05:04:16,520
we've talked about repositories modules
7188
05:04:16,520 --> 05:04:18,520
packages you've got go installed now
7189
05:04:18,520 --> 05:04:20,240
let's talk about how you can set up your
7190
05:04:20,240 --> 05:04:22,958
local development environment and some
7191
05:04:22,958 --> 05:04:24,240
of this stuff isn't going to be
7192
05:04:24,240 --> 05:04:25,760
necessary and I'll point that out but I
7193
05:04:25,760 --> 05:04:27,520
do want to show you how I've set up my
7194
05:04:27,520 --> 05:04:29,798
machine um and you can emulate the way I
7195
05:04:29,798 --> 05:04:33,000
do it if you like that style now I need
7196
05:04:33,000 --> 05:04:36,400
to mention the go paath if you're
7197
05:04:36,400 --> 05:04:37,840
Googling around trying to figure out how
7198
05:04:37,840 --> 05:04:39,080
to set up your local development
7199
05:04:39,080 --> 05:04:40,798
environment for go you will almost
7200
05:04:40,798 --> 05:04:42,840
certainly come across old outdated
7201
05:04:42,840 --> 05:04:45,440
articles that talk about the go path in
7202
05:04:45,440 --> 05:04:47,480
kind of any version newer than I think
7203
05:04:47,480 --> 05:04:50,400
it's 1.13 right so we're on
7204
05:04:50,400 --> 05:04:53,920
1.20 now um you can basically forget
7205
05:04:53,920 --> 05:04:55,600
about the go path you don't need to
7206
05:04:55,600 --> 05:04:57,840
worry about it um you used to have to
7207
05:04:57,840 --> 05:05:00,638
put your code in the go path um now the
7208
05:05:00,638 --> 05:05:02,520
recommended way is actually to not put
7209
05:05:02,520 --> 05:05:04,958
your code in the go path can be a little
7210
05:05:04,958 --> 05:05:07,280
confusing but again generally speaking
7211
05:05:07,280 --> 05:05:09,440
you can just forget about the go path
7212
05:05:09,440 --> 05:05:11,440
and if you find any articles that talk
7213
05:05:11,440 --> 05:05:14,280
about it they're probably outdated the
7214
05:05:14,280 --> 05:05:17,680
entire idea of go modules is what
7215
05:05:17,680 --> 05:05:20,400
replaced the old go path so the question
7216
05:05:20,400 --> 05:05:22,400
is do you need to put your code inside
7217
05:05:22,400 --> 05:05:25,280
of your go path um the answers are yes
7218
05:05:25,280 --> 05:05:26,638
it doesn't matter and no in fact you
7219
05:05:26,638 --> 05:05:29,360
shouldn't and actually in fact you
7220
05:05:29,360 --> 05:05:30,480
[Music]
7221
05:05:30,480 --> 05:05:32,680
shouldn't so I've altered my window
7222
05:05:32,680 --> 05:05:34,558
layout um so that's a little bit easier
7223
05:05:34,558 --> 05:05:36,360
for you to see what I'm doing I've got
7224
05:05:36,360 --> 05:05:38,040
the boot Dev instructions over here on
7225
05:05:38,040 --> 05:05:40,718
the left and then I've got vs code over
7226
05:05:40,718 --> 05:05:42,600
here on the right with my terminal at
7227
05:05:42,600 --> 05:05:44,480
the bottom cool so I'm just here in my
7228
05:05:44,480 --> 05:05:46,600
file system I'm not within the go path
7229
05:05:46,600 --> 05:05:47,958
I'm just kind of in my personal
7230
05:05:47,958 --> 05:05:50,120
workspace um and we'll just follow these
7231
05:05:50,120 --> 05:05:51,320
instructions it says create a new
7232
05:05:51,320 --> 05:05:53,718
directory and enter it so we'll make
7233
05:05:53,718 --> 05:05:55,920
directory hello
7234
05:05:55,920 --> 05:05:59,320
go and me just LS show you the new
7235
05:05:59,320 --> 05:06:01,320
directory was created and we'll enter
7236
05:06:01,320 --> 05:06:05,000
that directory cool now inside of that
7237
05:06:05,000 --> 05:06:06,920
new hello go directory I'm going to
7238
05:06:06,920 --> 05:06:08,600
create a new go module so we'll do go
7239
05:06:08,600 --> 05:06:10,360
mod in it
7240
05:06:10,360 --> 05:06:12,760
and I keep all of my code on GitHub so
7241
05:06:12,760 --> 05:06:14,920
I'll do github.com
7242
05:06:14,920 --> 05:06:17,558
SL my username because that's my
7243
05:06:17,558 --> 05:06:21,040
namespace on GitHub so Wags Lane slash
7244
05:06:21,040 --> 05:06:23,200
the name of this project which uh we're
7245
05:06:23,200 --> 05:06:26,878
just calling hello go cool says go
7246
05:06:26,878 --> 05:06:29,600
creating new module um now if I LS I
7247
05:06:29,600 --> 05:06:33,718
should see that new go.mod file next
7248
05:06:33,718 --> 05:06:36,200
let's go ahead and take a look at that
7249
05:06:36,200 --> 05:06:38,920
file so you can see it just created a
7250
05:06:38,920 --> 05:06:40,400
new module
7251
05:06:40,400 --> 05:06:43,558
github.com wax laneel go with the Go
7252
05:06:43,558 --> 05:06:45,558
version and there are no dependencies
7253
05:06:45,558 --> 05:06:47,638
yet so there's no other sections to the
7254
05:06:47,638 --> 05:06:49,558
go module file so now that we're done
7255
05:06:49,558 --> 05:06:51,440
with this step the question is why does
7256
05:06:51,440 --> 05:06:54,520
go include a remote URL in module paths
7257
05:06:54,520 --> 05:06:57,958
right so this is a remote URL in theory
7258
05:06:57,958 --> 05:06:59,440
right when we push this up to GitHub
7259
05:06:59,440 --> 05:07:02,600
we'll push it up to this URL um and the
7260
05:07:02,600 --> 05:07:04,958
answ are to confuse new Gophers uh to
7261
05:07:04,958 --> 05:07:06,400
ensure that developers are using Source
7262
05:07:06,400 --> 05:07:08,120
control or to simplify remote
7263
05:07:08,120 --> 05:07:09,958
downloading of packages and it is
7264
05:07:09,958 --> 05:07:12,520
definitely that last one the next
7265
05:07:12,520 --> 05:07:15,000
question on the same step asks what is
7266
05:07:15,000 --> 05:07:18,638
Hello go in our case the repository SL
7267
05:07:18,638 --> 05:07:21,878
directory name or the module path prefix
7268
05:07:21,878 --> 05:07:24,638
and in our case it's actually the name
7269
05:07:24,638 --> 05:07:26,558
of the repository so again if we were to
7270
05:07:26,558 --> 05:07:28,718
push this up to GitHub um GitHub is the
7271
05:07:28,718 --> 05:07:30,360
name of the website where it's hosted
7272
05:07:30,360 --> 05:07:32,920
wag Lane is my namespace on GitHub and
7273
05:07:32,920 --> 05:07:35,480
hello go would be the name of the
7274
05:07:35,480 --> 05:07:37,480
directory that we are in and the name of
7275
05:07:37,480 --> 05:07:41,440
the repository up on GitHub
7276
05:07:44,798 --> 05:07:46,040
then this next question is just to make
7277
05:07:46,040 --> 05:07:48,520
sure that we completed the step properly
7278
05:07:48,520 --> 05:07:50,000
what does the first line of go dood
7279
05:07:50,000 --> 05:07:53,160
contain and it contains module followed
7280
05:07:53,160 --> 05:07:57,440
by the module path now so that VSS code
7281
05:07:57,440 --> 05:08:00,000
will work properly with all my syntax
7282
05:08:00,000 --> 05:08:01,480
highlighting with the go plugin I'm
7283
05:08:01,480 --> 05:08:06,400
actually going to reopen uh vs code to
7284
05:08:06,400 --> 05:08:08,680
that same directory the hello go
7285
05:08:08,680 --> 05:08:10,120
directory so we'll just be working
7286
05:08:10,120 --> 05:08:14,160
within this module uh for a
7287
05:08:14,160 --> 05:08:16,840
second and the instructions say inside
7288
05:08:16,840 --> 05:08:19,600
of hello go so now I'm inside of this
7289
05:08:19,600 --> 05:08:21,958
hello go directory at kind of the top
7290
05:08:21,958 --> 05:08:25,360
level of uh my vs code window um it says
7291
05:08:25,360 --> 05:08:27,080
create a new file called main.go so
7292
05:08:27,080 --> 05:08:29,280
let's go ahead and do
7293
05:08:29,280 --> 05:08:31,718
that conventionally the file in the main
7294
05:08:31,718 --> 05:08:33,440
package uh that contains the main
7295
05:08:33,440 --> 05:08:36,400
function is called main.go uh paste the
7296
05:08:36,400 --> 05:08:38,000
following code into your file Okay cool
7297
05:08:38,000 --> 05:08:40,558
so we should all be familiar with this
7298
05:08:40,558 --> 05:08:43,280
code by now right we've we've probably
7299
05:08:43,280 --> 05:08:46,160
written code like this uh I don't know
7300
05:08:46,160 --> 05:08:48,520
almost a hundred times by now in the
7301
05:08:48,520 --> 05:08:51,200
boot Dev platform next it looks like
7302
05:08:51,200 --> 05:08:53,480
we're just going to run the code using
7303
05:08:53,480 --> 05:08:57,798
the go tool chains interpreter so gun
7304
05:08:57,798 --> 05:08:59,200
main.go
7305
05:08:59,200 --> 05:09:03,000
and we get a nice hello world printed to
7306
05:09:03,000 --> 05:09:05,240
the console there's sort of two main
7307
05:09:05,240 --> 05:09:08,040
ways to run go code locally one is with
7308
05:09:08,040 --> 05:09:10,440
the G run command like we just used the
7309
05:09:10,440 --> 05:09:12,080
other is to use the go build command
7310
05:09:12,080 --> 05:09:13,878
which we'll get into in just a second
7311
05:09:13,878 --> 05:09:17,400
and actually in general I prefer the go
7312
05:09:17,400 --> 05:09:20,480
build method uh G run is really only
7313
05:09:20,480 --> 05:09:22,600
suitable for when you're running uh tiny
7314
05:09:22,600 --> 05:09:25,520
little scripts like this one and just to
7315
05:09:25,520 --> 05:09:28,320
be clear about the difference G run so
7316
05:09:28,320 --> 05:09:33,080
gun main.go runs the go code in the file
7317
05:09:33,080 --> 05:09:34,760
that we pass in right in this case
7318
05:09:34,760 --> 05:09:37,798
main.go and and that's all it does go
7319
05:09:37,798 --> 05:09:39,958
build actually builds a production
7320
05:09:39,958 --> 05:09:42,440
executable um which is how you'll use
7321
05:09:42,440 --> 05:09:44,840
your go code in the real world so I
7322
05:09:44,840 --> 05:09:46,440
typically prefer building that
7323
05:09:46,440 --> 05:09:48,280
production executable um just because
7324
05:09:48,280 --> 05:09:49,958
it's more accurately reflects how your
7325
05:09:49,958 --> 05:09:52,558
code will run in production so the
7326
05:09:52,558 --> 05:09:55,400
question on this step is does g run
7327
05:09:55,400 --> 05:09:57,718
build a production executable and the
7328
05:09:57,718 --> 05:09:59,878
answer is no it just kind of oneoff runs
7329
05:09:59,878 --> 05:10:02,240
your code it doesn't build any uh
7330
05:10:02,240 --> 05:10:04,958
production ready artifacts now at the
7331
05:10:04,958 --> 05:10:06,958
end of this same step we were asked to
7332
05:10:06,958 --> 05:10:09,000
execute the go help run command in our
7333
05:10:09,000 --> 05:10:13,320
Shelf so go help run um which just
7334
05:10:13,320 --> 05:10:15,440
prints out a bunch of help information
7335
05:10:15,440 --> 05:10:18,400
on how to use uh the G run command and
7336
05:10:18,400 --> 05:10:20,520
the question for the step says uh which
7337
05:10:20,520 --> 05:10:22,958
can go run except as arguments if we
7338
05:10:22,958 --> 05:10:24,840
scroll to the top so here's where I ran
7339
05:10:24,840 --> 05:10:27,840
go help run uh we can see the usage
7340
05:10:27,840 --> 05:10:30,320
information and it says run compiles and
7341
05:10:30,320 --> 05:10:33,160
runs the named main go package typically
7342
05:10:33,160 --> 05:10:35,558
the package is specified as a list of.go
7343
05:10:35,558 --> 05:10:37,520
source files from a single directory but
7344
05:10:37,520 --> 05:10:39,360
it can also be an import path file
7345
05:10:39,360 --> 05:10:41,920
system path or pattern matching a single
7346
05:10:41,920 --> 05:10:44,920
known package so which can go run accept
7347
05:10:44,920 --> 05:10:47,638
as arguments package names file names um
7348
05:10:47,638 --> 05:10:49,160
it actually looks like it can handle
7349
05:10:49,160 --> 05:10:51,840
both great now we get to use go build so
7350
05:10:51,840 --> 05:10:53,440
you can for the most part just forget
7351
05:10:53,440 --> 05:10:55,600
about G run you probably don't need to
7352
05:10:55,600 --> 05:10:58,680
use it um all too often so go build
7353
05:10:58,680 --> 05:11:00,520
compiles go code into an executable
7354
05:11:00,520 --> 05:11:02,440
program so all you need to do is make
7355
05:11:02,440 --> 05:11:05,160
sure that you're in the same uh kind of
7356
05:11:05,160 --> 05:11:07,320
main package that you want to build so
7357
05:11:07,320 --> 05:11:09,840
I'm here in the hell go directory
7358
05:11:09,840 --> 05:11:12,000
um I can LS to prove it to you we've got
7359
05:11:12,000 --> 05:11:14,798
the main.go file here package main Funk
7360
05:11:14,798 --> 05:11:18,520
main all that good stuff uh we'll run go
7361
05:11:18,520 --> 05:11:20,878
build we don't even need to pass in
7362
05:11:20,878 --> 05:11:23,520
package or file names it just builds uh
7363
05:11:23,520 --> 05:11:26,000
the package of the current directory so
7364
05:11:26,000 --> 05:11:28,440
as you can see here we have this new
7365
05:11:28,440 --> 05:11:32,000
executable binary in our current helloo
7366
05:11:32,000 --> 05:11:34,440
directory now if you remember way back
7367
05:11:34,440 --> 05:11:36,600
to I think chapter one of this course we
7368
05:11:36,600 --> 05:11:37,878
talked about the difference between
7369
05:11:37,878 --> 05:11:40,000
interpreted languages and and compiled
7370
05:11:40,000 --> 05:11:42,240
languages and one of the amazing things
7371
05:11:42,240 --> 05:11:45,558
about go is that we build compiled
7372
05:11:45,558 --> 05:11:48,240
executables that we can execute anywhere
7373
05:11:48,240 --> 05:11:51,240
so this hello go binary we can now copy
7374
05:11:51,240 --> 05:11:53,440
this put it on another machine and run
7375
05:11:53,440 --> 05:11:55,280
it without even needing to install the
7376
05:11:55,280 --> 05:11:57,798
go tool chain on that machine this is
7377
05:11:57,798 --> 05:12:01,280
compiled machine code so we can now run
7378
05:12:01,280 --> 05:12:03,440
this hello go program like we would any
7379
05:12:03,440 --> 05:12:07,480
other executable /hello go and it prints
7380
05:12:07,480 --> 05:12:09,480
hello world now I do want to show you a
7381
05:12:09,480 --> 05:12:11,760
little tip here because every time you
7382
05:12:11,760 --> 05:12:13,920
update your code let's say I change this
7383
05:12:13,920 --> 05:12:17,878
to hello world 2 if I just rerun hello
7384
05:12:17,878 --> 05:12:20,240
go it still will just print hello world
7385
05:12:20,240 --> 05:12:22,320
and that's because I didn't recompile my
7386
05:12:22,320 --> 05:12:24,440
code so a lot of new go developers kind
7387
05:12:24,440 --> 05:12:26,920
of forget to recompile their code and
7388
05:12:26,920 --> 05:12:28,200
they think they have bugs or their
7389
05:12:28,200 --> 05:12:29,558
codee's not doing what they expect you
7390
05:12:29,558 --> 05:12:31,320
have to recompile what I'd recommend
7391
05:12:31,320 --> 05:12:33,840
doing is just every time you update your
7392
05:12:33,840 --> 05:12:36,080
code and want to rerun it uh you should
7393
05:12:36,080 --> 05:12:37,320
build a compile and you can just do it
7394
05:12:37,320 --> 05:12:39,600
in the same step uh by doing go build
7395
05:12:39,600 --> 05:12:42,480
and then double Amper sand do/ the name
7396
05:12:42,480 --> 05:12:44,840
of your binary so this basically says
7397
05:12:44,840 --> 05:12:48,320
compile my code if that succeeds run the
7398
05:12:48,320 --> 05:12:50,520
compiled binary and the question for
7399
05:12:50,520 --> 05:12:52,400
this step is what was created after
7400
05:12:52,400 --> 05:12:54,958
running go build an executable file
7401
05:12:54,958 --> 05:12:57,080
named main an executable file named
7402
05:12:57,080 --> 05:13:00,600
hello go or a package named CMD and in
7403
05:13:00,600 --> 05:13:02,600
this case it was an executable file
7404
05:13:02,600 --> 05:13:04,958
named hello go right we've got it right
7405
05:13:04,958 --> 05:13:06,400
there it just kind of defaults to the
7406
05:13:06,400 --> 05:13:08,840
name um of the directory the next
7407
05:13:08,840 --> 05:13:10,440
question for this step is what happens
7408
05:13:10,440 --> 05:13:13,718
when you run /hello go and I actually
7409
05:13:13,718 --> 05:13:15,878
changed this to hello world to but if we
7410
05:13:15,878 --> 05:13:18,400
do it again after changing the code back
7411
05:13:18,400 --> 05:13:21,120
um the options are program panics hello
7412
05:13:21,120 --> 05:13:23,320
world is printed or the code compiles um
7413
05:13:23,320 --> 05:13:25,080
hello world is printed and it's
7414
05:13:25,080 --> 05:13:26,958
important to understand here the reason
7415
05:13:26,958 --> 05:13:29,360
we don't say the code compiles is
7416
05:13:29,360 --> 05:13:32,400
because at this Steph Helo all we are
7417
05:13:32,400 --> 05:13:34,520
doing is running the compiled binary
7418
05:13:34,520 --> 05:13:38,400
we're not recompiling the code the next
7419
05:13:38,400 --> 05:13:40,520
command in the go tool chain that we're
7420
05:13:40,520 --> 05:13:43,000
going to talk about is go install now to
7421
05:13:43,000 --> 05:13:45,040
be honest I don't use it a ton but I
7422
05:13:45,040 --> 05:13:46,320
still think it's important to understand
7423
05:13:46,320 --> 05:13:48,958
because you'll see it around okay so Ure
7424
05:13:48,958 --> 05:13:50,878
you're in your hello repo then run go
7425
05:13:50,878 --> 05:13:52,440
install so I'm here in the hello
7426
05:13:52,440 --> 05:13:55,878
directory and we run go
7427
05:13:55,878 --> 05:13:58,798
install and next we navigate out of our
7428
05:13:58,798 --> 05:14:00,080
project directory so I'm going to go up
7429
05:14:00,080 --> 05:14:01,080
one
7430
05:14:01,080 --> 05:14:04,638
level and what it's telling me is go has
7431
05:14:04,638 --> 05:14:07,400
installed the hello go program globally
7432
05:14:07,400 --> 05:14:09,480
so the go tool chain when we ran go
7433
05:14:09,480 --> 05:14:11,718
install basically compiled that code and
7434
05:14:11,718 --> 05:14:13,558
then made it globally accessible to our
7435
05:14:13,558 --> 05:14:16,520
entire machine so now if I run hello go
7436
05:14:16,520 --> 05:14:18,520
notice without the dot slash because I'm
7437
05:14:18,520 --> 05:14:20,240
not running a program in my current
7438
05:14:20,240 --> 05:14:22,120
directory I'm running now a program
7439
05:14:22,120 --> 05:14:24,040
that's in my
7440
05:14:24,040 --> 05:14:26,680
path it prints hello world so now I can
7441
05:14:26,680 --> 05:14:29,638
use this script that I built anywhere on
7442
05:14:29,638 --> 05:14:32,520
my machine which is just super useful um
7443
05:14:32,520 --> 05:14:34,638
if you're building kind of scripts for
7444
05:14:34,638 --> 05:14:36,798
your own local productivity so the
7445
05:14:36,798 --> 05:14:38,520
question for this step is what does go
7446
05:14:38,520 --> 05:14:41,000
install do saves local code to the
7447
05:14:41,000 --> 05:14:43,080
remote Source control provider installs
7448
05:14:43,080 --> 05:14:45,240
dependencies or compiles and installs
7449
05:14:45,240 --> 05:14:46,920
the program locally and the answer is
7450
05:14:46,920 --> 05:14:48,520
that it compiles and installs the
7451
05:14:48,520 --> 05:14:50,360
program locally again you would really
7452
05:14:50,360 --> 05:14:52,360
only use this if you're building scripts
7453
05:14:52,360 --> 05:14:54,638
for your own personal use on your
7454
05:14:54,638 --> 05:14:57,480
machine the next question for this same
7455
05:14:57,480 --> 05:15:00,280
step is code must be compiled with go
7456
05:15:00,280 --> 05:15:02,760
build before running go install it's
7457
05:15:02,760 --> 05:15:04,200
true false now if you were paying
7458
05:15:04,200 --> 05:15:06,120
attention you probably noticed the
7459
05:15:06,120 --> 05:15:08,638
answer here but we actually ran go
7460
05:15:08,638 --> 05:15:09,480
andall
7461
05:15:09,480 --> 05:15:12,120
without a binary existing in our current
7462
05:15:12,120 --> 05:15:14,600
directory so if I go back into the hello
7463
05:15:14,600 --> 05:15:17,200
go directory and run go install you'll
7464
05:15:17,200 --> 05:15:19,878
see there's actually no hello go binary
7465
05:15:19,878 --> 05:15:21,680
that exists here um and it works just
7466
05:15:21,680 --> 05:15:24,280
the same so the codee does not need to
7467
05:15:24,280 --> 05:15:26,520
be compiled with go build
7468
05:15:26,520 --> 05:15:29,360
first all right so we've created a main
7469
05:15:29,360 --> 05:15:32,360
package and a executable program uh now
7470
05:15:32,360 --> 05:15:34,240
we're going to build a library package a
7471
05:15:34,240 --> 05:15:37,718
custom Library package so uh what we're
7472
05:15:37,718 --> 05:15:39,760
supposed to do is create a directory at
7473
05:15:39,760 --> 05:15:41,558
the same level as the hello go directory
7474
05:15:41,558 --> 05:15:42,760
so I'm in the hell go directory
7475
05:15:42,760 --> 05:15:45,160
currently I'm going to go up one level
7476
05:15:45,160 --> 05:15:47,958
and let's see so we've got helloo in
7477
05:15:47,958 --> 05:15:49,718
here I'm going to make a new directory
7478
05:15:49,718 --> 05:15:51,280
called my
7479
05:15:51,280 --> 05:15:54,760
strings and then we'll go into my
7480
05:15:54,760 --> 05:15:57,120
strings and here we need to initialize a
7481
05:15:57,120 --> 05:16:00,320
new go module so I'll do go mod in it
7482
05:16:00,320 --> 05:16:02,920
github.com Wags
7483
05:16:02,920 --> 05:16:06,280
Lane slash my
7484
05:16:06,280 --> 05:16:09,040
strings and that module is created now
7485
05:16:09,040 --> 05:16:11,480
to get my VSS code toing all working
7486
05:16:11,480 --> 05:16:14,160
properly again I'm going to just
7487
05:16:14,160 --> 05:16:17,280
reopen VSS code to that level so we'll
7488
05:16:17,280 --> 05:16:19,120
go back and find the
7489
05:16:19,120 --> 05:16:22,000
myrings directory and open directly into
7490
05:16:22,000 --> 05:16:23,200
that
7491
05:16:23,200 --> 05:16:25,040
directory
7492
05:16:25,040 --> 05:16:27,520
okay next we create a new file called
7493
05:16:27,520 --> 05:16:30,920
myrings Dogo so this is the go dood that
7494
05:16:30,920 --> 05:16:33,040
we created with the go mod in nit
7495
05:16:33,040 --> 05:16:34,878
command and now we're creating a new
7496
05:16:34,878 --> 05:16:39,040
file called myrings Dogo
7497
05:16:39,040 --> 05:16:43,360
and we want to paste the following
7498
05:16:43,680 --> 05:16:46,760
code okay so package my strings that's
7499
05:16:46,760 --> 05:16:48,240
the first thing to notice right this is
7500
05:16:48,240 --> 05:16:50,240
not a main package so we won't be able
7501
05:16:50,240 --> 05:16:53,480
to build this package as a standalone
7502
05:16:53,480 --> 05:16:56,040
executable this package will be kind of
7503
05:16:56,040 --> 05:16:58,400
the intention is for us to use it in our
7504
05:16:58,400 --> 05:17:01,440
other hello go package the other thing
7505
05:17:01,440 --> 05:17:04,600
to notice about this code aside from the
7506
05:17:04,600 --> 05:17:07,958
package name is that there is no main
7507
05:17:07,958 --> 05:17:10,080
function here again because it's not an
7508
05:17:10,080 --> 05:17:12,240
executable program we're just going to
7509
05:17:12,240 --> 05:17:15,320
be exporting functions that can be used
7510
05:17:15,320 --> 05:17:18,080
in our main package let's talk a little
7511
05:17:18,080 --> 05:17:20,200
bit about this reverse function so this
7512
05:17:20,200 --> 05:17:22,520
is the only function in the myrings
7513
05:17:22,520 --> 05:17:25,000
package at the moment and uh you know
7514
05:17:25,000 --> 05:17:26,718
theoretically it reverses a string from
7515
05:17:26,718 --> 05:17:28,200
left to right although I haven't tested
7516
05:17:28,200 --> 05:17:30,280
it um but the important thing is that we
7517
05:17:30,280 --> 05:17:33,558
need to capitalize we need to capitalize
7518
05:17:33,558 --> 05:17:36,520
the first letter of the function's name
7519
05:17:36,520 --> 05:17:38,920
and that's because in go that's how we
7520
05:17:38,920 --> 05:17:42,520
export a function if it were little r
7521
05:17:42,520 --> 05:17:44,240
then this function would not be able to
7522
05:17:44,240 --> 05:17:46,440
be used outside of this package but we
7523
05:17:46,440 --> 05:17:48,480
want to export it because we want to be
7524
05:17:48,480 --> 05:17:50,440
able to use it in our main package right
7525
05:17:50,440 --> 05:17:52,558
in the helloo directory um and and kind
7526
05:17:52,558 --> 05:17:55,320
of import this logic and use it now
7527
05:17:55,320 --> 05:17:57,480
we're told to run the go build command
7528
05:17:57,480 --> 05:17:59,240
here in this directory and you'll notice
7529
05:17:59,240 --> 05:18:01,840
it doesn't actually seem to do anything
7530
05:18:01,840 --> 05:18:04,080
there again there was no executable file
7531
05:18:04,080 --> 05:18:05,718
that was built because this is not a
7532
05:18:05,718 --> 05:18:07,920
main package um but it is worth pointing
7533
05:18:07,920 --> 05:18:09,718
out that go build is still a useful
7534
05:18:09,718 --> 05:18:11,240
command because it checks for compile
7535
05:18:11,240 --> 05:18:13,400
time errors so for example if I uh
7536
05:18:13,400 --> 05:18:15,360
create an invalid token here and then
7537
05:18:15,360 --> 05:18:18,320
run go build uh we will get compile time
7538
05:18:18,320 --> 05:18:20,638
errors so it is um still kind of useful
7539
05:18:20,638 --> 05:18:22,760
just to make sure that this code
7540
05:18:22,760 --> 05:18:25,360
compiles so the question for the step is
7541
05:18:25,360 --> 05:18:27,680
what was the output of the go build
7542
05:18:27,680 --> 05:18:30,718
command in the library package um was it
7543
05:18:30,718 --> 05:18:32,200
an executable program or was the
7544
05:18:32,200 --> 05:18:34,000
compiled package silently saved to the
7545
05:18:34,000 --> 05:18:36,200
local build cache well we didn't get an
7546
05:18:36,200 --> 05:18:39,080
executable package right uh this is not
7547
05:18:39,080 --> 05:18:41,480
a main package so we don't get um a nice
7548
05:18:41,480 --> 05:18:43,600
runnable executable instead it is
7549
05:18:43,600 --> 05:18:45,120
silently saved to the local build cache
7550
05:18:45,120 --> 05:18:47,600
so it can be used later in an actual
7551
05:18:47,600 --> 05:18:50,600
executable program and then the next
7552
05:18:50,600 --> 05:18:53,000
question is why is the function capital
7553
05:18:53,000 --> 05:18:55,400
r reverse instead of lowercase are
7554
05:18:55,400 --> 05:18:58,360
reverse and it's lowercase names aren't
7555
05:18:58,360 --> 05:19:00,160
exported for external use or
7556
05:19:00,160 --> 05:19:01,760
conventionally uppercase names are used
7557
05:19:01,760 --> 05:19:04,200
in go the answer is that lowercase names
7558
05:19:04,200 --> 05:19:06,558
are not exported so by convention
7559
05:19:06,558 --> 05:19:09,320
functions can have either a lowercase
7560
05:19:09,320 --> 05:19:11,718
name or an uppercase name and uppercase
7561
05:19:11,718 --> 05:19:14,680
names are exported from the package so
7562
05:19:14,680 --> 05:19:16,440
this next question is does a package in
7563
05:19:16,440 --> 05:19:19,320
a folder named date parser need to also
7564
05:19:19,320 --> 05:19:21,400
be called Date parser right does the
7565
05:19:21,400 --> 05:19:23,558
package need to be date parser now
7566
05:19:23,558 --> 05:19:24,878
you'll notice that we created a
7567
05:19:24,878 --> 05:19:27,360
directory called my strings and a
7568
05:19:27,360 --> 05:19:29,920
package called my strings and if you
7569
05:19:29,920 --> 05:19:31,840
remember back to earlier in this chapter
7570
05:19:31,840 --> 05:19:34,280
we talked about how by convention that's
7571
05:19:34,280 --> 05:19:37,320
the best way to do it it's not necessary
7572
05:19:37,320 --> 05:19:40,000
um but it is it is the convention okay
7573
05:19:40,000 --> 05:19:42,840
so now let's use our reverse function
7574
05:19:42,840 --> 05:19:45,480
back in the main package in the hello
7575
05:19:45,480 --> 05:19:47,840
directory right so it says um modify
7576
05:19:47,840 --> 05:19:50,840
helloo main.go so I need to
7577
05:19:50,840 --> 05:19:54,240
reopen I'm going to open vs code back
7578
05:19:54,240 --> 05:19:59,320
into the hello go
7579
05:20:00,120 --> 05:20:02,480
directory it says modify hello Go's
7580
05:20:02,480 --> 05:20:05,798
main.go file okay so we'll use
7581
05:20:05,798 --> 05:20:08,200
parenthesis here so that we can do some
7582
05:20:08,200 --> 05:20:09,760
multip Le
7583
05:20:09,760 --> 05:20:12,760
Imports and we'll be using the import
7584
05:20:12,760 --> 05:20:16,440
path that matches the module name of our
7585
05:20:16,440 --> 05:20:18,040
my strings package so in my case it was
7586
05:20:18,040 --> 05:20:23,200
github.com Wags Lane slm
7587
05:20:23,200 --> 05:20:28,040
strings and then here we just copy this
7588
05:20:28,040 --> 05:20:30,798
code from the instructions and in fact
7589
05:20:30,798 --> 05:20:32,600
let me space this out so we can see it
7590
05:20:32,600 --> 05:20:35,280
just a little bit better Okay cool so
7591
05:20:35,280 --> 05:20:37,440
we've imported the myrings package and
7592
05:20:37,440 --> 05:20:39,480
then down in our code we we can use my
7593
05:20:39,480 --> 05:20:41,000
strings which is the name of the
7594
05:20:41,000 --> 05:20:43,160
package.
7595
05:20:43,160 --> 05:20:48,240
reverse to call that exported function
7596
05:20:48,240 --> 05:20:51,120
okay now because we've added a
7597
05:20:51,120 --> 05:20:53,480
dependency we need to update our go dood
7598
05:20:53,480 --> 05:20:57,878
file so edit the hell Go's go.mod file
7599
05:20:57,878 --> 05:20:59,160
to contain the
7600
05:20:59,160 --> 05:21:01,400
following this is the important part
7601
05:21:01,400 --> 05:21:02,200
down
7602
05:21:02,200 --> 05:21:04,718
here so we need to
7603
05:21:04,718 --> 05:21:08,000
add replace example.com username my
7604
05:21:08,000 --> 05:21:12,520
strings with do dotm strings and require
7605
05:21:12,520 --> 05:21:13,798
example.com
7606
05:21:13,798 --> 05:21:18,520
username myrings version z now I do need
7607
05:21:18,520 --> 05:21:20,400
to update this right because I didn't
7608
05:21:20,400 --> 05:21:25,798
use example.com I used github.com Wags
7609
05:21:26,080 --> 05:21:31,240
Lane now what's going on here right Go's
7610
05:21:31,240 --> 05:21:33,638
dependency management is very heavily
7611
05:21:33,638 --> 05:21:37,160
based on git and remote URLs so normally
7612
05:21:37,160 --> 05:21:39,680
what you would do is take your my
7613
05:21:39,680 --> 05:21:43,160
streams my strings package and push it
7614
05:21:43,160 --> 05:21:46,240
up to GitHub and then import it from
7615
05:21:46,240 --> 05:21:48,440
there and and sort of all of the go
7616
05:21:48,440 --> 05:21:50,680
packages in the world that require the
7617
05:21:50,680 --> 05:21:53,280
my strings package will point up to that
7618
05:21:53,280 --> 05:21:56,400
remote location that remote server what
7619
05:21:56,400 --> 05:22:00,160
we are doing here with this replace and
7620
05:22:00,160 --> 05:22:03,320
require well specifically the replace is
7621
05:22:03,320 --> 05:22:05,718
we're kind of doing a little hack to get
7622
05:22:05,718 --> 05:22:07,958
things to work locally without having to
7623
05:22:07,958 --> 05:22:10,840
publish to get so we're basically saying
7624
05:22:10,840 --> 05:22:13,798
I want you to take this string this
7625
05:22:13,798 --> 05:22:16,718
import path right github.com waglan
7626
05:22:16,718 --> 05:22:19,240
myrings and don't go look for it out on
7627
05:22:19,240 --> 05:22:22,840
the internet instead just resolve it to
7628
05:22:22,840 --> 05:22:26,120
this path dot do my strings right and
7629
05:22:26,120 --> 05:22:28,638
now because well I should probably get
7630
05:22:28,638 --> 05:22:31,200
back into the hello go
7631
05:22:31,200 --> 05:22:34,080
directory right do do/
7632
05:22:34,080 --> 05:22:37,360
myrings this is the directory containing
7633
05:22:37,360 --> 05:22:39,160
the my strings package
7634
05:22:39,160 --> 05:22:41,080
right so we're basically just saying
7635
05:22:41,080 --> 05:22:44,200
replace this with my local uh file
7636
05:22:44,200 --> 05:22:46,920
system we're telling go how to find this
7637
05:22:46,920 --> 05:22:49,638
package on our machine so now that we've
7638
05:22:49,638 --> 05:22:52,200
made those changes uh we can build and
7639
05:22:52,200 --> 05:22:55,400
run this program again so go
7640
05:22:55,400 --> 05:22:58,240
build slh
7641
05:22:58,240 --> 05:23:01,718
heloo build and run and it looks like
7642
05:23:01,718 --> 05:23:04,760
it's working correctly this this
7643
05:23:04,760 --> 05:23:06,120
function is supposed to reverse the
7644
05:23:06,120 --> 05:23:10,440
string and we get this nasty little
7645
05:23:10,878 --> 05:23:12,718
and the question is just asking us what
7646
05:23:12,718 --> 05:23:15,520
was printed and that's what we got on
7647
05:23:15,520 --> 05:23:18,080
the same step this next question asks
7648
05:23:18,080 --> 05:23:20,200
how does the go tool chain know where to
7649
05:23:20,200 --> 05:23:23,240
find the imported code npm hosts the
7650
05:23:23,240 --> 05:23:25,200
files publicly it downloads it from
7651
05:23:25,200 --> 05:23:27,680
Google's servers we use the replace
7652
05:23:27,680 --> 05:23:30,040
keyword in the Goot dood to point it to
7653
05:23:30,040 --> 05:23:32,080
the relative location of myrings or it
7654
05:23:32,080 --> 05:23:34,080
was fetched from GitHub now again I want
7655
05:23:34,080 --> 05:23:35,638
to point out that most of the time
7656
05:23:35,638 --> 05:23:37,600
you'll be fetching code from GitHub or
7657
05:23:37,600 --> 05:23:39,798
gitlab or some remote Source when you're
7658
05:23:39,798 --> 05:23:42,600
using thirdparty dependencies in our
7659
05:23:42,600 --> 05:23:46,840
case we used this replace keyword uh to
7660
05:23:46,840 --> 05:23:49,400
point the go tool chain to the location
7661
05:23:49,400 --> 05:23:52,680
of the myrings package on our machine so
7662
05:23:52,680 --> 05:23:54,520
we already briefly talked about this but
7663
05:23:54,520 --> 05:23:57,080
I just want to reiterate that this
7664
05:23:57,080 --> 05:24:00,240
little replace hack is useful for kind
7665
05:24:00,240 --> 05:24:01,878
of testing and doing things on our local
7666
05:24:01,878 --> 05:24:04,280
machine but it's not suitable for
7667
05:24:04,280 --> 05:24:06,240
production generally what you would do
7668
05:24:06,240 --> 05:24:08,360
is push up that my strings get repos
7669
05:24:08,360 --> 05:24:10,558
repository to GitHub and then import
7670
05:24:10,558 --> 05:24:13,958
from there so you will typically not see
7671
05:24:13,958 --> 05:24:17,718
replace aliases in production go dood
7672
05:24:17,718 --> 05:24:21,000
files very often you'll just see um
7673
05:24:21,000 --> 05:24:24,360
packages sort of required vanilla from
7674
05:24:24,360 --> 05:24:26,558
their remote location so now we're going
7675
05:24:26,558 --> 05:24:29,360
to practice using a remote thirdparty
7676
05:24:29,360 --> 05:24:31,480
module says create a new directory in
7677
05:24:31,480 --> 05:24:33,680
the same uh Parent Directory as hello
7678
05:24:33,680 --> 05:24:36,638
and myrings called Date test so let's go
7679
05:24:36,638 --> 05:24:39,360
back up one level and create a new
7680
05:24:39,360 --> 05:24:43,600
directory make dur date test and then
7681
05:24:43,600 --> 05:24:45,798
I'm going to go ahead and again reopen
7682
05:24:45,798 --> 05:24:47,718
vs
7683
05:24:47,718 --> 05:24:52,600
code into that
7684
05:24:53,200 --> 05:24:56,600
directory okay create a main.go with
7685
05:24:56,600 --> 05:24:57,440
this
7686
05:24:57,440 --> 05:25:00,958
code we can do
7687
05:25:04,280 --> 05:25:09,240
that next initialize a module so we do
7688
05:25:09,240 --> 05:25:13,120
to go mod and it and again I'll just use
7689
05:25:13,120 --> 05:25:13,840
good
7690
05:25:13,840 --> 05:25:18,558
hub.com Wags Lane SL date
7691
05:25:18,558 --> 05:25:21,798
test creating new go.mod to add module
7692
05:25:21,798 --> 05:25:24,200
requirements and Subs do go mod tidy
7693
05:25:24,200 --> 05:25:26,920
okay cool um I'm going to ignore that
7694
05:25:26,920 --> 05:25:28,320
for just a second and instead I'm going
7695
05:25:28,320 --> 05:25:29,480
to follow the instructions it says
7696
05:25:29,480 --> 05:25:31,240
download and install the remote go tiny
7697
05:25:31,240 --> 05:25:33,480
date package using go
7698
05:25:33,480 --> 05:25:36,040
get Okay so we've used go install in the
7699
05:25:36,040 --> 05:25:38,360
past right go install installs an
7700
05:25:38,360 --> 05:25:40,400
executable on our machine to be used
7701
05:25:40,400 --> 05:25:43,520
anywhere um goget is how we go download
7702
05:25:43,520 --> 05:25:46,040
and install third party dependencies so
7703
05:25:46,040 --> 05:25:48,760
we're going and grabbing the github.com
7704
05:25:48,760 --> 05:25:53,440
waglan slgo tiny time
7705
05:25:53,440 --> 05:25:56,440
module and it gets added
7706
05:25:56,440 --> 05:26:00,280
automatically to our go.mod you'll see
7707
05:26:00,280 --> 05:26:03,320
that it just kind of grabs the latest
7708
05:26:03,320 --> 05:26:06,080
version cool um print the contents of
7709
05:26:06,080 --> 05:26:08,400
your go onod uh I don't need to run that
7710
05:26:08,400 --> 05:26:09,798
because we've got it open here in vs
7711
05:26:09,798 --> 05:26:11,680
code um and then compile and run our
7712
05:26:11,680 --> 05:26:16,240
program again so let's do that go
7713
05:26:16,240 --> 05:26:20,958
build and run and it's going to compile
7714
05:26:20,958 --> 05:26:23,680
to a file called Date test right because
7715
05:26:23,680 --> 05:26:26,360
that's the name of our
7716
05:26:27,920 --> 05:26:30,600
directory cool and as you can see it's
7717
05:26:30,600 --> 05:26:33,520
printing out this date here so what did
7718
05:26:33,520 --> 05:26:37,840
we do right we used goget to download
7719
05:26:37,840 --> 05:26:40,120
code from this remote location which
7720
05:26:40,120 --> 05:26:42,320
also happens to be the import path right
7721
05:26:42,320 --> 05:26:44,958
because that's how go packages work
7722
05:26:44,958 --> 05:26:47,360
typically so let me go grab that and
7723
05:26:47,360 --> 05:26:51,000
just show you this
7724
05:26:51,000 --> 05:26:53,920
is this is a package that's hosted on
7725
05:26:53,920 --> 05:26:55,520
GitHub so the go tool chain actually
7726
05:26:55,520 --> 05:26:58,280
went to GitHub and downloaded this code
7727
05:26:58,280 --> 05:27:01,400
right added it to the go dood as a
7728
05:27:01,400 --> 05:27:03,400
dependency and then created this new
7729
05:27:03,400 --> 05:27:06,718
file called go. sum that kind of
7730
05:27:06,718 --> 05:27:10,160
contains any uh transient dependencies
7731
05:27:10,160 --> 05:27:13,760
or dependencies used by the go tiny time
7732
05:27:13,760 --> 05:27:15,320
package that we just imported so kind of
7733
05:27:15,320 --> 05:27:17,160
keeps track of everything that we're
7734
05:27:17,160 --> 05:27:19,200
using and the question for this one is
7735
05:27:19,200 --> 05:27:21,040
how did the go tool chain know where to
7736
05:27:21,040 --> 05:27:24,958
download the Go tiny time package oh man
7737
05:27:24,958 --> 05:27:27,080
this uh this question is not optimized
7738
05:27:27,080 --> 05:27:30,200
for this ridiculously zoomed in view it
7739
05:27:30,200 --> 05:27:31,878
says the module import path is used for
7740
05:27:31,878 --> 05:27:35,240
remote lookups EG github.com Wags Lane
7741
05:27:35,240 --> 05:27:37,718
go timing time um or the go tool chain
7742
05:27:37,718 --> 05:27:40,080
has free open source go modules location
7743
05:27:40,080 --> 05:27:42,638
memorized uh that is not true it just it
7744
05:27:42,638 --> 05:27:44,638
just does a remote lookup right it goes
7745
05:27:44,638 --> 05:27:48,958
and fetches that from the remote git URL
7746
05:27:48,958 --> 05:27:50,200
and then just to make sure that we did
7747
05:27:50,200 --> 05:27:52,840
the step correctly uh it's asking us
7748
05:27:52,840 --> 05:27:54,160
what was printed after running the new
7749
05:27:54,160 --> 05:27:57,040
date test program can see it right there
7750
05:27:57,040 --> 05:27:58,958
it looks like it's this
7751
05:27:58,958 --> 05:28:02,520
2020-4 d03 right it's it's this
7752
05:28:02,520 --> 05:28:09,120
hardcoded date in RFC 3339 format
7753
05:28:09,120 --> 05:28:10,638
so hopefully that last section gave you
7754
05:28:10,638 --> 05:28:12,638
a taste of local development at least
7755
05:28:12,638 --> 05:28:14,040
showing you how to build and compile
7756
05:28:14,040 --> 05:28:15,920
some code on your own machine we'll
7757
05:28:15,920 --> 05:28:17,718
obviously be doing a lot more local
7758
05:28:17,718 --> 05:28:19,160
development at the end of this video
7759
05:28:19,160 --> 05:28:21,160
with the project uh but for now for the
7760
05:28:21,160 --> 05:28:22,520
rest of this course we'll be back
7761
05:28:22,520 --> 05:28:25,320
working in the boot Dev web interface
7762
05:28:25,320 --> 05:28:28,360
cool so we're on to talking about clean
7763
05:28:28,360 --> 05:28:31,240
packages and this is kind of just a an
7764
05:28:31,240 --> 05:28:33,120
article that I'm not going to bother
7765
05:28:33,120 --> 05:28:35,320
reading out loud on screen but I'll talk
7766
05:28:35,320 --> 05:28:37,878
about each individual section as the
7767
05:28:37,878 --> 05:28:40,240
question questions are asked so the
7768
05:28:40,240 --> 05:28:43,718
question is should you export code from
7769
05:28:43,718 --> 05:28:46,638
the main package and that's talked about
7770
05:28:46,638 --> 05:28:49,240
um down here it's basically simple don't
7771
05:28:49,240 --> 05:28:50,878
export code from the main package and if
7772
05:28:50,878 --> 05:28:52,080
you think about it it makes sense
7773
05:28:52,080 --> 05:28:54,120
there's no reason to capitalize function
7774
05:28:54,120 --> 05:28:56,520
names in the main package because no
7775
05:28:56,520 --> 05:28:59,120
other packages can import from a main
7776
05:28:59,120 --> 05:29:01,440
package a main package is built into its
7777
05:29:01,440 --> 05:29:03,558
own Standalone executable it's not a
7778
05:29:03,558 --> 05:29:07,000
library so capitalizing functions in the
7779
05:29:07,000 --> 05:29:08,680
main package is just kind kind of
7780
05:29:08,680 --> 05:29:10,958
confusing because it kind of signals to
7781
05:29:10,958 --> 05:29:12,638
developers that you're writing code
7782
05:29:12,638 --> 05:29:16,160
that's meant to be imported and it's
7783
05:29:16,160 --> 05:29:19,000
not this next question says when should
7784
05:29:19,000 --> 05:29:22,558
you not export a function variable or
7785
05:29:22,558 --> 05:29:26,040
type now this is an interesting question
7786
05:29:26,040 --> 05:29:28,240
I think a lot of newer developers think
7787
05:29:28,240 --> 05:29:30,638
well maybe I should just export more
7788
05:29:30,638 --> 05:29:33,558
stuff because maybe the users of my
7789
05:29:33,558 --> 05:29:35,920
package will find it useful um you
7790
05:29:35,920 --> 05:29:38,040
actually want to think in the reverse
7791
05:29:38,040 --> 05:29:40,680
you want to export as few things as
7792
05:29:40,680 --> 05:29:42,798
possible when you're building Library
7793
05:29:42,798 --> 05:29:45,080
packages because anytime you export a
7794
05:29:45,080 --> 05:29:48,400
function you now need to support that
7795
05:29:48,400 --> 05:29:50,160
function right you can't really take it
7796
05:29:50,160 --> 05:29:52,920
away later everyone's code will break
7797
05:29:52,920 --> 05:29:54,320
right so you should really think about
7798
05:29:54,320 --> 05:29:57,120
what you're exposing to your users as
7799
05:29:57,120 --> 05:29:59,480
like the surface area of a shape and you
7800
05:29:59,480 --> 05:30:01,760
want to keep that surface area as small
7801
05:30:01,760 --> 05:30:03,760
as possible to keep the maintenance
7802
05:30:03,760 --> 05:30:06,160
burden down and to make your package
7803
05:30:06,160 --> 05:30:08,958
easy to use right the few things that
7804
05:30:08,958 --> 05:30:10,798
your users need to know about in order
7805
05:30:10,798 --> 05:30:12,798
to effectively use your package the
7806
05:30:12,798 --> 05:30:15,360
easier it'll be to use so when should
7807
05:30:15,360 --> 05:30:17,200
you not export a function variable or
7808
05:30:17,200 --> 05:30:19,760
type um when the end user doesn't need
7809
05:30:19,760 --> 05:30:22,160
to know about it hide everything that
7810
05:30:22,160 --> 05:30:25,200
they don't need to know about the next
7811
05:30:25,200 --> 05:30:27,320
question is should you often change a
7812
05:30:27,320 --> 05:30:30,558
packages exported API so API stands for
7813
05:30:30,558 --> 05:30:32,638
application programming interface and
7814
05:30:32,638 --> 05:30:34,760
basically anytime you export something
7815
05:30:34,760 --> 05:30:37,600
from a library package uh you're adding
7816
05:30:37,600 --> 05:30:41,080
that thing to the package's API right
7817
05:30:41,080 --> 05:30:43,520
it's the interface that other developers
7818
05:30:43,520 --> 05:30:46,520
will use to access your package so
7819
05:30:46,520 --> 05:30:48,280
should you often change a package's
7820
05:30:48,280 --> 05:30:51,040
exported API the answer is that no you
7821
05:30:51,040 --> 05:30:52,920
should try to keep changes to your
7822
05:30:52,920 --> 05:30:55,440
internal functionality right imagine if
7823
05:30:55,440 --> 05:30:57,520
the go programming language uh let's say
7824
05:30:57,520 --> 05:31:00,320
the standard Library changed fmt do
7825
05:31:00,320 --> 05:31:04,280
print line to fm. print right and just
7826
05:31:04,280 --> 05:31:07,760
removed fm. print line that would break
7827
05:31:07,760 --> 05:31:09,920
and an immense amount of code right so
7828
05:31:09,920 --> 05:31:11,920
you don't want to go about uh publishing
7829
05:31:11,920 --> 05:31:13,958
packages that you intend to kind of
7830
05:31:13,958 --> 05:31:17,200
update the API for uh very rapidly
7831
05:31:17,200 --> 05:31:20,878
stable apis are good apis so should you
7832
05:31:20,878 --> 05:31:23,000
often change a package as exported API
7833
05:31:23,000 --> 05:31:25,400
no try to keep the changes to internal
7834
05:31:25,400 --> 05:31:27,440
functionality yes move fast and break
7835
05:31:27,440 --> 05:31:30,638
things or if the package is main then
7836
05:31:30,638 --> 05:31:34,120
yes uh the answer is just no try to keep
7837
05:31:34,120 --> 05:31:37,280
changes to internal functionality again
7838
05:31:37,280 --> 05:31:39,400
if the package is main then it's
7839
05:31:39,400 --> 05:31:41,798
irrelevant because you're not building
7840
05:31:41,798 --> 05:31:42,878
uh a
7841
05:31:42,878 --> 05:31:44,798
library I want to talk about the
7842
05:31:44,798 --> 05:31:47,000
difference between concurrent or
7843
05:31:47,000 --> 05:31:50,000
parallel programming and synchronous or
7844
05:31:50,000 --> 05:31:52,200
sequential programming now it's worth
7845
05:31:52,200 --> 05:31:53,638
pointing out at this point that
7846
05:31:53,638 --> 05:31:56,000
concurrency and parallelism are
7847
05:31:56,000 --> 05:31:57,798
different and we'll talk about their
7848
05:31:57,798 --> 05:31:59,958
differences in a future course for for
7849
05:31:59,958 --> 05:32:02,000
now we're going to kind of treat them as
7850
05:32:02,000 --> 05:32:03,400
the same idea and I'll just kind of
7851
05:32:03,400 --> 05:32:06,080
refer to them as concurrency uh
7852
05:32:06,080 --> 05:32:08,440
similarly sequential Pro programming and
7853
05:32:08,440 --> 05:32:10,280
synchronous they're slightly different
7854
05:32:10,280 --> 05:32:12,120
terms but um I'm going to kind of bucket
7855
05:32:12,120 --> 05:32:14,240
them for the purpose of this discussion
7856
05:32:14,240 --> 05:32:16,878
we'll be really comparing uh concurrent
7857
05:32:16,878 --> 05:32:19,520
code to synchronous uh or sequential
7858
05:32:19,520 --> 05:32:21,240
code so let's start with the easy one
7859
05:32:21,240 --> 05:32:22,558
let's talk about synchronous or
7860
05:32:22,558 --> 05:32:25,520
sequential programming say we have some
7861
05:32:25,520 --> 05:32:30,040
code x colal 5
7862
05:32:30,040 --> 05:32:35,600
x++ and then maybe fmt do print.
7863
05:32:35,600 --> 05:32:38,680
print line
7864
05:32:38,680 --> 05:32:41,360
X the nice thing about this code and
7865
05:32:41,360 --> 05:32:43,600
what makes it synchronous or sequential
7866
05:32:43,600 --> 05:32:45,600
is that the code executes in order from
7867
05:32:45,600 --> 05:32:47,320
top to bottom right first we create a
7868
05:32:47,320 --> 05:32:49,718
variable named X set equal to 5 then we
7869
05:32:49,718 --> 05:32:52,440
increment it by one and then we print X
7870
05:32:52,440 --> 05:32:54,680
right everything's happening in order
7871
05:32:54,680 --> 05:32:57,638
from top to bottom one thing at a time
7872
05:32:57,638 --> 05:33:00,280
now this is usually what you want it's
7873
05:33:00,280 --> 05:33:02,120
simple it's easy to reason about it's
7874
05:33:02,120 --> 05:33:04,600
easy to write code this way the problem
7875
05:33:04,600 --> 05:33:07,000
is sometimes it's not the most efficient
7876
05:33:07,000 --> 05:33:09,840
way to write performance code or code
7877
05:33:09,840 --> 05:33:13,000
that can run as fast as possible on a
7878
05:33:13,000 --> 05:33:15,320
given set of Hardware so in order to
7879
05:33:15,320 --> 05:33:17,040
understand how we can maybe optimize
7880
05:33:17,040 --> 05:33:19,440
this we need to look into how your
7881
05:33:19,440 --> 05:33:20,920
computer's
7882
05:33:20,920 --> 05:33:25,240
CPU or Central Processing Unit
7883
05:33:25,240 --> 05:33:29,080
works so your CPU has a clock speed um
7884
05:33:29,080 --> 05:33:31,440
which basically like from a very high
7885
05:33:31,440 --> 05:33:33,958
level means how many instructions how
7886
05:33:33,958 --> 05:33:34,878
many
7887
05:33:34,878 --> 05:33:38,558
instructions it can do per let's say set
7888
05:33:38,558 --> 05:33:40,120
those aren't necessarily the units but
7889
05:33:40,120 --> 05:33:42,360
it is basically how many computations it
7890
05:33:42,360 --> 05:33:45,840
can do um per amount of time we just say
7891
05:33:45,840 --> 05:33:49,200
it seconds to keep things simple okay so
7892
05:33:49,200 --> 05:33:50,558
when we're analyzing this code over here
7893
05:33:50,558 --> 05:33:52,080
on the right basically what needs to
7894
05:33:52,080 --> 05:33:54,638
happen is first we set x equal to five
7895
05:33:54,638 --> 05:33:57,680
and that takes up one instruction right
7896
05:33:57,680 --> 05:33:59,480
after that we get to increment X by six
7897
05:33:59,480 --> 05:34:01,200
that'll take up another instruction and
7898
05:34:01,200 --> 05:34:04,558
then we get to print X so the speed at
7899
05:34:04,558 --> 05:34:07,000
which we can execute this little program
7900
05:34:07,000 --> 05:34:11,240
here is dependent on how fast the cpu's
7901
05:34:11,240 --> 05:34:13,718
clock speed is so if we want our program
7902
05:34:13,718 --> 05:34:15,440
to go faster we can basically do one of
7903
05:34:15,440 --> 05:34:17,798
two things either we can reduce the
7904
05:34:17,798 --> 05:34:20,760
number of instructions required uh for
7905
05:34:20,760 --> 05:34:24,280
our program to execute or we can get a
7906
05:34:24,280 --> 05:34:26,600
faster CPU one that can do more
7907
05:34:26,600 --> 05:34:29,160
instructions per second the problem is
7908
05:34:29,160 --> 05:34:32,360
getting a faster CPU sometimes is really
7909
05:34:32,360 --> 05:34:35,280
really expensive and so instead of
7910
05:34:35,280 --> 05:34:37,840
getting a faster CPU what we've kind
7911
05:34:37,840 --> 05:34:40,718
have done over the years is instead add
7912
05:34:40,718 --> 05:34:42,320
more
7913
05:34:42,320 --> 05:34:45,240
CPUs and in this case um we've kind of
7914
05:34:45,240 --> 05:34:47,798
broken the CPU up actually into what we
7915
05:34:47,798 --> 05:34:49,878
call different cores so you might
7916
05:34:49,878 --> 05:34:52,840
actually have a quad core processor Each
7917
05:34:52,840 --> 05:34:56,600
of which let's say does I don't know
7918
05:34:56,600 --> 05:35:00,638
5,000 instructions per Nan I'm totally
7919
05:35:00,638 --> 05:35:03,160
making these units up um but you get the
7920
05:35:03,160 --> 05:35:06,240
idea any one of these CPU cores can only
7921
05:35:06,240 --> 05:35:09,120
do 5,000 but the interest thing is they
7922
05:35:09,120 --> 05:35:13,120
can all do 5,000 per nond at the same
7923
05:35:13,120 --> 05:35:16,718
time so if we distribute our program
7924
05:35:16,718 --> 05:35:19,080
across all of the cores in theory we
7925
05:35:19,080 --> 05:35:20,638
should able to go uh we should be able
7926
05:35:20,638 --> 05:35:25,040
to go about four times as fast again if
7927
05:35:25,040 --> 05:35:27,280
we use all four cores instead of just
7928
05:35:27,280 --> 05:35:30,120
one the problem is that most code we
7929
05:35:30,120 --> 05:35:33,120
write can't take advantage of all four
7930
05:35:33,120 --> 05:35:34,878
cores for example let's look at this
7931
05:35:34,878 --> 05:35:37,280
code over here we set x equal to 5 and
7932
05:35:37,280 --> 05:35:38,878
then we increment it and then we print
7933
05:35:38,878 --> 05:35:42,600
it it has to happen in 1 2
7934
05:35:42,600 --> 05:35:46,760
3 right in order 1 2 3 we can't do all
7935
05:35:46,760 --> 05:35:48,558
of these instructions at the same time
7936
05:35:48,558 --> 05:35:52,000
if we did then x++ would have nothing to
7937
05:35:52,000 --> 05:35:53,360
increment because we never would have
7938
05:35:53,360 --> 05:35:55,958
set um an X variable equal to five in
7939
05:35:55,958 --> 05:35:58,718
the first place and print line X would
7940
05:35:58,718 --> 05:36:00,760
have nothing to print because X hasn't
7941
05:36:00,760 --> 05:36:04,280
been set yet so writing concurrent or
7942
05:36:04,280 --> 05:36:07,200
parallel code can drastically speed up
7943
05:36:07,200 --> 05:36:08,798
the performance of our programs because
7944
05:36:08,798 --> 05:36:11,200
we're able to distribute um kind of all
7945
05:36:11,200 --> 05:36:13,080
the instructions that we need to compute
7946
05:36:13,080 --> 05:36:15,558
across multiple cores the problem is we
7947
05:36:15,558 --> 05:36:17,558
do actually need to write our code in a
7948
05:36:17,558 --> 05:36:20,558
different way we need to expect that
7949
05:36:20,558 --> 05:36:22,360
some of the instructions are going to
7950
05:36:22,360 --> 05:36:24,638
happen at the same time and that's
7951
05:36:24,638 --> 05:36:26,520
what's going to speed up our program so
7952
05:36:26,520 --> 05:36:28,920
let's say we had a little bit more code
7953
05:36:28,920 --> 05:36:31,718
in our program here maybe we have X or
7954
05:36:31,718 --> 05:36:33,958
excuse me y colal
7955
05:36:33,958 --> 05:36:36,040
6 y
7956
05:36:36,040 --> 05:36:38,240
-- FM
7957
05:36:38,240 --> 05:36:39,840
t.
7958
05:36:39,840 --> 05:36:41,400
print
7959
05:36:41,400 --> 05:36:43,200
line
7960
05:36:43,200 --> 05:36:48,000
Y okay this code here in this block kind
7961
05:36:48,000 --> 05:36:49,718
of dependent on each other right we have
7962
05:36:49,718 --> 05:36:53,320
to do it in one two three order um and
7963
05:36:53,320 --> 05:36:55,958
the same goes for this block here but we
7964
05:36:55,958 --> 05:36:58,878
don't have to necessarily do this block
7965
05:36:58,878 --> 05:37:01,680
of code where we calculate and print X
7966
05:37:01,680 --> 05:37:03,760
before or after we calculate and print y
7967
05:37:03,760 --> 05:37:05,080
they're they're kind of separate in that
7968
05:37:05,080 --> 05:37:06,718
way so what we can actually do is take
7969
05:37:06,718 --> 05:37:08,840
this block of code code and execute it
7970
05:37:08,840 --> 05:37:11,440
in one core and at the same time execute
7971
05:37:11,440 --> 05:37:14,360
this other block of code in another core
7972
05:37:14,360 --> 05:37:16,360
doing them at the same time so let's
7973
05:37:16,360 --> 05:37:18,878
sort of visualize the runtime of this
7974
05:37:18,878 --> 05:37:21,558
program here if we run this code
7975
05:37:21,558 --> 05:37:23,840
synchronously or sequentially right not
7976
05:37:23,840 --> 05:37:25,920
taking advantage of two CPU cores but
7977
05:37:25,920 --> 05:37:27,760
instead of doing it all in one core then
7978
05:37:27,760 --> 05:37:29,400
our running time might look something
7979
05:37:29,400 --> 05:37:34,160
like this I don't know let's just say 6
7980
05:37:34,160 --> 05:37:37,638
nond but instead if we run it across two
7981
05:37:37,638 --> 05:37:40,160
cores in
7982
05:37:40,160 --> 05:37:45,200
parallel each core executes at the same
7983
05:37:45,200 --> 05:37:47,680
time and they'll each take approximately
7984
05:37:47,680 --> 05:37:50,400
let's say three
7985
05:37:50,400 --> 05:37:53,240
nond so we're done in half the time
7986
05:37:53,240 --> 05:37:55,040
again because we took advantage of the
7987
05:37:55,040 --> 05:37:57,760
hardware that was available to us so to
7988
05:37:57,760 --> 05:38:01,280
wrap up writing concurrent code in many
7989
05:38:01,280 --> 05:38:05,360
cases can drastically reduce of how long
7990
05:38:05,360 --> 05:38:07,558
it takes to run our programs and it
7991
05:38:07,558 --> 05:38:09,200
depends just a little bit on kind of
7992
05:38:09,200 --> 05:38:11,320
fundamentally what we're trying to do so
7993
05:38:11,320 --> 05:38:13,120
in this case we literally could take a
7994
05:38:13,120 --> 05:38:16,600
program and chop its runtime in half by
7995
05:38:16,600 --> 05:38:19,400
utilizing a little bit more Hardware so
7996
05:38:19,400 --> 05:38:20,958
this chapter is going to be all about
7997
05:38:20,958 --> 05:38:23,160
concurrency in the go programm language
7998
05:38:23,160 --> 05:38:26,280
and the great thing about go is how easy
7999
05:38:26,280 --> 05:38:29,160
it makes it to write concurrent code so
8000
05:38:29,160 --> 05:38:30,878
the question is how do we write
8001
05:38:30,878 --> 05:38:33,718
concurrent code and go what's the syntax
8002
05:38:33,718 --> 05:38:36,240
well there's actually a really awesome
8003
05:38:36,240 --> 05:38:38,360
builtin keyword word to the go program
8004
05:38:38,360 --> 05:38:42,400
language the go keyword and it spawns a
8005
05:38:42,400 --> 05:38:45,360
new go routine when you use it now a go
8006
05:38:45,360 --> 05:38:48,160
routine is kind of unique to the go
8007
05:38:48,160 --> 05:38:50,120
programming language but at a high level
8008
05:38:50,120 --> 05:38:51,920
you can just think of it as a separate
8009
05:38:51,920 --> 05:38:54,240
thread of execution we're essentially
8010
05:38:54,240 --> 05:38:56,760
telling the go programming language hey
8011
05:38:56,760 --> 05:38:59,000
all this stuff in this function right
8012
05:38:59,000 --> 05:39:01,440
that I'm calling with the go keyword can
8013
05:39:01,440 --> 05:39:03,760
happen in parallel right we can go
8014
05:39:03,760 --> 05:39:06,878
execute that on another core of the CPU
8015
05:39:06,878 --> 05:39:09,680
if we need to so whenever we use the go
8016
05:39:09,680 --> 05:39:12,840
keyword execution kind of immediately
8017
05:39:12,840 --> 05:39:15,520
jumps to the next step after the
8018
05:39:15,520 --> 05:39:18,558
function call right so this do something
8019
05:39:18,558 --> 05:39:21,878
function will kind of go be executed in
8020
05:39:21,878 --> 05:39:24,240
parallel right and then execution
8021
05:39:24,240 --> 05:39:26,638
continues in the current function um
8022
05:39:26,638 --> 05:39:28,520
kind of just on the next line and then
8023
05:39:28,520 --> 05:39:30,360
as a last note before we jump into some
8024
05:39:30,360 --> 05:39:32,600
code to see how this really works when
8025
05:39:32,600 --> 05:39:35,280
we use the go keyword we're not able to
8026
05:39:35,280 --> 05:39:38,000
capture any return values from this
8027
05:39:38,000 --> 05:39:39,840
function call which makes sense right
8028
05:39:39,840 --> 05:39:42,200
because we're kind of moving on we can't
8029
05:39:42,200 --> 05:39:44,638
wait for the function to finish and
8030
05:39:44,638 --> 05:39:46,280
return some stuff that's the whole point
8031
05:39:46,280 --> 05:39:48,320
we want the function to go kind of do
8032
05:39:48,320 --> 05:39:51,200
its thing on another thread so let's try
8033
05:39:51,200 --> 05:39:53,478
this out in an assignment says emo we
8034
05:39:53,478 --> 05:39:55,920
send a lot of network requests right
8035
05:39:55,920 --> 05:39:58,638
requests over the Internet each email we
8036
05:39:58,638 --> 05:39:59,958
send must go out over the internet to
8037
05:39:59,958 --> 05:40:01,638
serve our millions of customers we need
8038
05:40:01,638 --> 05:40:03,320
to we need a single go program to be
8039
05:40:03,320 --> 05:40:05,120
capable of sending thousands of emails
8040
05:40:05,120 --> 05:40:06,718
at once right so we need to be able to
8041
05:40:06,718 --> 05:40:08,080
do lots of things things at once this is
8042
05:40:08,080 --> 05:40:11,478
what go routines allow us to do edit the
8043
05:40:11,478 --> 05:40:13,400
send email function to execute its
8044
05:40:13,400 --> 05:40:15,400
Anonymous function concurrently so that
8045
05:40:15,400 --> 05:40:18,120
the received message prints after the
8046
05:40:18,120 --> 05:40:20,080
sent message so let's go ahead and run
8047
05:40:20,080 --> 05:40:23,360
the code in its current
8048
05:40:25,798 --> 05:40:29,280
state and we get email received hello
8049
05:40:29,280 --> 05:40:31,638
there Stacy email sent hello there Stacy
8050
05:40:31,638 --> 05:40:34,160
right so it looks out of order now
8051
05:40:34,160 --> 05:40:36,440
here's our send email function it takes
8052
05:40:36,440 --> 05:40:41,520
a message um as a string parameter and
8053
05:40:41,520 --> 05:40:43,160
the interesting thing is it calls this
8054
05:40:43,160 --> 05:40:44,920
Anonymous function here right so it's
8055
05:40:44,920 --> 05:40:46,320
defining this function and then
8056
05:40:46,320 --> 05:40:48,798
immediately calling it um where it's
8057
05:40:48,798 --> 05:40:51,520
going to wait for 250 milliseconds and
8058
05:40:51,520 --> 05:40:54,878
then print email received and then this
8059
05:40:54,878 --> 05:40:57,400
function will exit and it will print
8060
05:40:57,400 --> 05:40:58,920
email sent right and then print the
8061
05:40:58,920 --> 05:41:00,558
message so again that's why this is out
8062
05:41:00,558 --> 05:41:02,320
of order right we're we're executing
8063
05:41:02,320 --> 05:41:04,400
this function first and then we're
8064
05:41:04,400 --> 05:41:07,558
moving on to the next line so the way we
8065
05:41:07,558 --> 05:41:10,400
fix this is by using the go
8066
05:41:10,400 --> 05:41:13,840
keyword to execute this bit of code at
8067
05:41:13,840 --> 05:41:17,160
the same time is this bit of code right
8068
05:41:17,160 --> 05:41:18,638
the go keyword will immediately move
8069
05:41:18,638 --> 05:41:21,320
down to line 13 on the main thread or
8070
05:41:21,320 --> 05:41:24,000
the main go routine and spawn a new go
8071
05:41:24,000 --> 05:41:25,840
routine to kind of do this in the
8072
05:41:25,840 --> 05:41:29,120
background and because of this waiting
8073
05:41:29,120 --> 05:41:32,400
time the email received message should
8074
05:41:32,400 --> 05:41:35,440
happen afterwards so let's go ahead and
8075
05:41:35,440 --> 05:41:39,040
run this again
8076
05:41:40,400 --> 05:41:42,280
sent received sent received looks good
8077
05:41:42,280 --> 05:41:45,478
to me so you may have been thinking to
8078
05:41:45,478 --> 05:41:47,760
yourself well how useful is it to call a
8079
05:41:47,760 --> 05:41:49,760
function in a go routine if I can't even
8080
05:41:49,760 --> 05:41:52,958
get the return values the answer in go
8081
05:41:52,958 --> 05:41:55,840
is that we use channels typically to
8082
05:41:55,840 --> 05:41:58,520
kind of resynchronize our code so
8083
05:41:58,520 --> 05:42:01,558
typically we'll use go routines or the
8084
05:42:01,558 --> 05:42:04,160
go keyword plus some function to go do a
8085
05:42:04,160 --> 05:42:05,958
bunch of computation all at the same
8086
05:42:05,958 --> 05:42:07,680
time and then we can kind of
8087
05:42:07,680 --> 05:42:09,760
resynchronize either in the main go
8088
05:42:09,760 --> 05:42:12,120
routine or in some other go routine by
8089
05:42:12,120 --> 05:42:14,440
passing data back and forth between go
8090
05:42:14,440 --> 05:42:17,958
routines using channels a channel is
8091
05:42:17,958 --> 05:42:20,760
really just a thread safe or go routine
8092
05:42:20,760 --> 05:42:25,000
safe cue we can put stuff in one end and
8093
05:42:25,000 --> 05:42:26,958
read it out the other end in the same
8094
05:42:26,958 --> 05:42:29,600
order so we'll typically have one or
8095
05:42:29,600 --> 05:42:32,200
more go routines kind of sending data
8096
05:42:32,200 --> 05:42:33,958
into the channel maybe they finished a
8097
05:42:33,958 --> 05:42:35,840
calculation they're returning their
8098
05:42:35,840 --> 05:42:37,520
results over the channel and then we'll
8099
05:42:37,520 --> 05:42:39,920
have one or more go routines on the
8100
05:42:39,920 --> 05:42:42,240
other end reading that data off of the
8101
05:42:42,240 --> 05:42:44,120
channel and processing it in some way
8102
05:42:44,120 --> 05:42:46,280
maybe sending a report maybe printing it
8103
05:42:46,280 --> 05:42:49,200
to the console so this is the Syntax for
8104
05:42:49,200 --> 05:42:51,478
making a channel and channels are typed
8105
05:42:51,478 --> 05:42:53,920
so we can say this is a channel of
8106
05:42:53,920 --> 05:42:56,520
integers and then we can send data into
8107
05:42:56,520 --> 05:42:58,958
the channel using this Arrow operator
8108
05:42:58,958 --> 05:43:00,558
it's it's really pretty intuitive we're
8109
05:43:00,558 --> 05:43:04,080
saying 69 is being sent into the channel
8110
05:43:04,080 --> 05:43:06,320
and then it's actually the same operator
8111
05:43:06,320 --> 05:43:08,478
to read a a value out of a channel we
8112
05:43:08,478 --> 05:43:10,320
just move it over to the other side
8113
05:43:10,320 --> 05:43:12,080
again super intuitive we're reading a
8114
05:43:12,080 --> 05:43:14,878
value out of the channel and saving it
8115
05:43:14,878 --> 05:43:17,680
into the variable V in this example now
8116
05:43:17,680 --> 05:43:19,478
it's important to understand that both
8117
05:43:19,478 --> 05:43:21,878
of these operations sending and
8118
05:43:21,878 --> 05:43:23,760
receiving on a channel are blocking
8119
05:43:23,760 --> 05:43:27,280
operations so if I'm trying to send a
8120
05:43:27,280 --> 05:43:30,040
value into a channel and there's no
8121
05:43:30,040 --> 05:43:31,840
other go routine on the other side that
8122
05:43:31,840 --> 05:43:33,920
will be able to read it out then my code
8123
05:43:33,920 --> 05:43:37,200
will actually stop and wait on this go
8124
05:43:37,200 --> 05:43:39,798
routine until there is a reader ready
8125
05:43:39,798 --> 05:43:42,160
and the same goes for reading when a go
8126
05:43:42,160 --> 05:43:44,760
routine gets to this section of code if
8127
05:43:44,760 --> 05:43:47,280
there's nothing being sent into the
8128
05:43:47,280 --> 05:43:49,878
channel on another go routine then this
8129
05:43:49,878 --> 05:43:52,080
code will just sit and wait until
8130
05:43:52,080 --> 05:43:54,360
something is sent so let's move on to
8131
05:43:54,360 --> 05:43:56,558
the assignment says run the program
8132
05:43:56,558 --> 05:43:58,680
you'll see that it Deadlocks and never
8133
05:43:58,680 --> 05:44:00,840
exits so a deadlock is basically when
8134
05:44:00,840 --> 05:44:03,040
all the go routines in a program are
8135
05:44:03,040 --> 05:44:05,040
blocking and there's nothing for them to
8136
05:44:05,040 --> 05:44:07,120
do it means there's a bug in the code so
8137
05:44:07,120 --> 05:44:09,000
let's run the code just to see what that
8138
05:44:09,000 --> 05:44:11,958
feels like although I think it's just
8139
05:44:11,958 --> 05:44:13,360
going to feel like it's running the code
8140
05:44:13,360 --> 05:44:15,000
for a long time so I'm going to go and
8141
05:44:15,000 --> 05:44:16,718
cancel
8142
05:44:16,718 --> 05:44:19,400
that the filter old emails function is
8143
05:44:19,400 --> 05:44:20,958
trying to send on a channel and there's
8144
05:44:20,958 --> 05:44:22,400
no other go routin running that can
8145
05:44:22,400 --> 05:44:23,840
accept the value from the channel okay
8146
05:44:23,840 --> 05:44:25,878
so let's take a look filter old emails
8147
05:44:25,878 --> 05:44:29,440
takes some emails as an input creates an
8148
05:44:29,440 --> 05:44:31,280
is old Channel and that looks like it
8149
05:44:31,280 --> 05:44:33,558
Loops over the emails and if they are
8150
05:44:33,558 --> 05:44:35,798
before a certain date it's going to pass
8151
05:44:35,798 --> 05:44:37,638
the Boolean true into the channel
8152
05:44:37,638 --> 05:44:39,280
otherwise it's going to pass in false
8153
05:44:39,280 --> 05:44:42,558
and then once that Loop exits it's going
8154
05:44:42,558 --> 05:44:46,478
to read out of the channel here and
8155
05:44:46,478 --> 05:44:48,600
print to the console you know whether or
8156
05:44:48,600 --> 05:44:52,760
not the emails uh were old Okay
8157
05:44:52,760 --> 05:44:55,000
cool so this makes sense this makes
8158
05:44:55,000 --> 05:44:56,920
sense why this is blocking right this
8159
05:44:56,920 --> 05:44:59,160
first send either here or here which
8160
05:44:59,160 --> 05:45:01,878
everyone happens first is going to block
8161
05:45:01,878 --> 05:45:03,160
because the
8162
05:45:03,160 --> 05:45:05,920
reader like that code hasn't happened
8163
05:45:05,920 --> 05:45:08,120
yet this is the same this is the same go
8164
05:45:08,120 --> 05:45:10,840
routine right this is not happening at
8165
05:45:10,840 --> 05:45:12,680
the same time as this is happening so
8166
05:45:12,680 --> 05:45:14,680
we'll use a go routine to fix it fix the
8167
05:45:14,680 --> 05:45:16,000
deadlock by spawning an anonymous go
8168
05:45:16,000 --> 05:45:18,718
routine to write to the is old Channel
8169
05:45:18,718 --> 05:45:20,000
instead of using the same go routine
8170
05:45:20,000 --> 05:45:21,638
that's reading from it okay cool so we
8171
05:45:21,638 --> 05:45:24,120
need to run this Loop essentially in a
8172
05:45:24,120 --> 05:45:29,000
new go routine so we'll do go Funk and
8173
05:45:29,000 --> 05:45:30,320
we'll just use an anonymous function
8174
05:45:30,320 --> 05:45:31,920
here because we don't really care about
8175
05:45:31,920 --> 05:45:33,558
naming
8176
05:45:33,558 --> 05:45:36,080
it and we'll just run that entire block
8177
05:45:36,080 --> 05:45:37,520
of code
8178
05:45:37,520 --> 05:45:40,040
in a new Anonymous function so now this
8179
05:45:40,040 --> 05:45:42,638
and this will happen at the same time
8180
05:45:42,638 --> 05:45:45,360
let's go ahead and run
8181
05:45:47,360 --> 05:45:50,040
that cool and this looks like what I
8182
05:45:50,040 --> 05:45:51,478
would expect I'll go ahead and submit
8183
05:45:51,478 --> 05:45:55,160
that so there's this concept of a token
8184
05:45:55,160 --> 05:45:57,120
when we're talking about concurrent
8185
05:45:57,120 --> 05:46:00,638
programs a a token is basically a unary
8186
05:46:00,638 --> 05:46:02,440
value right so not not binary there's
8187
05:46:02,440 --> 05:46:04,478
not two possible values true and false
8188
05:46:04,478 --> 05:46:06,718
unary there's just one possible value
8189
05:46:06,718 --> 05:46:08,680
and when there's just one possible value
8190
05:46:08,680 --> 05:46:11,240
we really don't care much about that
8191
05:46:11,240 --> 05:46:13,600
value it's not interesting in any way
8192
05:46:13,600 --> 05:46:15,798
right so it's not that we care what is
8193
05:46:15,798 --> 05:46:17,600
passed when we're working with tokens
8194
05:46:17,600 --> 05:46:20,520
it's that we care when and if something
8195
05:46:20,520 --> 05:46:23,440
is passed through a Channel at all so
8196
05:46:23,440 --> 05:46:26,280
for example this code here is reading a
8197
05:46:26,280 --> 05:46:29,400
value out of this Channel and it's just
8198
05:46:29,400 --> 05:46:31,360
discarding whatever it reads out it
8199
05:46:31,360 --> 05:46:33,478
doesn't even care what it is it's just
8200
05:46:33,478 --> 05:46:36,958
waiting to see uh kind of when something
8201
05:46:36,958 --> 05:46:38,958
thing comes through the channel so let's
8202
05:46:38,958 --> 05:46:41,080
move on to the assignment um and kind of
8203
05:46:41,080 --> 05:46:43,160
put that into practice it says our maleo
8204
05:46:43,160 --> 05:46:44,958
server isn't able to boot up until it
8205
05:46:44,958 --> 05:46:46,240
receives the signal that all of its
8206
05:46:46,240 --> 05:46:48,478
databases are online and it learns about
8207
05:46:48,478 --> 05:46:50,600
them being online by waiting for tokens
8208
05:46:50,600 --> 05:46:52,760
which are just empty structs um on a
8209
05:46:52,760 --> 05:46:55,080
channel complete the wait for DBS
8210
05:46:55,080 --> 05:46:56,798
function it should block until it
8211
05:46:56,798 --> 05:47:00,680
receives numb DBS so this integer here
8212
05:47:00,680 --> 05:47:04,638
um tokens on the DB Chan channel right
8213
05:47:04,638 --> 05:47:06,478
so this is a channel of empty structs
8214
05:47:06,478 --> 05:47:08,360
and again empty structs are tokens
8215
05:47:08,360 --> 05:47:10,240
they're unary values um they're not
8216
05:47:10,240 --> 05:47:12,600
interesting they don't have any Fields
8217
05:47:12,600 --> 05:47:14,280
each time it reads a token the get
8218
05:47:14,280 --> 05:47:16,200
databases Channel go routine will print
8219
05:47:16,200 --> 05:47:18,478
a message to the console for you okay so
8220
05:47:18,478 --> 05:47:20,360
I'm guessing that's down here yeah it
8221
05:47:20,360 --> 05:47:22,878
looks like it's going to watch um and
8222
05:47:22,878 --> 05:47:26,478
and print here okay so let's get started
8223
05:47:26,478 --> 05:47:27,958
and write some
8224
05:47:27,958 --> 05:47:30,040
code it should block until it receives
8225
05:47:30,040 --> 05:47:32,798
numb DB's tokens so it's a variable
8226
05:47:32,798 --> 05:47:35,120
amount of tokens so I guess the easiest
8227
05:47:35,120 --> 05:47:36,558
way to do this would be for with a loop
8228
05:47:36,558 --> 05:47:39,718
so 4 I col equals
8229
05:47:39,718 --> 05:47:44,520
0 I is less than num
8230
05:47:44,520 --> 05:47:46,798
DBS I
8231
05:47:46,798 --> 05:47:49,120
++ and then in here we're just going to
8232
05:47:49,120 --> 05:47:52,320
wait for a token to come across the DB
8233
05:47:52,320 --> 05:47:54,478
channel right so it'll block once and
8234
05:47:54,478 --> 05:47:55,798
then it'll move on to the next iteration
8235
05:47:55,798 --> 05:47:58,478
of the loop block again move on until
8236
05:47:58,478 --> 05:48:01,878
we've waited for you know numb DB's
8237
05:48:01,878 --> 05:48:04,440
tokens um and then block until it
8238
05:48:04,440 --> 05:48:05,680
receives the tokens each time it reads a
8239
05:48:05,680 --> 05:48:08,200
token that's it looks like we don't have
8240
05:48:08,200 --> 05:48:12,478
to return anything so let's run
8241
05:48:13,240 --> 05:48:15,878
that database one is online two is
8242
05:48:15,878 --> 05:48:18,558
online this looks good to me so now
8243
05:48:18,558 --> 05:48:21,040
let's talk about buffered channels so
8244
05:48:21,040 --> 05:48:22,400
the channels we've been using up until
8245
05:48:22,400 --> 05:48:23,958
this point haven't really stored
8246
05:48:23,958 --> 05:48:26,040
anything in them right we needed a
8247
05:48:26,040 --> 05:48:28,440
sender and a receiver at the same time
8248
05:48:28,440 --> 05:48:30,680
as soon as the sender sends the receiver
8249
05:48:30,680 --> 05:48:32,400
receives there's nothing kind of stored
8250
05:48:32,400 --> 05:48:35,280
in the channel at any given time but
8251
05:48:35,280 --> 05:48:38,120
that is exactly what a buffered channel
8252
05:48:38,120 --> 05:48:40,120
is so we have a buffer of some length
8253
05:48:40,120 --> 05:48:42,760
let's say five different items and
8254
05:48:42,760 --> 05:48:44,878
senders can actually send into the
8255
05:48:44,878 --> 05:48:48,200
channel even when there's no receivers
8256
05:48:48,200 --> 05:48:51,000
until the buffer fills up so a sender
8257
05:48:51,000 --> 05:48:52,840
could send five things into the channel
8258
05:48:52,840 --> 05:48:54,638
and then the buffer is full the channel
8259
05:48:54,638 --> 05:48:57,638
is full right and when a receiver
8260
05:48:57,638 --> 05:48:59,920
finally goes to read and pop items off
8261
05:48:59,920 --> 05:49:01,958
of the other end it will read and pop
8262
05:49:01,958 --> 05:49:04,760
them off in order one by one until the
8263
05:49:04,760 --> 05:49:07,240
channel is empty so this this is the
8264
05:49:07,240 --> 05:49:09,360
syntax we'd use if we want to make a
8265
05:49:09,360 --> 05:49:11,680
Channel of integers with a buffer size
8266
05:49:11,680 --> 05:49:14,440
of 100 we just use that optional second
8267
05:49:14,440 --> 05:49:16,478
parameter um to the built-in make
8268
05:49:16,478 --> 05:49:18,080
function so let's move on to the
8269
05:49:18,080 --> 05:49:19,760
assignment it says we want to be able to
8270
05:49:19,760 --> 05:49:22,920
send emails in batches a writing go
8271
05:49:22,920 --> 05:49:24,520
routine we'll take an entire batch of
8272
05:49:24,520 --> 05:49:26,478
email messages to a buffer channel uh
8273
05:49:26,478 --> 05:49:28,320
we'll write an entire batch of email
8274
05:49:28,320 --> 05:49:30,040
messages to a buffer Channel and later
8275
05:49:30,040 --> 05:49:32,240
once the channel is full a reading go
8276
05:49:32,240 --> 05:49:33,920
routine will go read all of those
8277
05:49:33,920 --> 05:49:35,798
messages so we can actually go find
8278
05:49:35,798 --> 05:49:39,600
where that's happening here in the test
8279
05:49:39,798 --> 05:49:43,638
Suite okay here so send emails um oh
8280
05:49:43,638 --> 05:49:44,920
nope this is where they're getting read
8281
05:49:44,920 --> 05:49:48,360
I'm sorry ah I'm silly the function that
8282
05:49:48,360 --> 05:49:50,878
we'll be working on is what's writing
8283
05:49:50,878 --> 05:49:53,840
into the channel so emails to send is
8284
05:49:53,840 --> 05:49:55,600
the channel um we're supposed to write
8285
05:49:55,600 --> 05:49:57,440
an entire batch of emails into the
8286
05:49:57,440 --> 05:49:59,520
channel and then theoretically sometime
8287
05:49:59,520 --> 05:50:01,040
in the
8288
05:50:01,040 --> 05:50:04,638
future those emails will be read out of
8289
05:50:04,638 --> 05:50:07,600
the channel and actually sent off
8290
05:50:07,600 --> 05:50:10,240
Okay cool so what happens if I run the
8291
05:50:10,240 --> 05:50:12,478
code in its current
8292
05:50:12,478 --> 05:50:14,958
state I'm kind of imagining that it's
8293
05:50:14,958 --> 05:50:17,360
going to block
8294
05:50:17,360 --> 05:50:20,680
forever yeah that's never going to exit
8295
05:50:20,680 --> 05:50:24,400
so at emails toq is getting called here
8296
05:50:24,400 --> 05:50:27,240
and send emails is getting called here
8297
05:50:27,240 --> 05:50:29,240
and notice that they're getting called
8298
05:50:29,240 --> 05:50:31,280
on the same they're both running in the
8299
05:50:31,280 --> 05:50:34,718
same go routine Right add emails to Q is
8300
05:50:34,718 --> 05:50:36,360
there's no go keyword anywhere that I
8301
05:50:36,360 --> 05:50:39,360
see so that's why we are blocking here
8302
05:50:39,360 --> 05:50:42,638
there's no reader on the other end right
8303
05:50:42,638 --> 05:50:45,120
but because we want to do this batching
8304
05:50:45,120 --> 05:50:47,400
we actually should be able to do it all
8305
05:50:47,400 --> 05:50:49,920
on the same thread we just need a big
8306
05:50:49,920 --> 05:50:52,798
enough batch size so we need a
8307
05:50:52,798 --> 05:50:55,798
buffer if we buffer this emails to send
8308
05:50:55,798 --> 05:51:00,760
Channel with the length of the emails
8309
05:51:00,760 --> 05:51:03,320
slice then we should have enough room to
8310
05:51:03,320 --> 05:51:04,920
push all of the emails into the buffer
8311
05:51:04,920 --> 05:51:08,558
Channel let's go ahead and try that
8312
05:51:09,240 --> 05:51:12,600
cool that looks like it is working
8313
05:51:12,600 --> 05:51:15,360
channels in go can actually be closed
8314
05:51:15,360 --> 05:51:17,760
and there's really only one reason you'd
8315
05:51:17,760 --> 05:51:19,760
want to close a go Channel and it's to
8316
05:51:19,760 --> 05:51:22,080
indicate that you're done with it a
8317
05:51:22,080 --> 05:51:24,120
channel should always be closed from the
8318
05:51:24,120 --> 05:51:26,600
sending side so the sending go routine
8319
05:51:26,600 --> 05:51:28,040
the one that's pushing values into the
8320
05:51:28,040 --> 05:51:29,638
channel will be the one to close the
8321
05:51:29,638 --> 05:51:31,360
channel and that will indicate to any
8322
05:51:31,360 --> 05:51:33,040
readers of the channel That this channel
8323
05:51:33,040 --> 05:51:35,160
is closed there's nothing else to read
8324
05:51:35,160 --> 05:51:38,240
from it and the actual syntax is really
8325
05:51:38,240 --> 05:51:40,400
simple it's just the built-in close
8326
05:51:40,400 --> 05:51:42,440
function where we pass in the channel
8327
05:51:42,440 --> 05:51:44,558
itself now on the reading side we can
8328
05:51:44,558 --> 05:51:48,400
actually check if a channel is closed
8329
05:51:48,400 --> 05:51:50,840
using this kind of optional second
8330
05:51:50,840 --> 05:51:52,920
variable um that comes back when reading
8331
05:51:52,920 --> 05:51:54,680
a channel this okay variable it's a
8332
05:51:54,680 --> 05:51:57,040
Boolean uh if the Boolean is true the
8333
05:51:57,040 --> 05:51:58,958
channel is open if it is false the
8334
05:51:58,958 --> 05:52:01,840
channel is closed if the channel happens
8335
05:52:01,840 --> 05:52:05,000
to be buffered then okay will remain
8336
05:52:05,000 --> 05:52:07,920
true until the channel is emptied out so
8337
05:52:07,920 --> 05:52:10,440
okay will only be false once the buffer
8338
05:52:10,440 --> 05:52:13,878
channel is empty and closed the last
8339
05:52:13,878 --> 05:52:15,240
thing I'll mention before we jump into
8340
05:52:15,240 --> 05:52:17,200
the assignment is that you never want to
8341
05:52:17,200 --> 05:52:20,200
send a value across a closed Channel if
8342
05:52:20,200 --> 05:52:23,160
you do that go routine will panic and
8343
05:52:23,160 --> 05:52:24,558
that's why it's really important that
8344
05:52:24,558 --> 05:52:26,798
you only ever close a channel from the
8345
05:52:26,798 --> 05:52:29,558
sending side because that go routine is
8346
05:52:29,558 --> 05:52:31,360
going to be the one that knows when it's
8347
05:52:31,360 --> 05:52:34,040
done sending values okay on to the
8348
05:52:34,040 --> 05:52:36,520
assignment it says Amo we're all about
8349
05:52:36,520 --> 05:52:38,600
tring what our systems are up to with
8350
05:52:38,600 --> 05:52:40,958
great logging and Telemetry the send
8351
05:52:40,958 --> 05:52:42,440
reports function sends out a batch of
8352
05:52:42,440 --> 05:52:44,240
reports to our clients and reports back
8353
05:52:44,240 --> 05:52:46,240
how many were sent across a channel it
8354
05:52:46,240 --> 05:52:48,638
closes the channel when it's done okay
8355
05:52:48,638 --> 05:52:52,958
so the send reports function here sends
8356
05:52:52,958 --> 05:52:54,680
the reports or sends the number of
8357
05:52:54,680 --> 05:52:56,040
reports across the channel and closes
8358
05:52:56,040 --> 05:52:57,240
the channel
8359
05:52:57,240 --> 05:53:00,240
great complete the count reports
8360
05:53:00,240 --> 05:53:02,478
function it should use an infinite for
8361
05:53:02,478 --> 05:53:04,558
Loop to read from the channel if the
8362
05:53:04,558 --> 05:53:06,920
channel is closed break out of the loop
8363
05:53:06,920 --> 05:53:08,440
otherwise keep a running total of the
8364
05:53:08,440 --> 05:53:10,320
number of reports sent and return the
8365
05:53:10,320 --> 05:53:13,958
total number of responses Okay cool so
8366
05:53:13,958 --> 05:53:16,840
first things first we need to keep track
8367
05:53:16,840 --> 05:53:21,280
of a total so let's start it at
8368
05:53:21,280 --> 05:53:23,440
zero and we know that at the end of the
8369
05:53:23,440 --> 05:53:24,680
function we'll be
8370
05:53:24,680 --> 05:53:26,520
returning the
8371
05:53:26,520 --> 05:53:28,040
total
8372
05:53:28,040 --> 05:53:30,400
right then it says use an infinite for
8373
05:53:30,400 --> 05:53:33,280
Loop to read from the channel okay so
8374
05:53:33,280 --> 05:53:36,440
four um and then we need to read from
8375
05:53:36,440 --> 05:53:41,400
from the channel so we'll do um nums
8376
05:53:41,400 --> 05:53:45,760
Cent and read from the nums Cent
8377
05:53:46,878 --> 05:53:48,958
Channel okay if the channels closed
8378
05:53:48,958 --> 05:53:50,280
break out of the loop ah right so we
8379
05:53:50,280 --> 05:53:52,400
need to use that syntax to check if the
8380
05:53:52,400 --> 05:53:55,120
channel is closed so if not okay if the
8381
05:53:55,120 --> 05:53:57,760
channel is closed then we'll
8382
05:53:57,760 --> 05:54:00,160
return
8383
05:54:00,160 --> 05:54:02,320
total or I suppose we're returning down
8384
05:54:02,320 --> 05:54:03,840
here so we could just break let's just
8385
05:54:03,840 --> 05:54:07,160
do that instead break
8386
05:54:07,160 --> 05:54:10,320
otherwise uh we do total plus equals
8387
05:54:10,320 --> 05:54:12,440
nums Cent and it's important to
8388
05:54:12,440 --> 05:54:14,958
understand that as soon as okay is false
8389
05:54:14,958 --> 05:54:16,638
num scent will just be a zero value so
8390
05:54:16,638 --> 05:54:18,160
it's not a valid value that was sent
8391
05:54:18,160 --> 05:54:20,638
across the channel so it's safe to just
8392
05:54:20,638 --> 05:54:23,240
just break like that okay cool this is
8393
05:54:23,240 --> 05:54:25,600
looking correct to me let's go ahead and
8394
05:54:25,600 --> 05:54:28,360
run
8395
05:54:30,878 --> 05:54:34,920
that let's see batch of 15 38 and 61
8396
05:54:34,920 --> 05:54:38,080
Cent do those add up to 114 uh looks
8397
05:54:38,080 --> 05:54:42,200
like they might uh like my terrible in
8398
05:54:42,200 --> 05:54:44,638
in my head arithmetic says that that's
8399
05:54:44,638 --> 05:54:45,798
perfect so I'm going to go ahead and
8400
05:54:45,798 --> 05:54:48,440
submit it the range keyword works with
8401
05:54:48,440 --> 05:54:51,680
channels as well as slices and Maps so
8402
05:54:51,680 --> 05:54:53,558
we can actually range over the channel
8403
05:54:53,558 --> 05:54:56,680
and it will block until a value is ready
8404
05:54:56,680 --> 05:54:59,240
it will read it into in this case the
8405
05:54:59,240 --> 05:55:01,958
variable item and then execute the body
8406
05:55:01,958 --> 05:55:03,400
and it will do that over and over and
8407
05:55:03,400 --> 05:55:05,520
over for each new value coming across
8408
05:55:05,520 --> 05:55:08,520
the channel um and we'll only exit the
8409
05:55:08,520 --> 05:55:11,120
loop once the channel is closed so onto
8410
05:55:11,120 --> 05:55:12,718
the assignment it says it's that time
8411
05:55:12,718 --> 05:55:14,520
again maleo is hiring and we've been
8412
05:55:14,520 --> 05:55:17,160
assigned to do the interviews for some
8413
05:55:17,160 --> 05:55:19,440
reason the Fibonacci sequence is melo's
8414
05:55:19,440 --> 05:55:21,440
interview problem of choice we've been
8415
05:55:21,440 --> 05:55:23,040
tasked with building a small toy program
8416
05:55:23,040 --> 05:55:25,478
that we can use in the interview okay so
8417
05:55:25,478 --> 05:55:28,000
complete the concurrent Fibonacci
8418
05:55:28,000 --> 05:55:29,638
function if you're not familiar with the
8419
05:55:29,638 --> 05:55:31,680
Fibonacci sequence um I don't want to go
8420
05:55:31,680 --> 05:55:33,958
like too crazy far into it but it's
8421
05:55:33,958 --> 05:55:37,040
basically this sequence of numbers here
8422
05:55:37,040 --> 05:55:41,200
where each number is the sum of the two
8423
05:55:41,200 --> 05:55:44,320
preceding numbers so 1 and 2 equal 3 2
8424
05:55:44,320 --> 05:55:46,280
and three equal 5 in fact you probably
8425
05:55:46,280 --> 05:55:48,200
can't even see that let me Zoom this in
8426
05:55:48,200 --> 05:55:51,240
a little bit so 1 and one or 1 and two
8427
05:55:51,240 --> 05:55:55,840
equal 3 2 and 3 equal 5 3 and 5 equal 8
8428
05:55:55,840 --> 05:55:57,280
right so it's just this kind of set
8429
05:55:57,280 --> 05:55:59,478
sequence of
8430
05:55:59,478 --> 05:56:01,958
numbers okay complete the concurrent FIB
8431
05:56:01,958 --> 05:56:03,320
function it should create a new channel
8432
05:56:03,320 --> 05:56:05,878
of ins so let's go ahead and do that so
8433
05:56:05,878 --> 05:56:06,798
Channel
8434
05:56:06,798 --> 05:56:12,280
ins make channel of ins great call
8435
05:56:12,280 --> 05:56:15,160
Fibonacci in a go routine passing to it
8436
05:56:15,160 --> 05:56:17,878
the channel and the number of Fibonacci
8437
05:56:17,878 --> 05:56:19,638
numbers to generate okay so we have a
8438
05:56:19,638 --> 05:56:22,400
Fibonacci function here and it takes the
8439
05:56:22,400 --> 05:56:25,638
numbers and the channel itself so let's
8440
05:56:25,638 --> 05:56:28,760
start a go routine in an anonymous
8441
05:56:28,760 --> 05:56:30,558
function go
8442
05:56:30,558 --> 05:56:32,638
Funk call the
8443
05:56:32,638 --> 05:56:36,600
function um and in here we we call
8444
05:56:36,600 --> 05:56:38,718
Fibonacci let me just copy and paste
8445
05:56:38,718 --> 05:56:41,160
that because I can't spell
8446
05:56:41,160 --> 05:56:45,120
it uh it takes n
8447
05:56:45,120 --> 05:56:50,840
and this channel of in as input
8448
05:56:50,840 --> 05:56:54,040
okay then use a Range Loop to read from
8449
05:56:54,040 --> 05:56:55,280
the channel and print out the numbers
8450
05:56:55,280 --> 05:56:56,878
one by one each on a new line okay so
8451
05:56:56,878 --> 05:56:59,558
the Fibonacci function is going to pass
8452
05:56:59,558 --> 05:57:03,320
its results back over this channel so
8453
05:57:03,320 --> 05:57:06,440
it's it's taking the channel and it's
8454
05:57:06,440 --> 05:57:08,840
going to act as the sender on the
8455
05:57:08,840 --> 05:57:12,558
channel so we down here below um kind of
8456
05:57:12,558 --> 05:57:14,160
where we're spawning that go routine
8457
05:57:14,160 --> 05:57:18,638
need to act as the reader so for V and
8458
05:57:18,638 --> 05:57:21,878
range Channel
8459
05:57:23,440 --> 05:57:26,600
events print out the numbers one by
8460
05:57:26,600 --> 05:57:29,080
one print line
8461
05:57:29,080 --> 05:57:32,478
V and then when the Fibonacci function
8462
05:57:32,478 --> 05:57:34,400
is done it will close the channel so
8463
05:57:34,400 --> 05:57:37,160
we'll exit from the loop cool let's go
8464
05:57:37,160 --> 05:57:39,760
ahead and run
8465
05:57:41,040 --> 05:57:44,320
that does this look accurate 10 numbers
8466
05:57:44,320 --> 05:57:49,080
0er and one 0 + 1 is 1 1 + 2 is 3 2 + 3
8467
05:57:49,080 --> 05:57:52,400
is 5 looking good to me on to select
8468
05:57:52,400 --> 05:57:54,760
statements so a select statement is
8469
05:57:54,760 --> 05:57:56,520
similar to a switch statement if you're
8470
05:57:56,520 --> 05:57:58,440
familiar with switch statements from
8471
05:57:58,440 --> 05:58:00,320
other languages or from go where it's
8472
05:58:00,320 --> 05:58:03,718
kind of this if else uh chain and we're
8473
05:58:03,718 --> 05:58:05,478
really looking to kind of match a
8474
05:58:05,478 --> 05:58:07,200
specific case but what's interesting
8475
05:58:07,200 --> 05:58:08,638
about select statements is they're
8476
05:58:08,638 --> 05:58:11,120
unique to channels and they basically
8477
05:58:11,120 --> 05:58:14,718
let us listen on two different channels
8478
05:58:14,718 --> 05:58:18,080
and kind of execute one block of code um
8479
05:58:18,080 --> 05:58:20,840
or or or rather execute a block of code
8480
05:58:20,840 --> 05:58:24,160
for the channel that sends a value the
8481
05:58:24,160 --> 05:58:26,240
soonest so we can kind of simultaneously
8482
05:58:26,240 --> 05:58:28,600
listen on both channels and if this
8483
05:58:28,600 --> 05:58:30,558
channel sends a value first then we'll
8484
05:58:30,558 --> 05:58:32,920
do you know one thing otherwise when
8485
05:58:32,920 --> 05:58:34,440
this one sends something we'll do
8486
05:58:34,440 --> 05:58:37,000
another thing so one go r can kind of
8487
05:58:37,000 --> 05:58:39,600
process events from multiple channels at
8488
05:58:39,600 --> 05:58:41,638
the same time using a select statement
8489
05:58:41,638 --> 05:58:44,200
so this is the syntax here we create a
8490
05:58:44,200 --> 05:58:47,558
select block and then multiple cases one
8491
05:58:47,558 --> 05:58:49,840
for each channel that we are interested
8492
05:58:49,840 --> 05:58:52,280
in kind of listening for values on or
8493
05:58:52,280 --> 05:58:55,718
reading uh values off of so if this
8494
05:58:55,718 --> 05:58:58,840
channel ins has a value ready then this
8495
05:58:58,840 --> 05:59:01,638
case will be executed otherwise if this
8496
05:59:01,638 --> 05:59:04,000
one uh if Channel strings has a value
8497
05:59:04,000 --> 05:59:07,520
ready then this case will be executed if
8498
05:59:07,520 --> 05:59:09,638
both have a value ready at the same time
8499
05:59:09,638 --> 05:59:12,000
then one will be chosen randomly so you
8500
05:59:12,000 --> 05:59:13,600
don't want to kind of be dependent on
8501
05:59:13,600 --> 05:59:16,040
any weird ordering um basically as stuff
8502
05:59:16,040 --> 05:59:18,360
comes across it's going to get processed
8503
05:59:18,360 --> 05:59:20,280
so on to the assignment it says complete
8504
05:59:20,280 --> 05:59:21,840
the log messages function using an
8505
05:59:21,840 --> 05:59:23,240
infinite for Loop and a select statement
8506
05:59:23,240 --> 05:59:25,120
to log the emails and SMS messages as
8507
05:59:25,120 --> 05:59:26,520
they come across the two channels okay
8508
05:59:26,520 --> 05:59:28,360
so channel of emails channel of SMS
8509
05:59:28,360 --> 05:59:30,840
messages add a condition to return from
8510
05:59:30,840 --> 05:59:31,920
the function when one of the two
8511
05:59:31,920 --> 05:59:34,120
channels closes whichever is first um
8512
05:59:34,120 --> 05:59:36,040
use the log SMS and log email function
8513
05:59:36,040 --> 05:59:38,520
functions to log the messages Okay cool
8514
05:59:38,520 --> 05:59:42,920
so uh infinite for Loop start there and
8515
05:59:42,920 --> 05:59:46,120
inside we'll need to
8516
05:59:46,680 --> 05:59:49,520
select can use this as our syntax guide
8517
05:59:49,520 --> 05:59:53,160
over here U we got case uh
8518
05:59:53,160 --> 05:59:55,920
email
8519
05:59:55,920 --> 06:00:00,360
okay value from channel of
8520
06:00:00,920 --> 06:00:03,760
emails if that case fires then we say if
8521
06:00:03,760 --> 06:00:06,240
not okay so if the channel is closed we
8522
06:00:06,240 --> 06:00:08,160
just return and this function returns
8523
06:00:08,160 --> 06:00:11,120
nothing so we just naked return um
8524
06:00:11,120 --> 06:00:14,840
otherwise we need to log email I think
8525
06:00:14,840 --> 06:00:18,798
that's yeah log email there it is the
8526
06:00:18,798 --> 06:00:24,080
email cool other case uh sms okay from
8527
06:00:24,080 --> 06:00:26,638
the channel of
8528
06:00:26,638 --> 06:00:29,240
SMS if not
8529
06:00:29,240 --> 06:00:31,558
okay
8530
06:00:31,558 --> 06:00:33,920
return
8531
06:00:33,920 --> 06:00:37,920
otherwise log the
8532
06:00:38,440 --> 06:00:40,760
right so this for Loop will just go
8533
06:00:40,760 --> 06:00:43,360
forever until one of these two channels
8534
06:00:43,360 --> 06:00:46,160
closes in which case it'll return right
8535
06:00:46,160 --> 06:00:48,240
and it's important that we return before
8536
06:00:48,240 --> 06:00:50,520
we do the logging because when a channel
8537
06:00:50,520 --> 06:00:54,638
closes the okay variable um is false and
8538
06:00:54,638 --> 06:00:58,920
a zero value comes across the channel um
8539
06:00:58,920 --> 06:01:00,558
that wasn't sent into the channel if
8540
06:01:00,558 --> 06:01:01,840
that makes sense so like the closure
8541
06:01:01,840 --> 06:01:05,120
happens after the last value comes out
8542
06:01:05,120 --> 06:01:07,920
let's go ahead and run that
8543
06:01:10,840 --> 06:01:14,120
looking good to me we'll submit it the
8544
06:01:14,120 --> 06:01:17,718
select statement also has a default case
8545
06:01:17,718 --> 06:01:19,798
you don't always need to use the default
8546
06:01:19,798 --> 06:01:22,120
case and basically the default case only
8547
06:01:22,120 --> 06:01:25,120
fires if you're interested in
8548
06:01:25,120 --> 06:01:27,798
nonblocking so for example this select
8549
06:01:27,798 --> 06:01:32,638
block here will fire the case uh that
8550
06:01:32,638 --> 06:01:34,840
kind of pulls this V value out of this
8551
06:01:34,840 --> 06:01:37,478
channel if there is a value ready to be
8552
06:01:37,478 --> 06:01:39,558
pulled at the time that we enter the
8553
06:01:39,558 --> 06:01:41,920
select block if there's not a value
8554
06:01:41,920 --> 06:01:44,240
ready to be read out of the channel um
8555
06:01:44,240 --> 06:01:46,240
then the default case is fired
8556
06:01:46,240 --> 06:01:48,200
immediately so it kind of turns the
8557
06:01:48,200 --> 06:01:51,080
select block into a nonblocking block of
8558
06:01:51,080 --> 06:01:52,760
code and then there's a few things we're
8559
06:01:52,760 --> 06:01:54,440
going to need to know for this
8560
06:01:54,440 --> 06:01:56,718
assignment the first are these uh
8561
06:01:56,718 --> 06:01:59,440
several standard Library functions so
8562
06:01:59,440 --> 06:02:02,320
time. tick returns a channel that sends
8563
06:02:02,320 --> 06:02:04,200
a value on a given interval so we could
8564
06:02:04,200 --> 06:02:07,240
say uh pass in a second to time. tick
8565
06:02:07,240 --> 06:02:10,160
and we would get back a channel um that
8566
06:02:10,160 --> 06:02:12,920
receives a value once per second pretty
8567
06:02:12,920 --> 06:02:15,200
cool for like rate limiting doing
8568
06:02:15,200 --> 06:02:19,080
something on a set interval um time.
8569
06:02:19,080 --> 06:02:21,920
after sends a single value after the
8570
06:02:21,920 --> 06:02:23,878
specified time has passed so if we
8571
06:02:23,878 --> 06:02:26,280
created a new Channel with time. after
8572
06:02:26,280 --> 06:02:28,638
and passed in one second then one value
8573
06:02:28,638 --> 06:02:30,478
would come across after a second had
8574
06:02:30,478 --> 06:02:32,200
passed and then the channel would be
8575
06:02:32,200 --> 06:02:36,200
closed um time dos sleep just blocks for
8576
06:02:36,200 --> 06:02:37,638
the specified amount of time in fact I
8577
06:02:37,638 --> 06:02:39,638
think we've kind of seen it around um so
8578
06:02:39,638 --> 06:02:42,000
far in the course and then we have read
8579
06:02:42,000 --> 06:02:44,120
only and write only channels and these
8580
06:02:44,120 --> 06:02:46,240
are pretty cool from like a type safety
8581
06:02:46,240 --> 06:02:47,920
standpoint uh basically we can take a
8582
06:02:47,920 --> 06:02:50,160
channel and we can pass it into a
8583
06:02:50,160 --> 06:02:52,478
function but specify that within the
8584
06:02:52,478 --> 06:02:55,120
function we are just going to read from
8585
06:02:55,120 --> 06:02:57,360
it so then within the function uh the
8586
06:02:57,360 --> 06:02:59,240
compiler will not allow us to write to
8587
06:02:59,240 --> 06:03:00,920
it so this is a great way to kind of
8588
06:03:00,920 --> 06:03:03,360
keep uh go routine safe in terms of
8589
06:03:03,360 --> 06:03:05,280
which functions are readers of channels
8590
06:03:05,280 --> 06:03:06,760
and which fun fun are writers of
8591
06:03:06,760 --> 06:03:08,840
channels um and we can do the same thing
8592
06:03:08,840 --> 06:03:11,600
with writers by using this syntax here
8593
06:03:11,600 --> 06:03:13,400
so readers read out of the channel
8594
06:03:13,400 --> 06:03:15,280
writers right into the channel the
8595
06:03:15,280 --> 06:03:16,958
assignment says like all good backed
8596
06:03:16,958 --> 06:03:18,638
Engineers we frequently save backup
8597
06:03:18,638 --> 06:03:21,520
snapshots of the maleo database complete
8598
06:03:21,520 --> 06:03:24,040
the save backups function okay it should
8599
06:03:24,040 --> 06:03:26,760
read values from the snapshot ticker and
8600
06:03:26,760 --> 06:03:29,440
save after channels simultaneously okay
8601
06:03:29,440 --> 06:03:31,040
so the ticker and the save after these
8602
06:03:31,040 --> 06:03:34,320
are channels that are created down
8603
06:03:34,320 --> 06:03:37,478
here us those standard Library functions
8604
06:03:37,478 --> 06:03:38,718
that we just talked
8605
06:03:38,718 --> 06:03:43,400
about okay so we need to use a select
8606
06:03:43,400 --> 06:03:45,760
statement it looks like read values
8607
06:03:45,760 --> 06:03:47,920
continuously so I'm going to use a for
8608
06:03:47,920 --> 06:03:51,878
Loop and a select
8609
06:03:51,878 --> 06:03:54,280
statement if a value is received from
8610
06:03:54,280 --> 06:03:57,680
snapshot ticker call take snapshot okay
8611
06:03:57,680 --> 06:04:03,360
so case Val okay we want to read out of
8612
06:04:03,360 --> 06:04:07,240
a snapshot ticker
8613
06:04:08,878 --> 06:04:10,798
um do we actually do we care about the
8614
06:04:10,798 --> 06:04:13,798
channel being closed let's see saved
8615
06:04:13,798 --> 06:04:15,638
after no actually we don't so we just
8616
06:04:15,638 --> 06:04:18,280
need the value from snapshot
8617
06:04:18,280 --> 06:04:20,120
ticker oh and we don't even care about
8618
06:04:20,120 --> 06:04:21,958
what the value is so we can just
8619
06:04:21,958 --> 06:04:26,878
completely ignore the value um call take
8620
06:04:26,878 --> 06:04:29,280
snapshot
8621
06:04:29,280 --> 06:04:34,120
okay if the values saved after so
8622
06:04:34,120 --> 06:04:37,638
case save
8623
06:04:37,680 --> 06:04:41,200
after call Save
8624
06:04:41,200 --> 06:04:43,478
snapshot and return from the function
8625
06:04:43,478 --> 06:04:46,040
because we're done okay so again we
8626
06:04:46,040 --> 06:04:47,280
don't need to return anything from this
8627
06:04:47,280 --> 06:04:49,680
function doesn't have any return values
8628
06:04:49,680 --> 06:04:52,120
if neither channel has a value ready
8629
06:04:52,120 --> 06:04:56,718
call wait for data okay so
8630
06:04:56,840 --> 06:05:00,360
default wait for
8631
06:05:00,360 --> 06:05:03,478
data and then sleep for 500 milliseconds
8632
06:05:03,478 --> 06:05:07,478
so time do sleep
8633
06:05:07,478 --> 06:05:10,040
time.
8634
06:05:10,040 --> 06:05:12,558
millisecond time
8635
06:05:12,558 --> 06:05:14,200
500
8636
06:05:14,200 --> 06:05:16,240
okay this is looking good so we've got
8637
06:05:16,240 --> 06:05:17,878
this infinite for Loop we'll we're
8638
06:05:17,878 --> 06:05:20,718
looking for values um that are coming
8639
06:05:20,718 --> 06:05:23,520
across these channels anytime a snapshot
8640
06:05:23,520 --> 06:05:26,080
should be taken we take it anytime um
8641
06:05:26,080 --> 06:05:28,718
this save after Channel passes us a
8642
06:05:28,718 --> 06:05:31,280
value we will save the snapshot and exit
8643
06:05:31,280 --> 06:05:34,718
the function otherwise we'll wait for
8644
06:05:34,718 --> 06:05:37,200
data whatever that does and sleep for
8645
06:05:37,200 --> 06:05:38,878
500 milliseconds in fact I'm curious
8646
06:05:38,878 --> 06:05:40,440
what does wait for day to do okay so all
8647
06:05:40,440 --> 06:05:43,200
these do um is kind of Print Different
8648
06:05:43,200 --> 06:05:46,520
messages so let's go ahead and run
8649
06:05:49,600 --> 06:05:52,360
that okay cool so nothing to do waiting
8650
06:05:52,360 --> 06:05:54,520
nothing to do waiting right so every 500
8651
06:05:54,520 --> 06:05:56,160
milliseconds we're kind of logging out
8652
06:05:56,160 --> 06:05:57,478
that we are waiting we're waiting for
8653
06:05:57,478 --> 06:06:00,680
things to to do um taking back backups
8654
06:06:00,680 --> 06:06:03,600
taking backups and um finally saving the
8655
06:06:03,600 --> 06:06:05,280
backups at the end cool let's submit
8656
06:06:05,280 --> 06:06:08,920
this looks correct to me Dave Cheney is
8657
06:06:08,920 --> 06:06:11,718
a fantastic author and contributor to
8658
06:06:11,718 --> 06:06:13,478
the go programming language and the go
8659
06:06:13,478 --> 06:06:15,638
ecosystem um and he has this awesome
8660
06:06:15,638 --> 06:06:16,760
article that I would definitely
8661
06:06:16,760 --> 06:06:18,320
recommend checking out it's called
8662
06:06:18,320 --> 06:06:20,440
Channel axioms um I've kind of
8663
06:06:20,440 --> 06:06:22,600
summarized it here and we're going to
8664
06:06:22,600 --> 06:06:25,000
talk about a few key points so the first
8665
06:06:25,000 --> 06:06:27,920
is that Ascend to a nil Channel blocks
8666
06:06:27,920 --> 06:06:31,040
forever so the zero value for a channel
8667
06:06:31,040 --> 06:06:33,000
is nil if you don't use the make
8668
06:06:33,000 --> 06:06:34,840
function to initialize a channel then
8669
06:06:34,840 --> 06:06:37,080
the Channel's value is just nil and if
8670
06:06:37,080 --> 06:06:40,360
you try to send on a nil Channel your
8671
06:06:40,360 --> 06:06:42,798
code's just going to block forever
8672
06:06:42,798 --> 06:06:45,958
similarly a receive from a nil channel
8673
06:06:45,958 --> 06:06:48,440
will just block forever now this one's a
8674
06:06:48,440 --> 06:06:51,320
lot more dangerous trying to send on a
8675
06:06:51,320 --> 06:06:54,280
closed Channel panics so you need to be
8676
06:06:54,280 --> 06:06:55,878
really careful and make sure you're only
8677
06:06:55,878 --> 06:06:58,958
closing channels from the go routine or
8678
06:06:58,958 --> 06:07:00,440
the function that's writing to the
8679
06:07:00,440 --> 06:07:02,440
channel so that you can be sure you'll
8680
06:07:02,440 --> 06:07:04,240
never try to write to that closed
8681
06:07:04,240 --> 06:07:06,600
Channel again and then then a receive
8682
06:07:06,600 --> 06:07:09,200
from a closed Channel Returns the zero
8683
06:07:09,200 --> 06:07:11,000
value immediately so if you're trying to
8684
06:07:11,000 --> 06:07:12,798
pull data out of a channel and it's
8685
06:07:12,798 --> 06:07:14,478
already closed you'll just get the zero
8686
06:07:14,478 --> 06:07:16,600
value and we've already seen how you can
8687
06:07:16,600 --> 06:07:18,400
also kind of optionally check for that
8688
06:07:18,400 --> 06:07:20,760
okay value uh which will be returned as
8689
06:07:20,760 --> 06:07:23,360
false so what happens when you read from
8690
06:07:23,360 --> 06:07:26,320
a nil's channel uh the receiver will
8691
06:07:26,320 --> 06:07:29,040
block forever and what happens when you
8692
06:07:29,040 --> 06:07:32,160
send to a closed channel uh you'll get a
8693
06:07:32,160 --> 06:07:34,558
panic and you never really want to panic
8694
06:07:34,558 --> 06:07:36,798
and go that's almost always indicative
8695
06:07:36,798 --> 06:07:40,080
of a bug so channels are one tool that
8696
06:07:40,080 --> 06:07:42,360
we have in go to sort of synchronize
8697
06:07:42,360 --> 06:07:45,320
State across different go routines right
8698
06:07:45,320 --> 06:07:47,478
we can send data from one go routine to
8699
06:07:47,478 --> 06:07:50,200
another safely mutexes are another
8700
06:07:50,200 --> 06:07:52,240
builtin primitive well rather they're
8701
06:07:52,240 --> 06:07:53,718
not built into the language but they're
8702
06:07:53,718 --> 06:07:56,240
built into the standard library and they
8703
06:07:56,240 --> 06:07:58,878
allow us to also sort of communicate or
8704
06:07:58,878 --> 06:08:02,520
share data between two go routines
8705
06:08:02,520 --> 06:08:05,878
mutexes work by locking access to
8706
06:08:05,878 --> 06:08:08,440
protected resources so that only one go
8707
06:08:08,440 --> 06:08:10,840
routine can access that resource at a
8708
06:08:10,840 --> 06:08:15,000
time so the sync. mutex type is exposed
8709
06:08:15,000 --> 06:08:17,000
by the standard library and basically
8710
06:08:17,000 --> 06:08:18,360
the way it works is you create a new
8711
06:08:18,360 --> 06:08:20,718
mutex and then you share it across many
8712
06:08:20,718 --> 06:08:24,760
different go routines and then you wrap
8713
06:08:24,760 --> 06:08:27,280
whatever code that that is dangerous or
8714
06:08:27,280 --> 06:08:29,558
whatever resource that is dangerous um
8715
06:08:29,558 --> 06:08:32,040
that you never want two go routines at
8716
06:08:32,040 --> 06:08:34,680
the same time kind of getting access to
8717
06:08:34,680 --> 06:08:37,718
you wrap them in a call to lock and
8718
06:08:37,718 --> 06:08:39,400
unlock so for example in this function
8719
06:08:39,400 --> 06:08:42,320
we have this protected function and it
8720
06:08:42,320 --> 06:08:44,600
calls mx. lock at the top of the
8721
06:08:44,600 --> 06:08:48,440
function and then it defers an unlock
8722
06:08:48,440 --> 06:08:50,718
and what this means is when one go
8723
06:08:50,718 --> 06:08:53,718
routine calls this protected function um
8724
06:08:53,718 --> 06:08:56,200
if it's the first call to this protected
8725
06:08:56,200 --> 06:08:58,558
function then this mx. loock will lock
8726
06:08:58,558 --> 06:09:01,120
the mutex for this go routine and it
8727
06:09:01,120 --> 06:09:02,718
will be able to move on and kind of
8728
06:09:02,718 --> 06:09:04,120
complete the rest of the function and
8729
06:09:04,120 --> 06:09:07,680
then call uh m tex. unlock every other
8730
06:09:07,680 --> 06:09:10,680
go routine that calls this function
8731
06:09:10,680 --> 06:09:12,638
right on this shared mutex will actually
8732
06:09:12,638 --> 06:09:16,798
block at the mx. loock function call
8733
06:09:16,798 --> 06:09:18,680
because the mutex is locked by another
8734
06:09:18,680 --> 06:09:21,760
go routine so mutex stands for Mutual
8735
06:09:21,760 --> 06:09:24,520
exclusion because it excludes every go
8736
06:09:24,520 --> 06:09:26,240
routine except one except for the one
8737
06:09:26,240 --> 06:09:28,320
that holds the lock and once that first
8738
06:09:28,320 --> 06:09:31,040
one actually unlocks the mutex then one
8739
06:09:31,040 --> 06:09:32,878
other go routine is able to pick up the
8740
06:09:32,878 --> 06:09:36,080
lock um execute its protected code
8741
06:09:36,080 --> 06:09:38,040
and move on from there so it's a way to
8742
06:09:38,040 --> 06:09:40,400
take some dangerous resource and sort of
8743
06:09:40,400 --> 06:09:42,000
share it across many different go
8744
06:09:42,000 --> 06:09:44,798
routines uh safely there are a couple of
8745
06:09:44,798 --> 06:09:47,040
different reasons why you would want to
8746
06:09:47,040 --> 06:09:48,958
protect a resource and only allow a
8747
06:09:48,958 --> 06:09:51,360
single go routine to kind of work on
8748
06:09:51,360 --> 06:09:53,638
that resource at a time but one super
8749
06:09:53,638 --> 06:09:57,040
common one is Maps so maps are not
8750
06:09:57,040 --> 06:09:59,360
thread safe in go if two different go
8751
06:09:59,360 --> 06:10:01,840
routines or trying to read from and
8752
06:10:01,840 --> 06:10:04,320
write to the same map uh go will
8753
06:10:04,320 --> 06:10:05,958
actually panic
8754
06:10:05,958 --> 06:10:07,840
uh because that has a very high
8755
06:10:07,840 --> 06:10:09,798
likelihood of causing a race condition
8756
06:10:09,798 --> 06:10:11,400
and if you're wondering what a race
8757
06:10:11,400 --> 06:10:13,638
condition is a race condition is kind of
8758
06:10:13,638 --> 06:10:15,200
what it sounds like it's when two
8759
06:10:15,200 --> 06:10:18,360
different go routines effectively racing
8760
06:10:18,360 --> 06:10:20,920
uh to get access to a specific resource
8761
06:10:20,920 --> 06:10:23,520
so imagine a case where we have a count
8762
06:10:23,520 --> 06:10:25,280
variable and it's set equal to maybe
8763
06:10:25,280 --> 06:10:27,360
five and you have one go routine that
8764
06:10:27,360 --> 06:10:29,360
reads that count variable and saves it
8765
06:10:29,360 --> 06:10:32,320
into say another variable my count right
8766
06:10:32,320 --> 06:10:34,400
and then maybe doubles it and then saves
8767
06:10:34,400 --> 06:10:37,160
the doubled value back into count well
8768
06:10:37,160 --> 06:10:39,798
what if we have another uh thread of
8769
06:10:39,798 --> 06:10:42,000
execution doing the same thing if they
8770
06:10:42,000 --> 06:10:44,360
both read count let's say they both read
8771
06:10:44,360 --> 06:10:46,000
five
8772
06:10:46,000 --> 06:10:49,958
double five so now they both store 25
8773
06:10:49,958 --> 06:10:52,520
and they both go to write 25 back into
8774
06:10:52,520 --> 06:10:56,120
the variable all you did was double five
8775
06:10:56,120 --> 06:10:58,840
once where you were probably expecting
8776
06:10:58,840 --> 06:11:01,040
to have two different threads doubling
8777
06:11:01,040 --> 06:11:02,840
the variable so you probably were
8778
06:11:02,840 --> 06:11:05,360
expecting for it to go 5 to 25 and then
8779
06:11:05,360 --> 06:11:09,680
double again 25 s 625 I think um the
8780
06:11:09,680 --> 06:11:12,200
point is depending on exactly how those
8781
06:11:12,200 --> 06:11:14,240
operations are threaded into the CPU
8782
06:11:14,240 --> 06:11:16,680
you'll actually get different Behavior
8783
06:11:16,680 --> 06:11:19,878
so race conditions are awful to debug
8784
06:11:19,878 --> 06:11:23,120
and mutexes allow us to lock access to
8785
06:11:23,120 --> 06:11:24,360
those protected variables so we could
8786
06:11:24,360 --> 06:11:27,840
wrap that count variable in a mutex to
8787
06:11:27,840 --> 06:11:30,558
avoid it being accessed at the same time
8788
06:11:30,558 --> 06:11:33,360
by different go routines so this should
8789
06:11:33,360 --> 06:11:35,280
make a lot more sense once we write some
8790
06:11:35,280 --> 06:11:37,558
code the assignment says we send emails
8791
06:11:37,558 --> 06:11:39,360
across many different go routines at
8792
06:11:39,360 --> 06:11:41,798
maleo to keep track of how many we've
8793
06:11:41,798 --> 06:11:43,920
sent to a given email address we use an
8794
06:11:43,920 --> 06:11:46,520
in-memory map Okay so we've got this
8795
06:11:46,520 --> 06:11:49,680
counts map stored within a safe counter
8796
06:11:49,680 --> 06:11:52,080
struct the map is of string to integer
8797
06:11:52,080 --> 06:11:54,360
and then we've got a pointer to a mutex
8798
06:11:54,360 --> 06:11:56,200
uh that we're sharing across all these
8799
06:11:56,200 --> 06:11:59,040
different go routines um our safe
8800
06:11:59,040 --> 06:12:01,680
counter struct is unsafe update the
8801
06:12:01,680 --> 06:12:04,558
increment and the value methods so they
8802
06:12:04,558 --> 06:12:06,320
utilize the safe counters mutex to
8803
06:12:06,320 --> 06:12:08,400
ensure that the map is not accessed by
8804
06:12:08,400 --> 06:12:11,840
multiple go routines at the same time
8805
06:12:11,840 --> 06:12:14,080
okay so we've got the safe counter and
8806
06:12:14,080 --> 06:12:15,920
it looks like it's going to be kind of
8807
06:12:15,920 --> 06:12:18,958
copied across different go routines so
8808
06:12:18,958 --> 06:12:20,638
we create one instance of the safe
8809
06:12:20,638 --> 06:12:23,040
counter um it's getting passed into this
8810
06:12:23,040 --> 06:12:25,320
test function and then we've got this go
8811
06:12:25,320 --> 06:12:27,478
routine um it looks like we're spawning
8812
06:12:27,478 --> 06:12:30,920
go routines in a for Loop and then uh
8813
06:12:30,920 --> 06:12:32,798
and then using that safe counter right
8814
06:12:32,798 --> 06:12:34,680
so increment is being called many
8815
06:12:34,680 --> 06:12:37,120
different times across many different uh
8816
06:12:37,120 --> 06:12:39,440
threads of execution and that is not
8817
06:12:39,440 --> 06:12:42,760
safe cool um so let's see what happens
8818
06:12:42,760 --> 06:12:46,000
if I run the code right
8819
06:12:46,360 --> 06:12:49,920
now Jill has three emails John has
8820
06:12:49,920 --> 06:12:52,520
four and if I look down into the tests
8821
06:12:52,520 --> 06:12:55,798
like that is wildly inaccurate right so
8822
06:12:55,798 --> 06:12:58,000
it it kind of looks like what's
8823
06:12:58,000 --> 06:13:00,120
happening is is like the example I
8824
06:13:00,120 --> 06:13:02,520
described where maybe you're multiplying
8825
06:13:02,520 --> 06:13:04,798
numbers together at the same time so you
8826
06:13:04,798 --> 06:13:06,680
kind of end up with a smaller number cuz
8827
06:13:06,680 --> 06:13:07,920
everyone's doing it at the same time
8828
06:13:07,920 --> 06:13:09,440
then saving the variable back it kind of
8829
06:13:09,440 --> 06:13:11,120
looks like that's what's happening we're
8830
06:13:11,120 --> 06:13:13,320
getting these tiny results cuz all of
8831
06:13:13,320 --> 06:13:14,600
these different go routines are
8832
06:13:14,600 --> 06:13:17,680
incrementing uh the number at the same
8833
06:13:17,680 --> 06:13:23,520
time okay so we need to lock this
8834
06:13:23,520 --> 06:13:25,040
down
8835
06:13:25,040 --> 06:13:27,120
sc.
8836
06:13:27,120 --> 06:13:30,240
m.m. loock so lock
8837
06:13:30,240 --> 06:13:36,000
the the mutex and then defer the unlock
8838
06:13:36,440 --> 06:13:38,040
it's important to understand that we
8839
06:13:38,040 --> 06:13:40,958
could do this and it would be the
8840
06:13:40,958 --> 06:13:43,920
same um right we lock we do the
8841
06:13:43,920 --> 06:13:46,718
dangerous thing and then we unlock um
8842
06:13:46,718 --> 06:13:49,160
but this is the
8843
06:13:49,160 --> 06:13:51,240
preferred the preferred way kind of the
8844
06:13:51,240 --> 06:13:53,798
idiomatic go way to do it um it just
8845
06:13:53,798 --> 06:13:55,680
it's just a little safer right if we add
8846
06:13:55,680 --> 06:13:57,920
multiple Returns the defer will never
8847
06:13:57,920 --> 06:14:00,718
not execute so um that's how we're going
8848
06:14:00,718 --> 06:14:03,798
to do it and then we also need to lock
8849
06:14:03,798 --> 06:14:06,520
um on the Val function because reading
8850
06:14:06,520 --> 06:14:08,958
um and writing at the same time is also
8851
06:14:08,958 --> 06:14:11,878
dangerous cool let's run that see if we
8852
06:14:11,878 --> 06:14:14,520
get some bigger numbers in our
8853
06:14:14,520 --> 06:14:17,840
counts notice it's taking a lot longer
8854
06:14:17,840 --> 06:14:19,798
to run and and that's because we're
8855
06:14:19,798 --> 06:14:22,440
locking and unlocking so every thread
8856
06:14:22,440 --> 06:14:25,040
has to kind of go one after the other so
8857
06:14:25,040 --> 06:14:28,200
it slows it down um but it's a lot safer
8858
06:14:28,200 --> 06:14:31,200
so we get these accurate counts let's go
8859
06:14:31,200 --> 06:14:32,840
ahead and submit
8860
06:14:32,840 --> 06:14:35,840
that so as we discussed am mutex is
8861
06:14:35,840 --> 06:14:37,558
called a mutex because it's short for
8862
06:14:37,558 --> 06:14:41,040
Mutual exclusion and the conventional
8863
06:14:41,040 --> 06:14:44,600
name for a mutex is um mutex or
8864
06:14:44,600 --> 06:14:46,558
sometimes it's abbreviated to MX
8865
06:14:46,558 --> 06:14:49,958
personally I use MX a lot so to answer
8866
06:14:49,958 --> 06:14:51,840
the question what does it refer to it's
8867
06:14:51,840 --> 06:14:53,600
going to be mutual exclusion the next
8868
06:14:53,600 --> 06:14:55,718
question is how many threads or go
8869
06:14:55,718 --> 06:14:58,558
routines can lock a mutex at once or at
8870
06:14:58,558 --> 06:15:03,160
the same time the answer is one right if
8871
06:15:03,160 --> 06:15:05,040
any more could lock it at the same time
8872
06:15:05,040 --> 06:15:07,718
time it wouldn't be very useful the next
8873
06:15:07,718 --> 06:15:10,520
question is why would you use a mutex to
8874
06:15:10,520 --> 06:15:12,000
safely access a data structure
8875
06:15:12,000 --> 06:15:14,200
concurrently to stop other packages from
8876
06:15:14,200 --> 06:15:16,200
using my code to protect data from
8877
06:15:16,200 --> 06:15:18,320
network access or to encapsulate private
8878
06:15:18,320 --> 06:15:20,440
data members of a struct it's going to
8879
06:15:20,440 --> 06:15:23,440
be to safely Access Data
8880
06:15:23,440 --> 06:15:26,200
concurrently time to talk about another
8881
06:15:26,200 --> 06:15:29,040
type of mutex so we've already covered
8882
06:15:29,040 --> 06:15:30,440
pretty much all of the functionality you
8883
06:15:30,440 --> 06:15:32,958
need to know about the sync. mutex type
8884
06:15:32,958 --> 06:15:35,000
but there's another type there is a
8885
06:15:35,000 --> 06:15:40,200
sync. RW mutex or sync. readr mutex so
8886
06:15:40,200 --> 06:15:43,558
the sync. readr mutex has a little more
8887
06:15:43,558 --> 06:15:45,638
functionality um it has the same lock
8888
06:15:45,638 --> 06:15:48,000
and unlock methods and works exactly the
8889
06:15:48,000 --> 06:15:50,478
same way as a normal mutex but
8890
06:15:50,478 --> 06:15:52,798
additionally it has two more methods
8891
06:15:52,798 --> 06:15:55,718
rlock and R unlock so the reason you
8892
06:15:55,718 --> 06:15:58,638
would use a read write mutex is because
8893
06:15:58,638 --> 06:16:00,840
it allows you to have multiple readers
8894
06:16:00,840 --> 06:16:03,120
at the same time for example it's
8895
06:16:03,120 --> 06:16:06,160
actually safe to read for from a map on
8896
06:16:06,160 --> 06:16:08,360
multiple go routines at the same time as
8897
06:16:08,360 --> 06:16:10,160
long as you're not reading and writing
8898
06:16:10,160 --> 06:16:12,558
at the same time or writing and writing
8899
06:16:12,558 --> 06:16:14,360
at the same time writing is the
8900
06:16:14,360 --> 06:16:16,840
dangerous operation so the way this
8901
06:16:16,840 --> 06:16:20,240
works is if the mutex is locked like
8902
06:16:20,240 --> 06:16:23,520
with the do loock method then no other
8903
06:16:23,520 --> 06:16:28,320
go routines can lock or arlock the mutex
8904
06:16:28,320 --> 06:16:31,600
however if the mutex is just are locked
8905
06:16:31,600 --> 06:16:35,920
then other mutexes can still our locket
8906
06:16:35,920 --> 06:16:38,160
so you can get multiple readers but you
8907
06:16:38,160 --> 06:16:41,040
can't get readers and writers or writers
8908
06:16:41,040 --> 06:16:43,718
and writers it just allows many threads
8909
06:16:43,718 --> 06:16:46,680
to concurrently read so what this does
8910
06:16:46,680 --> 06:16:48,798
is if you have a program with a shared
8911
06:16:48,798 --> 06:16:51,200
resource where most of the threads are
8912
06:16:51,200 --> 06:16:52,680
interested with reading the shared
8913
06:16:52,680 --> 06:16:54,760
resource and you only have a few writers
8914
06:16:54,760 --> 06:16:57,320
you can make your code a lot faster by
8915
06:16:57,320 --> 06:16:59,280
using a read write mutex and allowing
8916
06:16:59,280 --> 06:17:01,080
multiple readers at the same time your
8917
06:17:01,080 --> 06:17:03,360
code will move faster and have fewer
8918
06:17:03,360 --> 06:17:05,360
locks slowing down
8919
06:17:05,360 --> 06:17:07,680
um and synchronizing your application so
8920
06:17:07,680 --> 06:17:09,600
on to the assignment it says let's
8921
06:17:09,600 --> 06:17:11,160
update our same code from the last
8922
06:17:11,160 --> 06:17:12,718
assignment but this time we can speed it
8923
06:17:12,718 --> 06:17:14,400
up by allowing readers to be read from
8924
06:17:14,400 --> 06:17:16,798
the map concurrently update The Vow
8925
06:17:16,798 --> 06:17:18,600
method to only lock the mutex for
8926
06:17:18,600 --> 06:17:20,558
reading notice that if you run the code
8927
06:17:20,558 --> 06:17:22,320
with a right lock it will block forever
8928
06:17:22,320 --> 06:17:24,080
Okay cool so if I run try to run it
8929
06:17:24,080 --> 06:17:26,878
right now um it's going to have issues
8930
06:17:26,878 --> 06:17:31,600
because I believe it is are locked um by
8931
06:17:31,600 --> 06:17:34,040
the test Suite out of the gate so that's
8932
06:17:34,040 --> 06:17:37,040
a problem um we can fix
8933
06:17:37,040 --> 06:17:43,000
it by changing those to rlock and R
8934
06:17:47,240 --> 06:17:49,440
unlock perfect looks good to me I'm
8935
06:17:49,440 --> 06:17:52,760
going to go ahead and submit that so a
8936
06:17:52,760 --> 06:17:55,120
quick review on read write mutexes how
8937
06:17:55,120 --> 06:17:57,840
many writers can access an RW mutex at
8938
06:17:57,840 --> 06:18:00,440
once or at the same time uh the answer
8939
06:18:00,440 --> 06:18:03,600
is one and how many readers can access
8940
06:18:03,600 --> 06:18:05,958
an RW mutex at once it's going to be
8941
06:18:05,958 --> 06:18:08,320
infinite there is no limit the next
8942
06:18:08,320 --> 06:18:10,360
question is can readers and writers use
8943
06:18:10,360 --> 06:18:13,840
RW mutexes at the same time the answer
8944
06:18:13,840 --> 06:18:16,400
is still no right no one can use the
8945
06:18:16,400 --> 06:18:19,478
mutex if it's being written to generics
8946
06:18:19,478 --> 06:18:21,798
are an amazing new feature in the go
8947
06:18:21,798 --> 06:18:24,040
programming language at least they are
8948
06:18:24,040 --> 06:18:26,240
new as of the time of this recording
8949
06:18:26,240 --> 06:18:28,680
we're on version 1.20 now and generics
8950
06:18:28,680 --> 06:18:31,320
were just released in 1.18 and they were
8951
06:18:31,320 --> 06:18:33,280
one of the most widely requested
8952
06:18:33,280 --> 06:18:36,400
features by go developers so let's talk
8953
06:18:36,400 --> 06:18:38,280
about what generics are and why they're
8954
06:18:38,280 --> 06:18:41,878
so useful let's take a look at this code
8955
06:18:41,878 --> 06:18:44,400
here we have a function called split in
8956
06:18:44,400 --> 06:18:46,878
slice so it takes a slice of ins and it
8957
06:18:46,878 --> 06:18:50,200
splits it into two smaller slices of
8958
06:18:50,200 --> 06:18:52,120
integers it effectively just splits the
8959
06:18:52,120 --> 06:18:56,160
slice in half and returns two new slices
8960
06:18:56,160 --> 06:18:57,718
the really interesting thing about this
8961
06:18:57,718 --> 06:18:59,000
function is that if you take a look at
8962
06:18:59,000 --> 06:19:01,680
the function body it doesn't actually
8963
06:19:01,680 --> 06:19:04,520
care that this is a slice of ins it
8964
06:19:04,520 --> 06:19:05,958
could be a slice of strings or a slice
8965
06:19:05,958 --> 06:19:07,760
of booleans the logic in the function
8966
06:19:07,760 --> 06:19:09,600
body would be the same right calculate
8967
06:19:09,600 --> 06:19:11,840
um kind of the midpoint of the slice and
8968
06:19:11,840 --> 06:19:14,080
return two new slices um with all the
8969
06:19:14,080 --> 06:19:17,200
values up to that midpoint the annoying
8970
06:19:17,200 --> 06:19:19,638
thing is that prior to generics in
8971
06:19:19,638 --> 06:19:22,360
version 1.18 if we wanted to split a
8972
06:19:22,360 --> 06:19:23,760
slice of strings we would actually need
8973
06:19:23,760 --> 06:19:26,840
to write an entirely separate function
8974
06:19:26,840 --> 06:19:29,440
because in go we have static typing and
8975
06:19:29,440 --> 06:19:32,040
we need to tell the compiler what type
8976
06:19:32,040 --> 06:19:35,280
of slice it is that we are splitting now
8977
06:19:35,280 --> 06:19:38,000
it is true that prior to generics you
8978
06:19:38,000 --> 06:19:40,080
could write a function that takes a
8979
06:19:40,080 --> 06:19:42,440
slice of the empty interface which is
8980
06:19:42,440 --> 06:19:44,400
essentially a slice of anything and then
8981
06:19:44,400 --> 06:19:47,400
returns to slices of the empty interface
8982
06:19:47,400 --> 06:19:49,080
the problem with that is that you need
8983
06:19:49,080 --> 06:19:52,040
to cast the return values back into
8984
06:19:52,040 --> 06:19:53,400
whatever they were which is kind of a
8985
06:19:53,400 --> 06:19:57,878
dangerous runtime check so generics or
8986
06:19:57,878 --> 06:20:00,400
type parameters are really just a way
8987
06:20:00,400 --> 06:20:02,080
for us to write that function with the
8988
06:20:02,080 --> 06:20:05,080
empty interface but do it in a compile
8989
06:20:05,080 --> 06:20:06,520
safe way because if you think about it
8990
06:20:06,520 --> 06:20:10,240
the compiler can know that this function
8991
06:20:10,240 --> 06:20:13,520
doesn't care about the types going in
8992
06:20:13,520 --> 06:20:16,000
but that anytime it's called the types
8993
06:20:16,000 --> 06:20:18,440
coming out will be the same as the types
8994
06:20:18,440 --> 06:20:21,240
coming in so how does it work well we
8995
06:20:21,240 --> 06:20:23,878
effectively have a new type of parameter
8996
06:20:23,878 --> 06:20:25,920
that can be passed into a function so
8997
06:20:25,920 --> 06:20:27,920
after the function's name we have these
8998
06:20:27,920 --> 06:20:30,200
optional square brackets and here we're
8999
06:20:30,200 --> 06:20:34,000
defining a new type we're calling it t
9000
06:20:34,000 --> 06:20:36,920
and we're saying it is of type any or it
9001
06:20:36,920 --> 06:20:41,400
can be anything now because we using T
9002
06:20:41,400 --> 06:20:44,280
the type parameter as both the input and
9003
06:20:44,280 --> 06:20:46,638
the output we're telling the go compiler
9004
06:20:46,638 --> 06:20:49,440
hey whatever I pass into this function
9005
06:20:49,440 --> 06:20:50,920
that's what I'm expecting to get back
9006
06:20:50,920 --> 06:20:52,558
out right if I pass in a slice of
9007
06:20:52,558 --> 06:20:55,638
integers I expect to get out two slices
9008
06:20:55,638 --> 06:20:58,240
of integers so now if we take a look at
9009
06:20:58,240 --> 06:21:01,120
how the code is actually used right how
9010
06:21:01,120 --> 06:21:03,120
the function is called we can use the
9011
06:21:03,120 --> 06:21:06,120
split any slice function give it a slice
9012
06:21:06,120 --> 06:21:08,638
of integers and we'll get back two
9013
06:21:08,638 --> 06:21:11,080
slices of integers everything is type
9014
06:21:11,080 --> 06:21:14,120
safe so in a nutshell the reason to use
9015
06:21:14,120 --> 06:21:17,160
generics is to dry up our code right dry
9016
06:21:17,160 --> 06:21:19,320
is just an acronym for don't repeat
9017
06:21:19,320 --> 06:21:21,120
yourself it's a way of writing code uh
9018
06:21:21,120 --> 06:21:23,638
that can be reused uh more easily so
9019
06:21:23,638 --> 06:21:25,520
instead of having to write two nearly
9020
06:21:25,520 --> 06:21:27,520
identical functions just to deal with
9021
06:21:27,520 --> 06:21:30,120
two separate types of slices we can now
9022
06:21:30,120 --> 06:21:33,200
write a typ safe function once and reuse
9023
06:21:33,200 --> 06:21:35,320
it throughout our application so let's
9024
06:21:35,320 --> 06:21:37,200
Jump Right In the assignment says at
9025
06:21:37,200 --> 06:21:39,240
maleo we often store all of the emails
9026
06:21:39,240 --> 06:21:41,680
of a given email campaign in memory as a
9027
06:21:41,680 --> 06:21:43,600
slice we store payments for a single
9028
06:21:43,600 --> 06:21:45,000
user in the same way so those are two
9029
06:21:45,000 --> 06:21:46,878
very different things right emails and
9030
06:21:46,878 --> 06:21:49,958
payments complete the get last function
9031
06:21:49,958 --> 06:21:51,478
it should be a generic function that
9032
06:21:51,478 --> 06:21:53,680
Returns the last element from a slice no
9033
06:21:53,680 --> 06:21:55,440
matter the type stored in the slice if
9034
06:21:55,440 --> 06:21:56,760
the slice is empty it should return the
9035
06:21:56,760 --> 06:21:58,718
zero value of the type okay cool let's
9036
06:21:58,718 --> 06:22:00,638
get started okay so we can kind of use
9037
06:22:00,638 --> 06:22:03,080
this syntax as a guide so we're going to
9038
06:22:03,080 --> 06:22:05,958
need um to specify type it can be
9039
06:22:05,958 --> 06:22:08,440
anything like the assignment said and
9040
06:22:08,440 --> 06:22:10,478
we're going to take as input a slice of
9041
06:22:10,478 --> 06:22:14,400
that type and return one element of that
9042
06:22:14,400 --> 06:22:17,520
type okay now it says um we need to
9043
06:22:17,520 --> 06:22:20,718
return the last element from a slice so
9044
06:22:20,718 --> 06:22:22,280
uh we need to slice the slice
9045
06:22:22,280 --> 06:22:23,878
essentially check its length right so we
9046
06:22:23,878 --> 06:22:29,920
can say um if the length of s is zero so
9047
06:22:29,920 --> 06:22:31,000
if there's nothing in the slice we're
9048
06:22:31,000 --> 06:22:32,840
going to have to just
9049
06:22:32,840 --> 06:22:38,160
return uh the m empty type of T which
9050
06:22:38,160 --> 06:22:40,200
down here it says we can create uh we
9051
06:22:40,200 --> 06:22:42,040
can create a new empty variable like
9052
06:22:42,040 --> 06:22:43,718
this so we'll just
9053
06:22:43,718 --> 06:22:45,958
do
9054
06:22:45,958 --> 06:22:50,160
bar zero Val and then we'll just return
9055
06:22:50,160 --> 06:22:52,320
it okay cool so if the slice is empty
9056
06:22:52,320 --> 06:22:55,638
we'll return the the zero value um
9057
06:22:55,638 --> 06:22:58,120
otherwise we'll
9058
06:22:58,120 --> 06:23:00,360
return S
9059
06:23:00,360 --> 06:23:05,400
at the length of s minus one right okay
9060
06:23:05,400 --> 06:23:07,240
so if there's nothing in the slice we'll
9061
06:23:07,240 --> 06:23:09,718
return the Z zero value otherwise we'll
9062
06:23:09,718 --> 06:23:11,878
return the element in the last index and
9063
06:23:11,878 --> 06:23:13,280
the reason we have to do this guard
9064
06:23:13,280 --> 06:23:14,760
Clause is because otherwise this would
9065
06:23:14,760 --> 06:23:16,878
be an unsafe operation we'd get an index
9066
06:23:16,878 --> 06:23:19,760
out of Bounce error uh if we tried to do
9067
06:23:19,760 --> 06:23:22,478
this operation on a slice of zero length
9068
06:23:22,478 --> 06:23:25,400
so let's go ahead and run
9069
06:23:25,400 --> 06:23:28,360
it and it looks
9070
06:23:28,360 --> 06:23:31,000
like okay so the test case with a zero
9071
06:23:31,000 --> 06:23:33,478
length slice returns an empty struct
9072
06:23:33,478 --> 06:23:35,638
that looks correct to me me getting last
9073
06:23:35,638 --> 06:23:38,040
email from a slice of length three
9074
06:23:38,040 --> 06:23:40,080
there's the last one looks like it
9075
06:23:40,080 --> 06:23:41,760
returned it correctly and then here we
9076
06:23:41,760 --> 06:23:43,280
have payments right so a completely
9077
06:23:43,280 --> 06:23:45,478
different type and the last one is Jane
9078
06:23:45,478 --> 06:23:48,080
example.com yep that looks correct to me
9079
06:23:48,080 --> 06:23:51,840
Margo Margo cool let's submit it so why
9080
06:23:51,840 --> 06:23:53,718
are there generics in the go programming
9081
06:23:53,718 --> 06:23:55,638
language well there's kind of three main
9082
06:23:55,638 --> 06:23:57,280
points that are important to understand
9083
06:23:57,280 --> 06:23:58,798
the first as we already covered is that
9084
06:23:58,798 --> 06:24:01,320
generics reduce repetitive code so
9085
06:24:01,320 --> 06:24:02,680
whenever we have code that doesn't
9086
06:24:02,680 --> 06:24:04,000
really care about the type or maybe it
9087
06:24:04,000 --> 06:24:06,600
only about a small superficial part of
9088
06:24:06,600 --> 06:24:09,360
the type then we can write more abstract
9089
06:24:09,360 --> 06:24:11,680
and more reusable code if we have access
9090
06:24:11,680 --> 06:24:13,718
to generics right because it keeps the
9091
06:24:13,718 --> 06:24:16,280
code compile time safe and type safe
9092
06:24:16,280 --> 06:24:18,240
before in go if we wanted to reuse code
9093
06:24:18,240 --> 06:24:20,680
we had to do sort of dangerous runtime
9094
06:24:20,680 --> 06:24:23,000
checking right casting things to empty
9095
06:24:23,000 --> 06:24:25,520
interfaces and back from empty
9096
06:24:25,520 --> 06:24:27,798
interfaces it's also important to
9097
06:24:27,798 --> 06:24:29,478
understand that generics are going to be
9098
06:24:29,478 --> 06:24:32,200
used much more frequently in libraries
9099
06:24:32,200 --> 06:24:34,718
and packages if you're say about backend
9100
06:24:34,718 --> 06:24:36,520
developer and you're building
9101
06:24:36,520 --> 06:24:38,958
applications um and not libraries or
9102
06:24:38,958 --> 06:24:40,320
packages that are intended to be used by
9103
06:24:40,320 --> 06:24:42,520
other people um You probably don't need
9104
06:24:42,520 --> 06:24:44,878
to use generics all that often which is
9105
06:24:44,878 --> 06:24:46,680
why the go programming language was able
9106
06:24:46,680 --> 06:24:48,400
to get away with not even supporting
9107
06:24:48,400 --> 06:24:51,440
them for so long now if you do work on
9108
06:24:51,440 --> 06:24:53,520
libraries or packages or maybe you're
9109
06:24:53,520 --> 06:24:55,878
even a contributor to the go standard
9110
06:24:55,878 --> 06:24:58,000
library then you probably are going to
9111
06:24:58,000 --> 06:25:00,320
use generics quite a bit more they'll
9112
06:25:00,320 --> 06:25:02,120
make it a lot easier to write more
9113
06:25:02,120 --> 06:25:04,320
abstract code that's useful uh for more
9114
06:25:04,320 --> 06:25:06,878
and more use cases the last Point that's
9115
06:25:06,878 --> 06:25:09,000
important to understand is just Why did
9116
06:25:09,000 --> 06:25:11,080
it take so long to get generics into the
9117
06:25:11,080 --> 06:25:13,718
language right they're super useful why
9118
06:25:13,718 --> 06:25:15,400
didn't we add them I don't know five
9119
06:25:15,400 --> 06:25:18,360
years ago or a decade ago and go was
9120
06:25:18,360 --> 06:25:20,718
kind of getting started the answer is
9121
06:25:20,718 --> 06:25:22,798
that one of the philosophies behind the
9122
06:25:22,798 --> 06:25:24,520
go programming language is just to kind
9123
06:25:24,520 --> 06:25:27,558
of keep it simple go doesn't have all
9124
06:25:27,558 --> 06:25:30,400
that many features because go developers
9125
06:25:30,400 --> 06:25:32,478
and go maintainers don't buy into the
9126
06:25:32,478 --> 06:25:34,718
idea that more features necessarily
9127
06:25:34,718 --> 06:25:36,840
makes a better programming language by
9128
06:25:36,840 --> 06:25:38,920
having fewer features it means there's
9129
06:25:38,920 --> 06:25:41,040
less to learn to get up and running with
9130
06:25:41,040 --> 06:25:42,718
the language it also means that anytime
9131
06:25:42,718 --> 06:25:44,478
you see a piece of go code you'll have
9132
06:25:44,478 --> 06:25:46,320
an easier time understanding it and
9133
06:25:46,320 --> 06:25:48,840
working with it so even more so than
9134
06:25:48,840 --> 06:25:50,798
other languages the go team is very
9135
06:25:50,798 --> 06:25:53,360
hesitant to add new stuff so generics
9136
06:25:53,360 --> 06:25:55,558
were in the works for a long time and it
9137
06:25:55,558 --> 06:25:58,000
was only after many years of thinking
9138
06:25:58,000 --> 06:25:59,400
about it and making sure that we really
9139
06:25:59,400 --> 06:26:01,200
needed them uh that they actually got
9140
06:26:01,200 --> 06:26:03,520
their way into the language so the
9141
06:26:03,520 --> 06:26:05,120
question here is is what code would
9142
06:26:05,120 --> 06:26:07,558
generics be most likely to help with a
9143
06:26:07,558 --> 06:26:09,920
binary tree detecting whether or not a
9144
06:26:09,920 --> 06:26:11,958
string contains a given substring or
9145
06:26:11,958 --> 06:26:16,120
calculating the area of a circle well
9146
06:26:16,120 --> 06:26:17,200
detecting whether or not a string
9147
06:26:17,200 --> 06:26:18,600
contains a substring we'll probably just
9148
06:26:18,600 --> 06:26:20,400
use string types and calculating the
9149
06:26:20,400 --> 06:26:22,040
area of a circle just sounds like floats
9150
06:26:22,040 --> 06:26:25,240
to me um but a binary tree is a data
9151
06:26:25,240 --> 06:26:26,958
structure that can store any type it's
9152
06:26:26,958 --> 06:26:28,878
kind of like you know a slice in that
9153
06:26:28,878 --> 06:26:30,478
way um so I'm going to go with binary
9154
06:26:30,478 --> 06:26:32,680
tree on that one the next question is
9155
06:26:32,680 --> 06:26:35,478
Go's approach to language design is to
9156
06:26:35,478 --> 06:26:37,040
support as many useful features as
9157
06:26:37,040 --> 06:26:39,200
possible to resist adding new features
9158
06:26:39,200 --> 06:26:40,878
until they're extremely important or
9159
06:26:40,878 --> 06:26:43,240
proven extremely important or to never
9160
06:26:43,240 --> 06:26:44,760
add new features the language doesn't
9161
06:26:44,760 --> 06:26:47,080
change um and the answer is to just
9162
06:26:47,080 --> 06:26:48,638
resist adding new features unless
9163
06:26:48,638 --> 06:26:51,040
they're proven to be very very important
9164
06:26:51,040 --> 06:26:52,680
the next question is generics will
9165
06:26:52,680 --> 06:26:55,400
probably be used more heavily in blank
9166
06:26:55,400 --> 06:26:57,320
main packages which are executable
9167
06:26:57,320 --> 06:27:00,080
applications or Library packages and I
9168
06:27:00,080 --> 06:27:01,320
definitely argue that they'll be more
9169
06:27:01,320 --> 06:27:04,000
heavily used in library packages okay so
9170
06:27:04,000 --> 06:27:05,558
we we talked about how generics are
9171
06:27:05,558 --> 06:27:08,080
super useful when the type that is being
9172
06:27:08,080 --> 06:27:10,080
used in your function doesn't matter
9173
06:27:10,080 --> 06:27:13,798
right when it can be anything but
9174
06:27:13,798 --> 06:27:16,760
constraints allow us to write generics
9175
06:27:16,760 --> 06:27:18,520
that are actually just useful for a
9176
06:27:18,520 --> 06:27:21,520
subset of types right so maybe this
9177
06:27:21,520 --> 06:27:23,840
function doesn't care too much about the
9178
06:27:23,840 --> 06:27:25,798
types that are being used but it does
9179
06:27:25,798 --> 06:27:28,240
care a little bit so let's take a look
9180
06:27:28,240 --> 06:27:32,040
at an example this concat function is
9181
06:27:32,040 --> 06:27:33,638
similar to the other generics that we've
9182
06:27:33,638 --> 06:27:34,680
worked with
9183
06:27:34,680 --> 06:27:36,520
the big difference is that the type T
9184
06:27:36,520 --> 06:27:38,478
the type parameter instead of being able
9185
06:27:38,478 --> 06:27:41,160
to be anything we're saying it has to be
9186
06:27:41,160 --> 06:27:43,200
a Stringer right and we've specified the
9187
06:27:43,200 --> 06:27:44,798
Stringer interface here it's just
9188
06:27:44,798 --> 06:27:47,080
anything with a string method on it that
9189
06:27:47,080 --> 06:27:50,200
returns a string with the builtin any
9190
06:27:50,200 --> 06:27:51,840
constraint which is effectively the
9191
06:27:51,840 --> 06:27:54,558
empty interface we can't really do
9192
06:27:54,558 --> 06:27:56,400
anything with the values inside the
9193
06:27:56,400 --> 06:27:57,680
functions right which is why it works
9194
06:27:57,680 --> 06:27:58,920
for something where we're just say
9195
06:27:58,920 --> 06:28:02,160
splitting a slice of that type but in
9196
06:28:02,160 --> 06:28:04,120
this function the concat function where
9197
06:28:04,120 --> 06:28:06,680
we're actually able to use the type a
9198
06:28:06,680 --> 06:28:10,600
little bit we're able to call the method
9199
06:28:10,600 --> 06:28:12,958
that's implemented on it and that's just
9200
06:28:12,958 --> 06:28:14,798
because the only thing that we know
9201
06:28:14,798 --> 06:28:16,240
about these values coming into the
9202
06:28:16,240 --> 06:28:18,280
function is that they have that string
9203
06:28:18,280 --> 06:28:20,760
method so what does the concat function
9204
06:28:20,760 --> 06:28:23,958
do well it takes a slice of
9205
06:28:23,958 --> 06:28:27,520
stringers it Loops over all of them
9206
06:28:27,520 --> 06:28:29,920
grabs the string representation right by
9207
06:28:29,920 --> 06:28:31,878
calling that string method the string
9208
06:28:31,878 --> 06:28:33,600
representation of each value and then
9209
06:28:33,600 --> 06:28:35,478
kind of just mashes them all together
9210
06:28:35,478 --> 06:28:37,878
right it concatenates them and Returns
9211
06:28:37,878 --> 06:28:40,360
the result so let's take a look at the
9212
06:28:40,360 --> 06:28:42,320
assignment we have different kinds of
9213
06:28:42,320 --> 06:28:43,920
line items that we can charge our
9214
06:28:43,920 --> 06:28:45,718
customers credit cards for line items
9215
06:28:45,718 --> 06:28:47,558
can be things like subscriptions one or
9216
06:28:47,558 --> 06:28:50,200
onetime payments great complete the
9217
06:28:50,200 --> 06:28:52,680
charge for line item function first it
9218
06:28:52,680 --> 06:28:54,280
should check if the user has a balance
9219
06:28:54,280 --> 06:28:55,798
with enough funds to be able to pay for
9220
06:28:55,798 --> 06:28:58,798
the cost of a new item okay so we're
9221
06:28:58,798 --> 06:29:01,200
given a new item which is of type T
9222
06:29:01,200 --> 06:29:04,120
given a slice of old items and a balance
9223
06:29:04,120 --> 06:29:07,160
is just a float um if they don't have
9224
06:29:07,160 --> 06:29:08,920
enough funds then we'll return an
9225
06:29:08,920 --> 06:29:11,478
insufficient funds error but if they do
9226
06:29:11,478 --> 06:29:13,280
have enough funds then we'll add the
9227
06:29:13,280 --> 06:29:14,878
line item to the user's history by
9228
06:29:14,878 --> 06:29:16,520
appending new item to the slice of old
9229
06:29:16,520 --> 06:29:19,240
old items okay this new slice is your
9230
06:29:19,240 --> 06:29:20,840
first return value right so we're
9231
06:29:20,840 --> 06:29:22,760
returning three values here so we're
9232
06:29:22,760 --> 06:29:25,320
returning kind of the new list of old
9233
06:29:25,320 --> 06:29:28,040
items after new item has been
9234
06:29:28,040 --> 06:29:30,718
appended um and we need to calculate the
9235
06:29:30,718 --> 06:29:32,718
user's New Balance by subtracting the
9236
06:29:32,718 --> 06:29:34,160
cost of the new item from their their
9237
06:29:34,160 --> 06:29:35,840
balance this is my second return value
9238
06:29:35,840 --> 06:29:37,840
Okay cool so we Tak in their balance
9239
06:29:37,840 --> 06:29:39,718
we're going to subtract the cost of the
9240
06:29:39,718 --> 06:29:42,760
new item and then return the New Balance
9241
06:29:42,760 --> 06:29:44,440
um and obviously if nothing went wrong
9242
06:29:44,440 --> 06:29:48,200
we'll return a nil error okay so we have
9243
06:29:48,200 --> 06:29:52,360
the type here as a line item so line
9244
06:29:52,360 --> 06:29:54,040
item is this interface and it looks like
9245
06:29:54,040 --> 06:29:55,718
we we kind of have these two methods
9246
06:29:55,718 --> 06:29:57,638
available to us um within our function
9247
06:29:57,638 --> 06:29:59,680
we can get the cost of a line item or we
9248
06:29:59,680 --> 06:30:02,600
can get the name of a line item so the
9249
06:30:02,600 --> 06:30:03,760
first thing our function is supposed to
9250
06:30:03,760 --> 06:30:05,760
do is check if the user has a balance
9251
06:30:05,760 --> 06:30:07,760
with enough funds so we need to do
9252
06:30:07,760 --> 06:30:12,440
something like uh new new
9253
06:30:12,440 --> 06:30:15,440
balance is equal
9254
06:30:15,440 --> 06:30:17,520
to
9255
06:30:17,520 --> 06:30:19,160
balance
9256
06:30:19,160 --> 06:30:21,718
minus the new
9257
06:30:21,718 --> 06:30:25,400
item. get cost right so we're going to
9258
06:30:25,400 --> 06:30:27,240
check what the New Balance would be
9259
06:30:27,240 --> 06:30:29,280
after subtracting the cost of the item
9260
06:30:29,280 --> 06:30:31,760
from the user's balance then we can say
9261
06:30:31,760 --> 06:30:35,080
if the new balance
9262
06:30:35,080 --> 06:30:37,478
it's less than
9263
06:30:37,478 --> 06:30:40,878
zero then we'll return this insufficient
9264
06:30:40,878 --> 06:30:43,478
funds error right and zero values for
9265
06:30:43,478 --> 06:30:46,958
everything else so it'll be uh nil slice
9266
06:30:46,958 --> 06:30:49,200
0.0 float
9267
06:30:49,200 --> 06:30:53,280
and errors. new insufficient
9268
06:30:53,280 --> 06:30:55,920
funds we'll need the errors
9269
06:30:55,920 --> 06:30:58,680
package okay cool otherwise that means
9270
06:30:58,680 --> 06:31:02,120
this uh this balance is uh zero or
9271
06:31:02,120 --> 06:31:04,478
greater right
9272
06:31:04,478 --> 06:31:07,200
um and it says add the line item to the
9273
06:31:07,200 --> 06:31:08,600
user's history by appending it to the
9274
06:31:08,600 --> 06:31:11,558
slice of old items so we could do old
9275
06:31:11,558 --> 06:31:17,398
items equals append old items new
9276
06:31:17,398 --> 06:31:20,958
item okay this new slice is your first
9277
06:31:20,958 --> 06:31:23,000
return value
9278
06:31:23,000 --> 06:31:25,638
great otherwi um and then calculate the
9279
06:31:25,638 --> 06:31:27,040
the user's New Balance by subtracting
9280
06:31:27,040 --> 06:31:28,240
the cost of the new item from their
9281
06:31:28,240 --> 06:31:30,878
balance so we already did that um this
9282
06:31:30,878 --> 06:31:32,000
is your second return value so I think
9283
06:31:32,000 --> 06:31:34,840
we could just return
9284
06:31:34,840 --> 06:31:39,200
um old items New
9285
06:31:39,200 --> 06:31:42,160
Balance and
9286
06:31:42,160 --> 06:31:47,320
nil right let's go ahead and run
9287
06:31:47,920 --> 06:31:50,520
that okay charging customer for a yearly
9288
06:31:50,520 --> 06:31:52,840
subscription current balance is 1,000
9289
06:31:52,840 --> 06:31:55,600
new balance is 750 total number of line
9290
06:31:55,600 --> 06:31:56,878
items is now
9291
06:31:56,878 --> 06:31:59,080
one for monthly
9292
06:31:59,080 --> 06:32:02,040
subscription new balance is less total
9293
06:32:02,040 --> 06:32:04,360
number of line items is now three let's
9294
06:32:04,360 --> 06:32:06,718
go take a look at those test cases just
9295
06:32:06,718 --> 06:32:10,398
to make sure that this makes
9296
06:32:10,478 --> 06:32:13,040
sense okay so they had zero now they
9297
06:32:13,040 --> 06:32:14,440
have one
9298
06:32:14,440 --> 06:32:16,558
subscription here they had two
9299
06:32:16,558 --> 06:32:19,120
subscriptions now they have three
9300
06:32:19,120 --> 06:32:21,280
subscriptions cool that looks or or
9301
06:32:21,280 --> 06:32:22,638
three L items that looks good to me I'm
9302
06:32:22,638 --> 06:32:24,160
going to go ahead and submit it when
9303
06:32:24,160 --> 06:32:26,398
generics were released a new syntax for
9304
06:32:26,398 --> 06:32:29,558
writing interfaces was also released um
9305
06:32:29,558 --> 06:32:31,478
partly just because this new syntax is
9306
06:32:31,478 --> 06:32:33,478
super useful if you're trying to use
9307
06:32:33,478 --> 06:32:35,680
interface faes as constraints for your
9308
06:32:35,680 --> 06:32:37,798
generic functions so let's take a look
9309
06:32:37,798 --> 06:32:40,240
at an example um a typ list is pretty
9310
06:32:40,240 --> 06:32:41,558
much as simple as it sounds we're
9311
06:32:41,558 --> 06:32:43,040
basically just creating a new interface
9312
06:32:43,040 --> 06:32:44,920
in this case we're calling it ordered
9313
06:32:44,920 --> 06:32:46,600
and then we're just listing all of the
9314
06:32:46,600 --> 06:32:49,520
types that we're saying Implement that
9315
06:32:49,520 --> 06:32:52,958
interface so there's no methods here but
9316
06:32:52,958 --> 06:32:54,558
the interesting thing about all of these
9317
06:32:54,558 --> 06:32:56,958
types is that they all support these
9318
06:32:56,958 --> 06:32:59,200
inequality operators like less than less
9319
06:32:59,200 --> 06:33:01,558
than or equal to greater than and so if
9320
06:33:01,558 --> 06:33:04,840
we use ordered as a cons straint then
9321
06:33:04,840 --> 06:33:07,520
we're free to use these comparison
9322
06:33:07,520 --> 06:33:11,240
operators on that type and the question
9323
06:33:11,240 --> 06:33:12,600
that goes along with this is why might
9324
06:33:12,600 --> 06:33:14,280
you create an interface using a type
9325
06:33:14,280 --> 06:33:16,440
list and the answers are you know
9326
06:33:16,440 --> 06:33:18,000
exactly which type satisfy your
9327
06:33:18,000 --> 06:33:19,878
interface or it's too much trouble to
9328
06:33:19,878 --> 06:33:21,080
define the methods required by your
9329
06:33:21,080 --> 06:33:23,120
interface um that second one is a bad
9330
06:33:23,120 --> 06:33:25,360
reason uh it's you would really only do
9331
06:33:25,360 --> 06:33:27,240
this if you know exactly which types
9332
06:33:27,240 --> 06:33:29,280
satisfy your interface let's take a look
9333
06:33:29,280 --> 06:33:31,760
at parametric constraints which sounds
9334
06:33:31,760 --> 06:33:34,040
like a kind of complex term but it's
9335
06:33:34,040 --> 06:33:35,680
actually really simple it basically just
9336
06:33:35,680 --> 06:33:39,240
means that we can use type parameters in
9337
06:33:39,240 --> 06:33:42,040
interface definitions as well so instead
9338
06:33:42,040 --> 06:33:43,840
of just creating interfaces which we
9339
06:33:43,840 --> 06:33:46,360
then use in our type parameters for
9340
06:33:46,360 --> 06:33:49,000
functions we're actually using type
9341
06:33:49,000 --> 06:33:52,558
parameters to Define new interfaces so
9342
06:33:52,558 --> 06:33:55,680
for example here we have a
9343
06:33:55,680 --> 06:33:59,600
store that takes as a type parameter P
9344
06:33:59,600 --> 06:34:02,200
which is a product now a product is just
9345
06:34:02,200 --> 06:34:04,638
an interface right um it's a product is
9346
06:34:04,638 --> 06:34:07,160
anything that can return a price and a
9347
06:34:07,160 --> 06:34:10,120
name so a store which is again an
9348
06:34:10,120 --> 06:34:13,320
interface is just anything that can sell
9349
06:34:13,320 --> 06:34:16,120
a product now the idea really is that
9350
06:34:16,120 --> 06:34:18,080
simple if you want to get an idea for
9351
06:34:18,080 --> 06:34:20,558
kind of how this whole uh snippet of
9352
06:34:20,558 --> 06:34:22,680
code works the example code I'm not
9353
06:34:22,680 --> 06:34:24,000
going to talk through every line that
9354
06:34:24,000 --> 06:34:25,360
would take a little bit too long but
9355
06:34:25,360 --> 06:34:26,878
feel free to kind of browse through this
9356
06:34:26,878 --> 06:34:29,718
and get a feel for how um that interface
9357
06:34:29,718 --> 06:34:31,680
Works we're going to jump straight into
9358
06:34:31,680 --> 06:34:33,398
the assignment so getting on to the
9359
06:34:33,398 --> 06:34:35,280
assign assment says the Chief Architect
9360
06:34:35,280 --> 06:34:36,920
at maleo has decided she wants us to
9361
06:34:36,920 --> 06:34:38,600
implement billing with generics
9362
06:34:38,600 --> 06:34:39,760
specifically she wants us to create a
9363
06:34:39,760 --> 06:34:41,718
new biller interface a biller is an
9364
06:34:41,718 --> 06:34:43,398
interface that can be used to charge a
9365
06:34:43,398 --> 06:34:45,478
customer and it can also report its name
9366
06:34:45,478 --> 06:34:46,440
okay so let's take a look at what a
9367
06:34:46,440 --> 06:34:49,320
customer is so a customer is this
9368
06:34:49,320 --> 06:34:51,398
interface it's just anything that has a
9369
06:34:51,398 --> 06:34:54,920
get billing email method on it so in
9370
06:34:54,920 --> 06:34:58,000
this case a user is a customer and an
9371
06:34:58,000 --> 06:35:01,440
org is a customer
9372
06:35:01,440 --> 06:35:05,360
okay um and it can also report its name
9373
06:35:05,360 --> 06:35:08,320
okay that's simple enough um there are
9374
06:35:08,320 --> 06:35:09,958
two kinds of billers user billers and
9375
06:35:09,958 --> 06:35:11,958
org billers Okay so we've got user
9376
06:35:11,958 --> 06:35:15,760
biller here and org biller
9377
06:35:15,760 --> 06:35:18,000
here create the new biller interface it
9378
06:35:18,000 --> 06:35:19,200
should have two methods okay so let's go
9379
06:35:19,200 --> 06:35:21,558
ahead and do that
9380
06:35:21,558 --> 06:35:23,240
type
9381
06:35:23,240 --> 06:35:24,760
biller
9382
06:35:24,760 --> 06:35:29,360
interface two methods charge and
9383
06:35:29,360 --> 06:35:31,478
name the good news is the architect
9384
06:35:31,478 --> 06:35:33,120
already wrote the user biller and org
9385
06:35:33,120 --> 06:35:35,240
biller type for us that fill this new B
9386
06:35:35,240 --> 06:35:38,200
interface right we took a look at
9387
06:35:38,200 --> 06:35:40,558
that use the definitions of the types
9388
06:35:40,558 --> 06:35:41,760
and their methods to figure out how to
9389
06:35:41,760 --> 06:35:43,600
write the biller interface on line 7
9390
06:35:43,600 --> 06:35:46,638
Okay cool so let's start with name it
9391
06:35:46,638 --> 06:35:49,200
looks simpler so a user biller um has a
9392
06:35:49,200 --> 06:35:50,798
name method it takes no parameters and
9393
06:35:50,798 --> 06:35:52,600
returns a string uh same with the or
9394
06:35:52,600 --> 06:35:54,920
biller so that one's simple it just
9395
06:35:54,920 --> 06:35:56,120
returns a
9396
06:35:56,120 --> 06:35:58,798
string okay the charge method for user
9397
06:35:58,798 --> 06:36:01,478
biller accepts a user returns a
9398
06:36:01,478 --> 06:36:04,040
bill but for the org Biller accepts an
9399
06:36:04,040 --> 06:36:06,520
org and returns a bill okay so it always
9400
06:36:06,520 --> 06:36:09,360
returns a bill that part's easy but what
9401
06:36:09,360 --> 06:36:12,958
it accepts is a little bit
9402
06:36:12,958 --> 06:36:15,920
different right and if we take a look
9403
06:36:15,920 --> 06:36:18,718
at the customer interface where did it
9404
06:36:18,718 --> 06:36:22,680
go customer interface here then we see
9405
06:36:22,680 --> 06:36:26,440
that we have
9406
06:36:26,440 --> 06:36:28,958
um we have this common interface that we
9407
06:36:28,958 --> 06:36:32,798
can use to represent both a user and an
9408
06:36:32,798 --> 06:36:34,520
orc
9409
06:36:34,520 --> 06:36:36,040
okay so that's convenient because we can
9410
06:36:36,040 --> 06:36:38,558
use that interface right as a parametric
9411
06:36:38,558 --> 06:36:44,558
uh constraint so let's create a new uh
9412
06:36:44,558 --> 06:36:48,680
parametric type or you know but a we'll
9413
06:36:48,680 --> 06:36:51,240
create a new type
9414
06:36:51,240 --> 06:36:54,040
parameter call it C because it's a
9415
06:36:54,040 --> 06:36:56,878
customer should be easy enough and then
9416
06:36:56,878 --> 06:37:01,200
charge will actually take as input
9417
06:37:01,200 --> 06:37:04,120
C right it will take a customer
9418
06:37:04,120 --> 06:37:07,360
rather than specifically a user or an
9419
06:37:07,360 --> 06:37:11,040
org okay let's try
9420
06:37:11,398 --> 06:37:13,878
that it compiled at least let's see what
9421
06:37:13,878 --> 06:37:16,280
we got using basic user biller to create
9422
06:37:16,280 --> 06:37:18,600
a bill for Joe example.com
9423
06:37:18,600 --> 06:37:22,958
$50 basic user biller for Samuel bogs
9424
06:37:22,958 --> 06:37:27,160
$50 Pro user biller for Jade
9425
06:37:27,160 --> 06:37:29,440
$100 okay that's looking correct to me
9426
06:37:29,440 --> 06:37:32,878
it looks like the pro uh Pro and basic
9427
06:37:32,878 --> 06:37:35,120
uh have a discrepancy of $50 and $100
9428
06:37:35,120 --> 06:37:37,398
and then the org biller is being used
9429
06:37:37,398 --> 06:37:39,638
here you can see it's actually much more
9430
06:37:39,638 --> 06:37:42,160
expensive so that looks correct to me so
9431
06:37:42,160 --> 06:37:44,680
let's talk about naming generic types uh
9432
06:37:44,680 --> 06:37:46,440
we can take a look at this old example
9433
06:37:46,440 --> 06:37:47,878
or the example from earlier in the
9434
06:37:47,878 --> 06:37:50,200
course where we had to split any slice
9435
06:37:50,200 --> 06:37:52,760
right and it has t as a type parameter
9436
06:37:52,760 --> 06:37:55,718
um of type any and then we use T um kind
9437
06:37:55,718 --> 06:37:57,718
of all throughout the function signature
9438
06:37:57,718 --> 06:37:59,958
um T is just a variable name it doesn't
9439
06:37:59,958 --> 06:38:01,718
we don't have to use T there we could
9440
06:38:01,718 --> 06:38:03,718
name we could name this whatever we want
9441
06:38:03,718 --> 06:38:07,000
right we could name it my type uh
9442
06:38:07,000 --> 06:38:09,520
whatever the heck we want right uh slice
9443
06:38:09,520 --> 06:38:12,680
value it doesn't matter um however it
9444
06:38:12,680 --> 06:38:14,840
turns out that capital t is actually
9445
06:38:14,840 --> 06:38:17,878
fairly common convention um when there
9446
06:38:17,878 --> 06:38:20,440
is just a single type parameter for a
9447
06:38:20,440 --> 06:38:22,520
function so the question here is the
9448
06:38:22,520 --> 06:38:25,958
name of a type parameter blank can and
9449
06:38:25,958 --> 06:38:27,958
should be whatever you want can be
9450
06:38:27,958 --> 06:38:30,520
anything but T is a common convention or
9451
06:38:30,520 --> 06:38:32,958
must be t uh it turns out it can be
9452
06:38:32,958 --> 06:38:34,760
anything but but T is a fairly common
9453
06:38:34,760 --> 06:38:37,398
conventional name Rob Pike one of the
9454
06:38:37,398 --> 06:38:39,280
creators of the go programming language
9455
06:38:39,280 --> 06:38:42,120
created an awesome set of Proverbs that
9456
06:38:42,120 --> 06:38:44,440
outlines some more of the philosophies
9457
06:38:44,440 --> 06:38:46,440
behind the language I'm not going to
9458
06:38:46,440 --> 06:38:48,120
read them all to you but I am going to
9459
06:38:48,120 --> 06:38:50,360
cover some of the ones that I think are
9460
06:38:50,360 --> 06:38:52,398
the most important and if you are
9461
06:38:52,398 --> 06:38:54,360
interested I'd highly recommend going
9462
06:38:54,360 --> 06:38:57,160
and watching his talk about the Proverbs
9463
06:38:57,160 --> 06:38:58,958
uh if if you want to go more in depth on
9464
06:38:58,958 --> 06:39:01,280
them so let's start at the top don't
9465
06:39:01,280 --> 06:39:03,840
communicate by sharing memory share
9466
06:39:03,840 --> 06:39:06,840
memory by communicating so this
9467
06:39:06,840 --> 06:39:08,360
basically is telling us we should
9468
06:39:08,360 --> 06:39:11,878
probably try to use channels more often
9469
06:39:11,878 --> 06:39:13,798
than we use mutexes when we're trying to
9470
06:39:13,798 --> 06:39:17,040
share memory between go routines which
9471
06:39:17,040 --> 06:39:19,760
leads right into the third one which is
9472
06:39:19,760 --> 06:39:23,000
channels orchestrate and mutexes
9473
06:39:23,000 --> 06:39:26,398
serialize so when we use channels we get
9474
06:39:26,398 --> 06:39:28,680
kind of this elegant flow of data
9475
06:39:28,680 --> 06:39:31,240
through our program right one go routine
9476
06:39:31,240 --> 06:39:33,440
did something another go routine can
9477
06:39:33,440 --> 06:39:35,920
react to it mutexes are all about just
9478
06:39:35,920 --> 06:39:38,638
locking access to protected resources if
9479
06:39:38,638 --> 06:39:41,080
we can use channels to express logic in
9480
06:39:41,080 --> 06:39:43,638
our program it will tend to work a
9481
06:39:43,638 --> 06:39:45,680
little bit better another great one is
9482
06:39:45,680 --> 06:39:49,200
that the empty interface says nothing
9483
06:39:49,200 --> 06:39:52,080
right every type in go fulfills the
9484
06:39:52,080 --> 06:39:54,240
empty interface you should really avoid
9485
06:39:54,240 --> 06:39:56,600
using the empty interface just because
9486
06:39:56,600 --> 06:39:58,760
it doesn't tell you anything interesting
9487
06:39:58,760 --> 06:40:01,718
about your types the empty interface is
9488
06:40:01,718 --> 06:40:03,920
sometimes used by new go Developers to
9489
06:40:03,920 --> 06:40:06,320
kind of get around the type system and
9490
06:40:06,320 --> 06:40:09,160
that just leads to unsafe code go format
9491
06:40:09,160 --> 06:40:11,718
style is no one's favorite and yet go
9492
06:40:11,718 --> 06:40:14,000
format style is everyone's favorite so
9493
06:40:14,000 --> 06:40:15,840
we'll get into this in just a bit when
9494
06:40:15,840 --> 06:40:18,080
we jump into the project but the go tool
9495
06:40:18,080 --> 06:40:20,320
chain comes with its own formatter and
9496
06:40:20,320 --> 06:40:22,320
pretty much every production piece of go
9497
06:40:22,320 --> 06:40:25,398
code out there uses the same formatter
9498
06:40:25,398 --> 06:40:27,280
which is fantastic because it means all
9499
06:40:27,280 --> 06:40:30,680
go code looks the same while not
9500
06:40:30,680 --> 06:40:33,360
everyone necessarily agrees on the form
9501
06:40:33,360 --> 06:40:36,360
matters choice of say tabs versus spaces
9502
06:40:36,360 --> 06:40:38,398
it's still everyone's favorite because
9503
06:40:38,398 --> 06:40:40,558
it means we all get something consistent
9504
06:40:40,558 --> 06:40:42,958
that works reasonably well the next one
9505
06:40:42,958 --> 06:40:45,000
is one of my favorites it's a little
9506
06:40:45,000 --> 06:40:46,478
copying is better than a little
9507
06:40:46,478 --> 06:40:48,320
dependency now if you've ever worked in
9508
06:40:48,320 --> 06:40:50,440
the JavaScript ecosystem with node
9509
06:40:50,440 --> 06:40:52,240
modules you'll know exactly what this
9510
06:40:52,240 --> 06:40:54,840
means node modules is typically a huge
9511
06:40:54,840 --> 06:40:56,718
folder and a lot of times when you're
9512
06:40:56,718 --> 06:40:59,040
working on a front-end framework your
9513
06:40:59,040 --> 06:41:01,558
dependencies are much greater than your
9514
06:41:01,558 --> 06:41:04,160
actual application code and in go we
9515
06:41:04,160 --> 06:41:06,160
typically just kind of invert that way
9516
06:41:06,160 --> 06:41:08,718
of thinking we want our application code
9517
06:41:08,718 --> 06:41:11,398
to be the bulk of the code within our
9518
06:41:11,398 --> 06:41:13,680
project and we tend to use far fewer
9519
06:41:13,680 --> 06:41:16,878
dependencies as almost a philosophy and
9520
06:41:16,878 --> 06:41:19,478
this brings us to the one uh mentioned
9521
06:41:19,478 --> 06:41:21,558
here in the question which says which is
9522
06:41:21,558 --> 06:41:23,718
better clear or clever and at least
9523
06:41:23,718 --> 06:41:27,000
according to rag Pike clear is better
9524
06:41:27,000 --> 06:41:29,638
than clever so if you can write your
9525
06:41:29,638 --> 06:41:31,718
code in a way that is very clear to
9526
06:41:31,718 --> 06:41:33,440
anyone else reading it or even just to
9527
06:41:33,440 --> 06:41:35,280
yourself that's better than trying to do
9528
06:41:35,280 --> 06:41:37,478
a trick that might seem clever but is
9529
06:41:37,478 --> 06:41:39,638
actually hard for humans to understand
9530
06:41:39,638 --> 06:41:42,240
remember code is written for humans not
9531
06:41:42,240 --> 06:41:43,958
for
9532
06:41:43,958 --> 06:41:46,000
machines the next question is which is
9533
06:41:46,000 --> 06:41:48,280
better copying a little code or
9534
06:41:48,280 --> 06:41:51,160
including a small dependency and Rob
9535
06:41:51,160 --> 06:41:53,000
Pike would argue that it's typically
9536
06:41:53,000 --> 06:41:55,398
better to copy a little bit of code
9537
06:41:55,398 --> 06:41:57,040
rather than include a very small
9538
06:41:57,040 --> 06:41:59,280
dependency in your project the next one
9539
06:41:59,280 --> 06:42:01,360
I want to point out is that errors are
9540
06:42:01,360 --> 06:42:04,520
just values right and go error is just a
9541
06:42:04,520 --> 06:42:06,440
specific interface and we return it from
9542
06:42:06,440 --> 06:42:08,080
functions just like we do any other
9543
06:42:08,080 --> 06:42:10,440
value there's not some special way to
9544
06:42:10,440 --> 06:42:12,558
handle errors with tries and catches
9545
06:42:12,558 --> 06:42:14,718
errors are just values and we deal with
9546
06:42:14,718 --> 06:42:18,320
them just like we would any other
9547
06:42:20,000 --> 06:42:22,398
value the last one I want to point out
9548
06:42:22,398 --> 06:42:25,440
is that documentation is for users this
9549
06:42:25,440 --> 06:42:27,478
is actually an interesting one I think
9550
06:42:27,478 --> 06:42:30,320
what he's saying here and I I need to go
9551
06:42:30,320 --> 06:42:33,160
rewatch The talk to confirm but that
9552
06:42:33,160 --> 06:42:34,798
documentation is primarily for people
9553
06:42:34,798 --> 06:42:36,958
who aren't maintaining the code in other
9554
06:42:36,958 --> 06:42:39,718
words it's best if the code itself is
9555
06:42:39,718 --> 06:42:41,478
really easy to understand so it doesn't
9556
06:42:41,478 --> 06:42:43,680
need to be heavily documented so that
9557
06:42:43,680 --> 06:42:46,000
other maintainers can work on it right
9558
06:42:46,000 --> 06:42:48,120
um documentation in the sense that you
9559
06:42:48,120 --> 06:42:49,680
know we should be writing external
9560
06:42:49,680 --> 06:42:51,440
documents that explain how the code work
9561
06:42:51,440 --> 06:42:53,280
or or how to use it should be for the
9562
06:42:53,280 --> 06:42:55,878
users of our code right in the sense
9563
06:42:55,878 --> 06:42:57,760
that if we're writing a library we
9564
06:42:57,760 --> 06:42:59,440
should be writing documentation for the
9565
06:42:59,440 --> 06:43:02,478
users of the library um the developers
9566
06:43:02,478 --> 06:43:05,280
calling our exported functions right not
9567
06:43:05,280 --> 06:43:08,718
the maintainers of the library itself so
9568
06:43:08,718 --> 06:43:10,040
documentation should primarily be
9569
06:43:10,040 --> 06:43:12,920
written for the users of your code it's
9570
06:43:12,920 --> 06:43:15,440
time to build a fully fledged backend
9571
06:43:15,440 --> 06:43:18,000
server Ino from scratch on our local
9572
06:43:18,000 --> 06:43:20,280
machines the purpose of the server will
9573
06:43:20,280 --> 06:43:22,958
be to aggregate data from RSS feeds if
9574
06:43:22,958 --> 06:43:24,558
you're not familiar with RSS it's a
9575
06:43:24,558 --> 06:43:26,360
protocol that makes Distributing things
9576
06:43:26,360 --> 06:43:29,000
like podcast and blog posts really easy
9577
06:43:29,000 --> 06:43:30,958
so what our server will allow users to
9578
06:43:30,958 --> 06:43:34,160
do is add different RSS feeds to its
9579
06:43:34,160 --> 06:43:35,878
database and then it will go
9580
06:43:35,878 --> 06:43:38,558
automatically collect all of the posts
9581
06:43:38,558 --> 06:43:40,840
from those feeds and download them and
9582
06:43:40,840 --> 06:43:42,638
save them in the database so that we can
9583
06:43:42,638 --> 06:43:45,080
then view them later before we get
9584
06:43:45,080 --> 06:43:47,320
started there are four things you're
9585
06:43:47,320 --> 06:43:50,798
going to need the first is a basic
9586
06:43:50,798 --> 06:43:53,080
understanding of SQL the language that's
9587
06:43:53,080 --> 06:43:54,958
most often used to query relational
9588
06:43:54,958 --> 06:43:56,718
databases if you're not familiar with
9589
06:43:56,718 --> 06:43:59,320
SQL yet that's okay I've got a full
9590
06:43:59,320 --> 06:44:01,478
course on SQL I'll link that down in the
9591
06:44:01,478 --> 06:44:03,280
description below go watch that then
9592
06:44:03,280 --> 06:44:04,920
come back here if you're not familiar
9593
06:44:04,920 --> 06:44:07,280
with SQL number two is you're going to
9594
06:44:07,280 --> 06:44:09,520
need a text editor and a command line
9595
06:44:09,520 --> 06:44:12,440
I'm using vs code and zsh uh here in the
9596
06:44:12,440 --> 06:44:14,080
video so you'll see me using that uh
9597
06:44:14,080 --> 06:44:16,280
feel free to go download those if uh you
9598
06:44:16,280 --> 06:44:17,840
want to try them out but you can use
9599
06:44:17,840 --> 06:44:19,920
whatever text editor you want as long as
9600
06:44:19,920 --> 06:44:21,958
it can edit your files and you have
9601
06:44:21,958 --> 06:44:24,600
access to a terminal to run commands
9602
06:44:24,600 --> 06:44:26,558
number three is the go programming
9603
06:44:26,558 --> 06:44:28,200
language itself if you don't have that
9604
06:44:28,200 --> 06:44:30,240
you can go download it I will link uh
9605
06:44:30,240 --> 06:44:31,638
the download page down in the
9606
06:44:31,638 --> 06:44:33,040
description below and I'd also recom
9607
06:44:33,040 --> 06:44:36,080
recommend just installing the go plugin
9608
06:44:36,080 --> 06:44:37,520
um if you're in VSS code there is an
9609
06:44:37,520 --> 06:44:39,600
official go plugin Go download that
9610
06:44:39,600 --> 06:44:41,360
it'll make your life easier with syntax
9611
06:44:41,360 --> 06:44:42,920
highlighting and formatting and that
9612
06:44:42,920 --> 06:44:45,240
sort of thing number four the last thing
9613
06:44:45,240 --> 06:44:49,080
you'll need is an HTTP client so an HTTP
9614
06:44:49,080 --> 06:44:50,958
client will allow you to make get and
9615
06:44:50,958 --> 06:44:53,600
post and put requests into the web
9616
06:44:53,600 --> 06:44:55,558
server that we're building we'll need
9617
06:44:55,558 --> 06:44:57,558
that for testing I use the Thunder
9618
06:44:57,558 --> 06:45:00,000
client it's a vs code extension but you
9619
06:45:00,000 --> 06:45:01,718
can use anything you like even curl on
9620
06:45:01,718 --> 06:45:03,840
the command line or post and insomnia
9621
06:45:03,840 --> 06:45:06,120
there's tons of choices Google HTTP
9622
06:45:06,120 --> 06:45:07,958
clients um or if you don't already have
9623
06:45:07,958 --> 06:45:10,320
a preference again if you're in vs code
9624
06:45:10,320 --> 06:45:12,080
I'd recommend the Thunder client
9625
06:45:12,080 --> 06:45:14,398
extension now that you have all of those
9626
06:45:14,398 --> 06:45:16,840
tools installed and hopefully working
9627
06:45:16,840 --> 06:45:18,478
let's jump into the project the first
9628
06:45:18,478 --> 06:45:19,840
thing we're going to need is just a
9629
06:45:19,840 --> 06:45:22,398
main.go file we'll create our entry
9630
06:45:22,398 --> 06:45:24,680
point um it will be a part of the main
9631
06:45:24,680 --> 06:45:28,280
package and it will need a main function
9632
06:45:28,280 --> 06:45:30,798
so Funk main takes no arguments return
9633
06:45:30,798 --> 06:45:33,320
those returns no parameters and for now
9634
06:45:33,320 --> 06:45:35,240
let's just print hello world make sure
9635
06:45:35,240 --> 06:45:37,440
we can kind of build and run this
9636
06:45:37,440 --> 06:45:39,760
program um we're going to need to
9637
06:45:39,760 --> 06:45:42,280
initialize a new module for our project
9638
06:45:42,280 --> 06:45:45,718
so I'm going to do go mod in it and I
9639
06:45:45,718 --> 06:45:47,320
like to name my modules after their
9640
06:45:47,320 --> 06:45:49,920
remote path right where they will exist
9641
06:45:49,920 --> 06:45:52,000
um kind of out on the internet so uh in
9642
06:45:52,000 --> 06:45:55,680
my case I use github.com my GitHub uh
9643
06:45:55,680 --> 06:45:58,398
namespace which is Wags Lane slash the
9644
06:45:58,398 --> 06:46:01,080
name of this repository which again is
9645
06:46:01,080 --> 06:46:02,600
where I'll be keeping this code on
9646
06:46:02,600 --> 06:46:04,878
GitHub so I highly recommend you keep
9647
06:46:04,878 --> 06:46:07,638
track of this code in GitHub this entire
9648
06:46:07,638 --> 06:46:09,958
project should be checked into git and
9649
06:46:09,958 --> 06:46:12,718
uploaded to GitHub or gitlab or whatever
9650
06:46:12,718 --> 06:46:15,520
you prefer um so I'm going to name this
9651
06:46:15,520 --> 06:46:20,320
repository um RSS aggregator RSS a so
9652
06:46:20,320 --> 06:46:22,878
we'll go ahead and create that that will
9653
06:46:22,878 --> 06:46:25,000
create this new go
9654
06:46:25,000 --> 06:46:27,240
module and now that that's ready we
9655
06:46:27,240 --> 06:46:29,320
should be able to just go
9656
06:46:29,320 --> 06:46:33,840
build and execute the new uh binary or
9657
06:46:33,840 --> 06:46:35,520
the new executable that will be created
9658
06:46:35,520 --> 06:46:36,958
from go build in fact I'll just run it
9659
06:46:36,958 --> 06:46:39,798
once so you can see I created this new
9660
06:46:39,798 --> 06:46:43,320
binary file here in my current directory
9661
06:46:43,320 --> 06:46:45,040
and so from now on I'll be running this
9662
06:46:45,040 --> 06:46:48,478
command go build and
9663
06:46:48,478 --> 06:46:52,680
slash RSS a so that will build and run
9664
06:46:52,680 --> 06:46:54,360
and we got hello world back so we're
9665
06:46:54,360 --> 06:46:56,478
good to go like I said before we're
9666
06:46:56,478 --> 06:46:58,360
going to be building this project with
9667
06:46:58,360 --> 06:47:00,120
Git and storing our code in Source
9668
06:47:00,120 --> 06:47:01,920
control as we go so I'm going to go
9669
06:47:01,920 --> 06:47:03,878
ahead and create a new
9670
06:47:03,878 --> 06:47:06,280
get repository and in vs code it
9671
06:47:06,280 --> 06:47:08,478
highlights all the code that has changed
9672
06:47:08,478 --> 06:47:10,200
but not yet been committed to Source
9673
06:47:10,200 --> 06:47:12,120
control here in green um but I don't
9674
06:47:12,120 --> 06:47:13,798
want all of this in my source control
9675
06:47:13,798 --> 06:47:16,000
the vs code file is configurations for
9676
06:47:16,000 --> 06:47:17,798
my editor um that's a personal thing
9677
06:47:17,798 --> 06:47:19,440
that doesn't need to be in the project
9678
06:47:19,440 --> 06:47:22,360
itself um same with the RSS a binary we
9679
06:47:22,360 --> 06:47:24,558
don't want to commit the binary that
9680
06:47:24,558 --> 06:47:26,280
we're building or the executable file
9681
06:47:26,280 --> 06:47:27,798
that we're building we just want to
9682
06:47:27,798 --> 06:47:30,040
commit our source code so I'm going to
9683
06:47:30,040 --> 06:47:33,798
create a newg ignore file
9684
06:47:33,798 --> 06:47:36,280
and we're going to ignore the vs code
9685
06:47:36,280 --> 06:47:40,798
folder and the RSS a
9686
06:47:40,798 --> 06:47:45,680
binary and next um we're going to add
9687
06:47:45,680 --> 06:47:47,600
all of the secrets the like
9688
06:47:47,600 --> 06:47:50,718
configuration Secrets uh for our project
9689
06:47:50,718 --> 06:47:54,600
in a EnV file and read them out of the
9690
06:47:54,600 --> 06:47:57,320
file itself so uh for example one of the
9691
06:47:57,320 --> 06:47:58,798
configuration variables that we're going
9692
06:47:58,798 --> 06:48:00,638
to set is the port that the server will
9693
06:48:00,638 --> 06:48:03,360
run on so um I'm going to set that port
9694
06:48:03,360 --> 06:48:05,360
to
9695
06:48:05,360 --> 06:48:09,320
8,000 and I'm going to also ignore thatv
9696
06:48:09,320 --> 06:48:10,920
file in the G
9697
06:48:10,920 --> 06:48:13,440
ignore again because configuration data
9698
06:48:13,440 --> 06:48:15,638
is something kind of local to my machine
9699
06:48:15,638 --> 06:48:17,798
in production this port might be
9700
06:48:17,798 --> 06:48:19,240
something different so we don't need to
9701
06:48:19,240 --> 06:48:21,558
commit this file to Source control um
9702
06:48:21,558 --> 06:48:24,920
but I do want it here in my repo now at
9703
06:48:24,920 --> 06:48:27,478
this point I do want to pause and say if
9704
06:48:27,478 --> 06:48:30,440
you have no idea what a port is or you
9705
06:48:30,440 --> 06:48:33,040
have no idea what HTTP requests are or
9706
06:48:33,040 --> 06:48:35,798
rest apis are um we're going to move
9707
06:48:35,798 --> 06:48:38,160
fairly quickly in this project so if
9708
06:48:38,160 --> 06:48:39,558
you're not familiar with that stuff
9709
06:48:39,558 --> 06:48:40,920
again I will link down in the
9710
06:48:40,920 --> 06:48:43,520
description below my HTTP course that
9711
06:48:43,520 --> 06:48:45,478
would be a good one to go brush up on
9712
06:48:45,478 --> 06:48:48,478
before working on this project so now we
9713
06:48:48,478 --> 06:48:51,638
need a way to read this port variable
9714
06:48:51,638 --> 06:48:54,200
into our program so that we can use it
9715
06:48:54,200 --> 06:48:56,000
and the ghost standard library has a
9716
06:48:56,000 --> 06:48:59,478
built-in uh function called os. getet n
9717
06:48:59,478 --> 06:49:01,600
so it's a an exported function called
9718
06:49:01,600 --> 06:49:05,080
get end from the OS package and we can
9719
06:49:05,080 --> 06:49:07,478
get the value of a variable by its key
9720
06:49:07,478 --> 06:49:09,520
so in this case the key is
9721
06:49:09,520 --> 06:49:14,798
port and we'll get back a port
9722
06:49:14,798 --> 06:49:17,718
string and then for now let's just uh
9723
06:49:17,718 --> 06:49:21,040
let's just say if Port string equals the
9724
06:49:21,040 --> 06:49:23,478
empty string then we'll
9725
06:49:23,478 --> 06:49:28,360
say uh log. fatal so log. fatal will
9726
06:49:28,360 --> 06:49:30,080
exit the program immediately with arrow
9727
06:49:30,080 --> 06:49:34,398
code one and a message and we'll say uh
9728
06:49:34,398 --> 06:49:39,080
Port is not found in the
9729
06:49:39,080 --> 06:49:42,478
environment otherwise we'll
9730
06:49:42,478 --> 06:49:44,920
say
9731
06:49:44,920 --> 06:49:48,360
port and we'll print the port string
9732
06:49:48,360 --> 06:49:51,520
okay cool let's go ahead and run
9733
06:49:56,280 --> 06:49:58,360
that Port is not found in the
9734
06:49:58,360 --> 06:50:00,878
environment okay so the problem here is
9735
06:50:00,878 --> 06:50:03,280
that Port the environment variable
9736
06:50:03,280 --> 06:50:05,440
doesn't exist in my current shell
9737
06:50:05,440 --> 06:50:07,638
session if I wanted to add it I could
9738
06:50:07,638 --> 06:50:11,520
run in my in my command line export Port
9739
06:50:11,520 --> 06:50:13,120
equals
9740
06:50:13,120 --> 06:50:16,798
8000 and then run this again and then we
9741
06:50:16,798 --> 06:50:18,958
get Port equals 8,000 the problem is I
9742
06:50:18,958 --> 06:50:22,000
don't want to manually set this
9743
06:50:22,000 --> 06:50:23,718
environment variable every time I work
9744
06:50:23,718 --> 06:50:26,440
on my server I want to pull it from this
9745
06:50:26,440 --> 06:50:29,440
file so we're going to use a package
9746
06:50:29,440 --> 06:50:30,958
that allows us to grab environment
9747
06:50:30,958 --> 06:50:33,240
variables from a file
9748
06:50:33,240 --> 06:50:36,040
um and it is this package here
9749
06:50:36,040 --> 06:50:37,478
github.com
9750
06:50:37,478 --> 06:50:41,558
jooho go. EnV um that's also the URL of
9751
06:50:41,558 --> 06:50:43,558
the library you can paste that into your
9752
06:50:43,558 --> 06:50:45,680
browser uh go check it out but we're
9753
06:50:45,680 --> 06:50:48,320
just going to install it here
9754
06:50:48,320 --> 06:50:51,798
locally and that will add it here to our
9755
06:50:51,798 --> 06:50:55,280
go.mod and then I'm going to run go
9756
06:50:55,280 --> 06:51:01,200
vendor to copy that code here into uh my
9757
06:51:01,200 --> 06:51:04,240
my vendor folder um we get kind of a
9758
06:51:04,240 --> 06:51:09,520
local copy of that and we'll run um here
9759
06:51:09,520 --> 06:51:10,920
we're going to need to actually use it
9760
06:51:10,920 --> 06:51:17,160
so we do go. env. load and by default
9761
06:51:17,160 --> 06:51:21,040
load loads the uhv file I think we can
9762
06:51:21,040 --> 06:51:26,080
also optionally pass in EnV as the file
9763
06:51:26,080 --> 06:51:28,638
path and what's uh what's my error here
9764
06:51:28,638 --> 06:51:31,280
could not import no required module
9765
06:51:31,280 --> 06:51:33,160
provides
9766
06:51:33,160 --> 06:51:35,360
go let's go mod
9767
06:51:35,360 --> 06:51:37,760
tidy that should clean up my imports
9768
06:51:37,760 --> 06:51:39,958
okay
9769
06:51:40,680 --> 06:51:42,760
perfect
9770
06:51:42,760 --> 06:51:45,040
and do I need to do anything else what
9771
06:51:45,040 --> 06:51:47,080
are we getting here could not import no
9772
06:51:47,080 --> 06:51:48,440
required module oh I should probably go
9773
06:51:48,440 --> 06:51:51,000
mod vendor
9774
06:51:51,478 --> 06:51:53,878
again that should pull in the code okay
9775
06:51:53,878 --> 06:51:56,040
so you can see we've kind of imported
9776
06:51:56,040 --> 06:51:58,718
and downloaded all of that code from the
9777
06:51:58,718 --> 06:52:00,840
package and now I'm not getting error
9778
06:52:00,840 --> 06:52:03,280
any errors in my console okay so this
9779
06:52:03,280 --> 06:52:04,920
will take the environment variables from
9780
06:52:04,920 --> 06:52:07,958
myv file and pull them into my current
9781
06:52:07,958 --> 06:52:10,558
environment so that then I can use os.
9782
06:52:10,558 --> 06:52:13,160
get EnV to load the variable so to test
9783
06:52:13,160 --> 06:52:15,520
that let's go ahead and change uh the
9784
06:52:15,520 --> 06:52:17,080
port to
9785
06:52:17,080 --> 06:52:20,798
8080 and rerun the
9786
06:52:21,478 --> 06:52:23,958
server still says 8,000 so something
9787
06:52:23,958 --> 06:52:25,600
went wrong maybe I'm misremembering how
9788
06:52:25,600 --> 06:52:28,160
to use this uh use this
9789
06:52:28,160 --> 06:52:32,600
package let's try just go. .load
9790
06:52:32,600 --> 06:52:34,200
still Port
9791
06:52:34,200 --> 06:52:37,798
80 what am I doing wrong does it not
9792
06:52:37,798 --> 06:52:39,638
overwrite you know what it might not
9793
06:52:39,638 --> 06:52:41,160
overwrite my current session I'm going
9794
06:52:41,160 --> 06:52:43,320
to kill my current cell session shell
9795
06:52:43,320 --> 06:52:46,398
session and create a new one then we'll
9796
06:52:46,398 --> 06:52:49,000
do this again so now I won't have that
9797
06:52:49,000 --> 06:52:52,840
exported 8,000 that I had in my terminal
9798
06:52:52,840 --> 06:52:56,478
um run that again okay cool so now it's
9799
06:52:56,478 --> 06:52:58,360
pulling it from the file because I don't
9800
06:52:58,360 --> 06:53:00,558
already have it defined in my shell
9801
06:53:00,558 --> 06:53:02,760
session now I want to take just a second
9802
06:53:02,760 --> 06:53:04,520
and point out there are text
9803
06:53:04,520 --> 06:53:06,600
instructions for this entire project
9804
06:53:06,600 --> 06:53:09,080
over on boot. and I'll link that down in
9805
06:53:09,080 --> 06:53:10,398
the description below we're going to be
9806
06:53:10,398 --> 06:53:12,798
using a lot of text uh you know code
9807
06:53:12,798 --> 06:53:15,120
Snippets from those text instructions
9808
06:53:15,120 --> 06:53:16,878
and they'll be easier to kind of copy
9809
06:53:16,878 --> 06:53:19,958
and paste and grab from boot. directly
9810
06:53:19,958 --> 06:53:21,360
than trying to you know retype what
9811
06:53:21,360 --> 06:53:23,680
you're seeing me type here on the screen
9812
06:53:23,680 --> 06:53:25,440
now we're going to actually spin up our
9813
06:53:25,440 --> 06:53:27,000
server and we're going to be using the
9814
06:53:27,000 --> 06:53:29,440
chi router to do it it's a third-party
9815
06:53:29,440 --> 06:53:31,878
router uh very lightweight built on top
9816
06:53:31,878 --> 06:53:33,398
of kind of the the same way that the
9817
06:53:33,398 --> 06:53:36,760
standard library in go does http routers
9818
06:53:36,760 --> 06:53:37,958
and so let's go ahead and install those
9819
06:53:37,958 --> 06:53:41,798
now we'll do go get um github.com
9820
06:53:41,798 --> 06:53:45,680
gochi chai or chi I always struggle to
9821
06:53:45,680 --> 06:53:48,160
pronounce that one um we'll install that
9822
06:53:48,160 --> 06:53:51,080
and we'll install the the cores package
9823
06:53:51,080 --> 06:53:54,120
from the same uh the same Nam space the
9824
06:53:54,120 --> 06:53:56,920
chi namespace next we'll create a new
9825
06:53:56,920 --> 06:53:59,840
router so I'll do router colon equals
9826
06:53:59,840 --> 06:54:02,760
chi. new router
9827
06:54:02,760 --> 06:54:06,920
fact I should probably go mod
9828
06:54:07,680 --> 06:54:09,760
vendor have it there and then I'll do
9829
06:54:09,760 --> 06:54:13,000
another go mod tidy and go mod vender to
9830
06:54:13,000 --> 06:54:14,320
bring it
9831
06:54:14,320 --> 06:54:17,558
in cool so this creates a new router
9832
06:54:17,558 --> 06:54:20,440
object next we'll connect up this router
9833
06:54:20,440 --> 06:54:23,878
to an HTTP do server so serve colon
9834
06:54:23,878 --> 06:54:27,558
equals a pointer to an HTTP do
9835
06:54:27,558 --> 06:54:31,760
server and a server needs a Handler
9836
06:54:31,760 --> 06:54:33,760
which will be router
9837
06:54:33,760 --> 06:54:38,958
itself and we also need a or an address
9838
06:54:38,958 --> 06:54:43,478
which is just a colon plus that Port
9839
06:54:43,478 --> 06:54:46,398
string so in this case it'll be colon
9840
06:54:46,398 --> 06:54:49,200
you know 8080 cool and then we can call
9841
06:54:49,200 --> 06:54:52,638
HTTP do listen and
9842
06:54:52,638 --> 06:54:55,160
serve or sorry not HTTP listen and serve
9843
06:54:55,160 --> 06:54:56,760
we want to call it on the server object
9844
06:54:56,760 --> 06:55:00,440
so serve. listen and serve cool and
9845
06:55:00,440 --> 06:55:02,398
before we call that in fact I think that
9846
06:55:02,398 --> 06:55:04,440
returns an error so let's capture that
9847
06:55:04,440 --> 06:55:07,680
error and say if error does not equal
9848
06:55:07,680 --> 06:55:10,080
nil log.
9849
06:55:10,080 --> 06:55:13,360
fatal pass in the air as a
9850
06:55:13,360 --> 06:55:17,040
message okay listen and serve will block
9851
06:55:17,040 --> 06:55:20,160
so when we get to line 30 our our code
9852
06:55:20,160 --> 06:55:21,718
basically just stops right here and
9853
06:55:21,718 --> 06:55:25,160
starts handling HTTP requests if
9854
06:55:25,160 --> 06:55:27,160
anything goes wrong in the process of
9855
06:55:27,160 --> 06:55:29,440
handling those requests then an error
9856
06:55:29,440 --> 06:55:32,080
will be returned and we'll you know log
9857
06:55:32,080 --> 06:55:34,478
in and exit the program but kind of the
9858
06:55:34,478 --> 06:55:37,160
happy path for our code is that you know
9859
06:55:37,160 --> 06:55:38,878
nothing should ever be returned from
9860
06:55:38,878 --> 06:55:40,520
listen and serve because our server is
9861
06:55:40,520 --> 06:55:42,878
just going to run forever before we run
9862
06:55:42,878 --> 06:55:45,200
this let's just add one more kind of
9863
06:55:45,200 --> 06:55:47,840
logging statement we'll do log. print
9864
06:55:47,840 --> 06:55:51,160
line actually let's do print F and we'll
9865
06:55:51,160 --> 06:55:56,120
say server starting on
9866
06:55:56,120 --> 06:56:00,440
portent V and we'll pass in that Port
9867
06:56:00,440 --> 06:56:03,360
string okay cool with that let's go
9868
06:56:03,360 --> 06:56:07,040
ahead and build and run again so go
9869
06:56:08,040 --> 06:56:10,878
build see what we
9870
06:56:10,878 --> 06:56:13,520
get Hello World server starting on Port
9871
06:56:13,520 --> 06:56:15,680
880 I should probably remove should
9872
06:56:15,680 --> 06:56:17,080
probably remove that hello world at this
9873
06:56:17,080 --> 06:56:19,440
point now that we have a running server
9874
06:56:19,440 --> 06:56:21,638
let's go ahead and test it so I'm over
9875
06:56:21,638 --> 06:56:23,958
here in the Thunder client tab again
9876
06:56:23,958 --> 06:56:25,120
because I'm using the Thunder client
9877
06:56:25,120 --> 06:56:27,160
plug-in and I'm going to click new
9878
06:56:27,160 --> 06:56:29,360
request and we're going to make a
9879
06:56:29,360 --> 06:56:31,240
request to
9880
06:56:31,240 --> 06:56:34,478
http SL localhost right we want to make
9881
06:56:34,478 --> 06:56:36,760
a request to our own machine on the port
9882
06:56:36,760 --> 06:56:39,080
that we running on which I believe is
9883
06:56:39,080 --> 06:56:41,798
8080 okay with that let's go ahead and
9884
06:56:41,798 --> 06:56:44,280
start up our
9885
06:56:47,878 --> 06:56:50,798
server okay server starting on port 8080
9886
06:56:50,798 --> 06:56:53,080
so it should be good now you'll see I
9887
06:56:53,080 --> 06:56:54,798
don't have a new prompt because my my
9888
06:56:54,798 --> 06:56:57,240
server is still running um if I send
9889
06:56:57,240 --> 06:57:00,120
this get request perfect we get a 404
9890
06:57:00,120 --> 06:57:01,760
that's exactly what we'd expect because
9891
06:57:01,760 --> 06:57:03,520
remember in our code we haven't actually
9892
06:57:03,520 --> 06:57:05,638
set up any handlers or anything we just
9893
06:57:05,638 --> 06:57:07,920
have a server running so we're getting a
9894
06:57:07,920 --> 06:57:10,478
404 because we're trying to hit a path
9895
06:57:10,478 --> 06:57:12,878
in this case the root path uh and it
9896
06:57:12,878 --> 06:57:15,520
doesn't have anything any logic there to
9897
06:57:15,520 --> 06:57:18,600
handle that code if we killed our server
9898
06:57:18,600 --> 06:57:20,558
and ran it again we just get a
9899
06:57:20,558 --> 06:57:23,040
connection refused I've configured my
9900
06:57:23,040 --> 06:57:25,558
thunder client to actually store all of
9901
06:57:25,558 --> 06:57:29,558
my tests or my HTTP requests as plain
9902
06:57:29,558 --> 06:57:31,558
text here in the working directory uh
9903
06:57:31,558 --> 06:57:33,398
but I don't want those going into my
9904
06:57:33,398 --> 06:57:34,558
source control so I'm going to go ahead
9905
06:57:34,558 --> 06:57:37,398
and add that to the G ignore thunder-
9906
06:57:37,398 --> 06:57:40,520
tests we'll ignore everything in there
9907
06:57:40,520 --> 06:57:42,958
next let's add a Coors configuration to
9908
06:57:42,958 --> 06:57:44,520
our router so this is so that people can
9909
06:57:44,520 --> 06:57:46,600
make requests to our server from a
9910
06:57:46,600 --> 06:57:48,280
browser and we're going to be using some
9911
06:57:48,280 --> 06:57:50,718
fairly permissive uh configurations here
9912
06:57:50,718 --> 06:57:51,840
and we'll use
9913
06:57:51,840 --> 06:57:56,200
router. use and then we'll pass in this
9914
06:57:56,200 --> 06:57:58,798
cores. Handler configuration this comes
9915
06:57:58,798 --> 06:58:00,200
from that Coors package that we
9916
06:58:00,200 --> 06:58:02,958
installed earlier and let me see what am
9917
06:58:02,958 --> 06:58:04,320
I doing here we need one more
9918
06:58:04,320 --> 06:58:07,000
parentheses there and then I'm going to
9919
06:58:07,000 --> 06:58:09,680
go ahead and vendor this as well so go
9920
06:58:09,680 --> 06:58:13,958
mod tidy go mod
9921
06:58:15,120 --> 06:58:17,478
vendor cool so we should have all of
9922
06:58:17,478 --> 06:58:21,040
that code here in our vendor folder as
9923
06:58:21,040 --> 06:58:24,160
well I'm not going to go too in depth on
9924
06:58:24,160 --> 06:58:25,718
exactly what cores are you can
9925
06:58:25,718 --> 06:58:27,080
definitely go look that up but just to
9926
06:58:27,080 --> 06:58:29,478
give you a high level overview um this
9927
06:58:29,478 --> 06:58:31,320
configuration is essentially telling our
9928
06:58:31,320 --> 06:58:34,320
server to you send a bunch of uh extra
9929
06:58:34,320 --> 06:58:37,680
HTTP headers in our responses that will
9930
06:58:37,680 --> 06:58:41,440
tell browsers hey we allow you to send
9931
06:58:41,440 --> 06:58:44,840
uh you know requests to http or https
9932
06:58:44,840 --> 06:58:46,478
versions We allow you to use these
9933
06:58:46,478 --> 06:58:48,878
methods we allow you to send any headers
9934
06:58:48,878 --> 06:58:50,760
um it's just a way to say hey we're
9935
06:58:50,760 --> 06:58:52,478
going to allow you to do basically
9936
06:58:52,478 --> 06:58:54,878
whatever you want there are ways you can
9937
06:58:54,878 --> 06:58:56,398
tighten up this configuration for
9938
06:58:56,398 --> 06:58:58,600
security purposes but for now we're just
9939
06:58:58,600 --> 06:59:00,320
going to be running our project on our
9940
06:59:00,320 --> 06:59:02,200
local machine so we're going to just
9941
06:59:02,200 --> 06:59:04,280
open it up make it permissive to avoid
9942
06:59:04,280 --> 06:59:06,478
any sort of uh kind of weird testing
9943
06:59:06,478 --> 06:59:08,280
issues if we try to connect to our
9944
06:59:08,280 --> 06:59:11,080
server through a browser This Server
9945
06:59:11,080 --> 06:59:13,200
we're building is going to be a Json
9946
06:59:13,200 --> 06:59:15,600
rest API which means all of the request
9947
06:59:15,600 --> 06:59:17,520
bodies coming in and response bodies
9948
06:59:17,520 --> 06:59:21,080
going back will have a Json format so
9949
06:59:21,080 --> 06:59:23,520
let's create a little helper function
9950
06:59:23,520 --> 06:59:25,440
that will make it easier to send Json
9951
06:59:25,440 --> 06:59:26,840
responses so I'm going to create a new
9952
06:59:26,840 --> 06:59:28,798
file call it json. go it's going to be
9953
06:59:28,798 --> 06:59:30,040
in the main
9954
06:59:30,040 --> 06:59:32,520
package and the function sign is going
9955
06:59:32,520 --> 06:59:33,878
to look like this so we've got a
9956
06:59:33,878 --> 06:59:35,120
function we're calling it respond with
9957
06:59:35,120 --> 06:59:38,240
Json it takes as input a response writer
9958
06:59:38,240 --> 06:59:40,520
this is the same HTTP response riter
9959
06:59:40,520 --> 06:59:43,520
that uh HTTP handlers Ingo use it's
9960
06:59:43,520 --> 06:59:45,718
exposed by the standard Library um it
9961
06:59:45,718 --> 06:59:48,280
will take a code so this is the status
9962
06:59:48,280 --> 06:59:49,718
code we're going to respond with and
9963
06:59:49,718 --> 06:59:51,760
then we'll take an interface which is
9964
06:59:51,760 --> 06:59:54,520
just something that we can Marshall to
9965
06:59:54,520 --> 06:59:56,840
um a Json structure the first thing the
9966
06:59:56,840 --> 06:59:58,958
function will do is Marshall the payload
9967
06:59:58,958 --> 07:00:02,200
into a Json object or a Json string and
9968
07:00:02,200 --> 07:00:04,000
the way we do that is with the standard
9969
07:00:04,000 --> 07:00:06,760
Library so we data and error equals
9970
07:00:06,760 --> 07:00:08,120
json.
9971
07:00:08,120 --> 07:00:10,878
Marshall and we pass in the
9972
07:00:10,878 --> 07:00:13,320
payload so this function will attempt to
9973
07:00:13,320 --> 07:00:16,240
Marshall uh whatever it's given into a
9974
07:00:16,240 --> 07:00:18,760
Json string and it will return it as
9975
07:00:18,760 --> 07:00:20,240
bytes and the reason it returns it as
9976
07:00:20,240 --> 07:00:21,958
bytes is so that we can write it in a
9977
07:00:21,958 --> 07:00:24,360
binary format directly to the HTTP
9978
07:00:24,360 --> 07:00:26,558
response uh which is pretty convenient
9979
07:00:26,558 --> 07:00:28,440
if that fails for whatever
9980
07:00:28,440 --> 07:00:32,120
reason then what we'll do
9981
07:00:32,120 --> 07:00:35,160
is we'll write a header to the response
9982
07:00:35,160 --> 07:00:36,878
and we'll use status code 500 we'll say
9983
07:00:36,878 --> 07:00:38,798
something went wrong on our end right
9984
07:00:38,798 --> 07:00:40,680
internal service error or internal
9985
07:00:40,680 --> 07:00:43,040
server error um and then we'll just
9986
07:00:43,040 --> 07:00:45,280
return from the function and actually if
9987
07:00:45,280 --> 07:00:46,718
something goes wrong we should probably
9988
07:00:46,718 --> 07:00:49,320
log it um as well on the server side so
9989
07:00:49,320 --> 07:00:51,520
that we can see our own logs and see hey
9990
07:00:51,520 --> 07:00:53,320
we tried to do something in a broke uh
9991
07:00:53,320 --> 07:00:56,638
so we'll do log dot print
9992
07:00:56,638 --> 07:01:00,080
line failed to
9993
07:01:00,080 --> 07:01:02,878
Marshall Json respon
9994
07:01:02,878 --> 07:01:06,718
response and let's print the
9995
07:01:06,760 --> 07:01:08,958
response or let's print what we tried to
9996
07:01:08,958 --> 07:01:11,440
Marshall that's probably more more
9997
07:01:11,440 --> 07:01:13,160
interesting we'll use print F so that we
9998
07:01:13,160 --> 07:01:15,718
can interpolate that value there um next
9999
07:01:15,718 --> 07:01:17,878
we're going to need to add a header to
10000
07:01:17,878 --> 07:01:18,878
the response to say that we're
10001
07:01:18,878 --> 07:01:20,798
responding with Json data so we'll do
10002
07:01:20,798 --> 07:01:23,718
W.R
10003
07:01:24,478 --> 07:01:27,160
header and or not right header I'm sorry
10004
07:01:27,160 --> 07:01:29,958
uh w.
10005
07:01:30,240 --> 07:01:32,958
headers do it
10006
07:01:32,958 --> 07:01:37,680
header do add and we want to add the
10007
07:01:37,680 --> 07:01:41,040
content type key so content
10008
07:01:41,040 --> 07:01:43,840
type and the key will be or the value
10009
07:01:43,840 --> 07:01:47,398
will be application Json so this adds a
10010
07:01:47,398 --> 07:01:49,160
response header to the HTTP request
10011
07:01:49,160 --> 07:01:50,680
saying hey we're responding with a
10012
07:01:50,680 --> 07:01:53,240
content type of application Json which
10013
07:01:53,240 --> 07:01:55,878
is the standard of value for Json
10014
07:01:55,878 --> 07:01:58,240
responses um and then we should be able
10015
07:01:58,240 --> 07:02:02,680
to uh write the status code so we do w .
10016
07:02:02,680 --> 07:02:06,360
WR header 200 so everything went well
10017
07:02:06,360 --> 07:02:07,920
and then we need to write the data
10018
07:02:07,920 --> 07:02:12,600
itself so w. write and pass in the Json
10019
07:02:12,600 --> 07:02:15,080
data this will write the response body
10020
07:02:15,080 --> 07:02:16,760
now that we have a way to respond with
10021
07:02:16,760 --> 07:02:18,760
some Json data let's create an HTTP
10022
07:02:18,760 --> 07:02:21,320
Handler that does that so we'll do
10023
07:02:21,320 --> 07:02:23,840
handlers or
10024
07:02:23,840 --> 07:02:26,600
Handler
10025
07:02:26,600 --> 07:02:28,878
Readiness again this will be in the main
10026
07:02:28,878 --> 07:02:30,958
package and we're going to create a new
10027
07:02:30,958 --> 07:02:33,200
function
10028
07:02:33,200 --> 07:02:36,160
called Handler Readiness and this is a
10029
07:02:36,160 --> 07:02:38,240
very specific function signature this is
10030
07:02:38,240 --> 07:02:40,040
the function signature that you have to
10031
07:02:40,040 --> 07:02:42,840
use if you want to Define an HTTP
10032
07:02:42,840 --> 07:02:44,638
Handler in the way that the goh standard
10033
07:02:44,638 --> 07:02:47,280
Library expects so it always takes a
10034
07:02:47,280 --> 07:02:49,718
response writer as the first parameter
10035
07:02:49,718 --> 07:02:52,440
and a pointer to an HTTP request as the
10036
07:02:52,440 --> 07:02:54,718
second parameter and then in the body of
10037
07:02:54,718 --> 07:02:56,760
this Handler we can just call our
10038
07:02:56,760 --> 07:02:59,760
respond with Json function so we'll say
10039
07:02:59,760 --> 07:03:03,120
respond with Json we'll pass in that
10040
07:03:03,120 --> 07:03:06,280
HTTP response writer we want to respond
10041
07:03:06,280 --> 07:03:11,478
with a 200 status code and some some
10042
07:03:11,478 --> 07:03:14,440
response payload in this case all we
10043
07:03:14,440 --> 07:03:17,080
care about is the 200 okay status code
10044
07:03:17,080 --> 07:03:18,160
so I'm actually just going to respond
10045
07:03:18,160 --> 07:03:19,520
with an empty struct which should
10046
07:03:19,520 --> 07:03:23,120
Marshall to kind of an empty Json object
10047
07:03:23,120 --> 07:03:24,840
and now that I'm writing this I realized
10048
07:03:24,840 --> 07:03:26,320
that we actually made a mistake or I
10049
07:03:26,320 --> 07:03:29,478
made a mistake in the Json uh respond
10050
07:03:29,478 --> 07:03:32,440
with Json code we should pass in uh we
10051
07:03:32,440 --> 07:03:34,680
should use the pting Response Code
10052
07:03:34,680 --> 07:03:36,638
instead of hardcoding the 200 so if
10053
07:03:36,638 --> 07:03:38,520
everything goes right we'll use the code
10054
07:03:38,520 --> 07:03:42,080
given okay now with that we need to hook
10055
07:03:42,080 --> 07:03:45,440
up our Handler Now using the chi router
10056
07:03:45,440 --> 07:03:47,558
what we do is we hook up a an HTTP
10057
07:03:47,558 --> 07:03:49,680
Handler which is this function to a
10058
07:03:49,680 --> 07:03:53,398
specific HTTP method and path okay so
10059
07:03:53,398 --> 07:03:54,840
the way we're going to do that is I'm
10060
07:03:54,840 --> 07:03:57,160
going to create a new router so V1
10061
07:03:57,160 --> 07:04:00,878
router and we'll use that same chi. new
10062
07:04:00,878 --> 07:04:02,558
router to do it
10063
07:04:02,558 --> 07:04:06,080
and I'm going to specify V1
10064
07:04:06,080 --> 07:04:07,600
router.
10065
07:04:07,600 --> 07:04:11,280
handle handle Funk excuse me I want to
10066
07:04:11,280 --> 07:04:13,840
handle the slash ready
10067
07:04:13,840 --> 07:04:17,200
path and I want to handle it with this
10068
07:04:17,200 --> 07:04:20,440
Handler Readiness function okay so we're
10069
07:04:20,440 --> 07:04:22,638
we're connecting the Handler Readiness
10070
07:04:22,638 --> 07:04:25,478
function to the slash ready path and the
10071
07:04:25,478 --> 07:04:27,798
reason I created this new V1 router is
10072
07:04:27,798 --> 07:04:30,320
because I'm going to mount that so I can
10073
07:04:30,320 --> 07:04:33,320
do router. Mount
10074
07:04:33,320 --> 07:04:35,680
count to the
10075
07:04:35,680 --> 07:04:40,360
slv1 path okay so I'm nesting a V1
10076
07:04:40,360 --> 07:04:43,200
router under the slv1 path and I'm
10077
07:04:43,200 --> 07:04:44,920
hooking up the Readiness Handler at the
10078
07:04:44,920 --> 07:04:48,360
SL ready path so the full path for this
10079
07:04:48,360 --> 07:04:51,320
request will be slv1 SL ready and that's
10080
07:04:51,320 --> 07:04:53,120
just so that if we make breaking changes
10081
07:04:53,120 --> 07:04:55,440
in the future we can kind of have two
10082
07:04:55,440 --> 07:04:57,600
different handlers one under version one
10083
07:04:57,600 --> 07:04:59,680
and one under version two for our rest
10084
07:04:59,680 --> 07:05:02,200
API this is fairly standard practice
10085
07:05:02,200 --> 07:05:04,718
and actually I'm going to name this path
10086
07:05:04,718 --> 07:05:08,520
health health Z that's just a habit uh
10087
07:05:08,520 --> 07:05:09,680
that I'm bringing with me from
10088
07:05:09,680 --> 07:05:11,478
kubernetes land it's pretty standard to
10089
07:05:11,478 --> 07:05:14,398
have a SL Health Z path um that you can
10090
07:05:14,398 --> 07:05:16,360
hit to see if your server is live and
10091
07:05:16,360 --> 07:05:18,280
running so that's the purpose of this
10092
07:05:18,280 --> 07:05:20,478
Handler it should just respond if the
10093
07:05:20,478 --> 07:05:22,320
server is alive and running and
10094
07:05:22,320 --> 07:05:23,958
everything's good okay so let's go ahead
10095
07:05:23,958 --> 07:05:25,798
and run the server and make sure it's
10096
07:05:25,798 --> 07:05:28,280
doing what we'd expect so go build and
10097
07:05:28,280 --> 07:05:31,798
slash RSS a that starts up the server
10098
07:05:31,798 --> 07:05:33,878
and then we can open up thunder
10099
07:05:33,878 --> 07:05:36,080
client and now instead of making a
10100
07:05:36,080 --> 07:05:37,760
request to the root which we'd expect to
10101
07:05:37,760 --> 07:05:41,200
get a 404 from we'll do
10102
07:05:41,200 --> 07:05:45,600
slv1 healz and make that get request and
10103
07:05:45,600 --> 07:05:48,398
we get the 200 now here's the weird
10104
07:05:48,398 --> 07:05:50,958
thing if I change this to a post request
10105
07:05:50,958 --> 07:05:54,398
and I make that I actually still get a
10106
07:05:54,398 --> 07:05:56,280
200 but that's not really Our intention
10107
07:05:56,280 --> 07:05:58,080
the health Z endpoint should really only
10108
07:05:58,080 --> 07:06:00,120
be accessible by get request so I'm
10109
07:06:00,120 --> 07:06:01,878
going to make an update here rather than
10110
07:06:01,878 --> 07:06:03,878
using the V1 router. handle Funk I'm
10111
07:06:03,878 --> 07:06:06,440
going to use V1 router. getet and this
10112
07:06:06,440 --> 07:06:09,718
will scope the Handler to only fire on
10113
07:06:09,718 --> 07:06:12,120
get requests okay with that let's go
10114
07:06:12,120 --> 07:06:13,760
ahead and rebuild our
10115
07:06:13,760 --> 07:06:18,240
server and check again post should fail
10116
07:06:18,240 --> 07:06:20,600
method not allowed perfect but the get
10117
07:06:20,600 --> 07:06:23,320
request should still work so we have a
10118
07:06:23,320 --> 07:06:25,040
nice helper function for responding with
10119
07:06:25,040 --> 07:06:27,320
arbitrary Json now I want one for
10120
07:06:27,320 --> 07:06:29,600
responding with arbitrary error messages
10121
07:06:29,600 --> 07:06:32,280
so let's do function respond with there
10122
07:06:32,280 --> 07:06:33,840
um it will look very similar but instead
10123
07:06:33,840 --> 07:06:35,240
of taking a payload which is an
10124
07:06:35,240 --> 07:06:37,680
interface it will take a message string
10125
07:06:37,680 --> 07:06:38,840
and this function is basically just
10126
07:06:38,840 --> 07:06:41,478
going to format that message into a
10127
07:06:41,478 --> 07:06:45,360
consistent uh Json object every single
10128
07:06:45,360 --> 07:06:47,760
time okay uh first thing we're going to
10129
07:06:47,760 --> 07:06:50,360
do is say if the code is greater than
10130
07:06:50,360 --> 07:06:52,600
499 we're going to log a message and
10131
07:06:52,600 --> 07:06:56,200
that's because uh error codes in the 400
10132
07:06:56,200 --> 07:06:58,680
range are client side errors so we don't
10133
07:06:58,680 --> 07:07:00,120
really need to know about them it just
10134
07:07:00,120 --> 07:07:02,120
means someone's using our API in a weird
10135
07:07:02,120 --> 07:07:03,840
way um but we do need to know whenever
10136
07:07:03,840 --> 07:07:06,440
we're sering we're responding with a 500
10137
07:07:06,440 --> 07:07:08,320
level error code because that means we
10138
07:07:08,320 --> 07:07:09,798
have a bug on our end and we should
10139
07:07:09,798 --> 07:07:12,760
probably go fix it so we'll do log.
10140
07:07:12,760 --> 07:07:17,760
print line responding with 500 level
10141
07:07:17,760 --> 07:07:19,878
error and we'll just tack the message
10142
07:07:19,878 --> 07:07:23,240
itself on there okay cool after we do
10143
07:07:23,240 --> 07:07:26,360
that logging um we'll use the respond
10144
07:07:26,360 --> 07:07:28,958
with Json function uh but we'll be
10145
07:07:28,958 --> 07:07:30,240
responding with a
10146
07:07:30,240 --> 07:07:32,080
specific uh
10147
07:07:32,080 --> 07:07:34,360
structure of Json uh so let's go ahead
10148
07:07:34,360 --> 07:07:37,718
and Define that as a struct so type um
10149
07:07:37,718 --> 07:07:39,398
air
10150
07:07:39,398 --> 07:07:41,878
response is a struct and it has one
10151
07:07:41,878 --> 07:07:45,240
field error which just a string and
10152
07:07:45,240 --> 07:07:48,280
we'll add this Json tag to just say this
10153
07:07:48,280 --> 07:07:50,478
the key that this should Marcel to is
10154
07:07:50,478 --> 07:07:54,440
error so in go we typically take a
10155
07:07:54,440 --> 07:07:57,760
struct and add these Json reflect tags
10156
07:07:57,760 --> 07:08:01,200
to it to specify how we want this json.
10157
07:08:01,200 --> 07:08:03,798
Mar function or on the other side the
10158
07:08:03,798 --> 07:08:07,558
json. unmarshal function uh to kind of
10159
07:08:07,558 --> 07:08:11,040
convert this struct into a Json object
10160
07:08:11,040 --> 07:08:13,320
so in this case we're saying I have an
10161
07:08:13,320 --> 07:08:16,000
error field it's string and I want the
10162
07:08:16,000 --> 07:08:18,440
key for the field to be error so this
10163
07:08:18,440 --> 07:08:20,920
struct will Marshall into a Json object
10164
07:08:20,920 --> 07:08:24,920
that looks kind of like uh like
10165
07:08:25,280 --> 07:08:27,040
this
10166
07:08:27,040 --> 07:08:33,440
error you something went wrong
10167
07:08:33,600 --> 07:08:36,040
right it wouldn't have actually wouldn't
10168
07:08:36,040 --> 07:08:38,638
have that but it would look like that
10169
07:08:38,638 --> 07:08:41,600
okay and we'll see that in just a second
10170
07:08:41,600 --> 07:08:43,878
okay so now we get to respond with Json
10171
07:08:43,878 --> 07:08:46,760
we pass in the response writer a the
10172
07:08:46,760 --> 07:08:48,760
same code that we were given and then
10173
07:08:48,760 --> 07:08:51,958
we'll just respond with an error
10174
07:08:51,958 --> 07:08:54,718
response and the error message will be
10175
07:08:54,718 --> 07:08:56,680
the message that we were
10176
07:08:56,680 --> 07:09:00,000
given okay let's hook this up to another
10177
07:09:00,000 --> 07:09:05,798
Handler so here we can do V1 router.
10178
07:09:05,798 --> 07:09:09,760
getet we'll create an error endpoint and
10179
07:09:09,760 --> 07:09:13,080
oh I need I need an actual Handler so
10180
07:09:13,080 --> 07:09:16,478
we'll create a new one called
10181
07:09:16,600 --> 07:09:19,600
Handler
10182
07:09:20,398 --> 07:09:24,558
error Handler error and we'll respond
10183
07:09:24,558 --> 07:09:26,638
with an error instead of passing in an
10184
07:09:26,638 --> 07:09:29,360
empty struct we'll
10185
07:09:29,360 --> 07:09:32,360
say something when
10186
07:09:32,360 --> 07:09:36,160
wrong and we'll respond with a 400
10187
07:09:36,160 --> 07:09:39,520
status code client error right okay now
10188
07:09:39,520 --> 07:09:41,280
we can hook up this error
10189
07:09:41,280 --> 07:09:45,160
Handler here it will only work on get
10190
07:09:45,160 --> 07:09:47,798
requests that seems reasonable and
10191
07:09:47,798 --> 07:09:50,000
basically it's just going to call that
10192
07:09:50,000 --> 07:09:51,280
respond with error function so it'll be
10193
07:09:51,280 --> 07:09:53,440
a good way to test
10194
07:09:53,440 --> 07:09:59,000
that okay let's go ahead and rebuild the
10195
07:09:59,040 --> 07:10:02,080
server nope what did we screw up
10196
07:10:02,080 --> 07:10:05,040
routing pattern must begin with Slash ah
10197
07:10:05,040 --> 07:10:07,718
let's go fix
10198
07:10:08,040 --> 07:10:10,718
that so you can see here we've got SL
10199
07:10:10,718 --> 07:10:13,718
Health zv1 we need to start these with a
10200
07:10:13,718 --> 07:10:16,200
slash it's just the way the chai rou or
10201
07:10:16,200 --> 07:10:18,920
the chi router
10202
07:10:19,120 --> 07:10:22,160
works cool um let's go open up the
10203
07:10:22,160 --> 07:10:24,280
Thunder client and send a
10204
07:10:24,280 --> 07:10:27,718
request to the slash errror
10205
07:10:27,718 --> 07:10:31,360
Handler cool we get the 400 bad request
10206
07:10:31,360 --> 07:10:34,638
status code and this is that Json body
10207
07:10:34,638 --> 07:10:37,240
um so every single time that we need to
10208
07:10:37,240 --> 07:10:39,280
return an error from our server now we
10209
07:10:39,280 --> 07:10:40,718
can just use this function and it will
10210
07:10:40,718 --> 07:10:43,398
always use this consistent error format
10211
07:10:43,398 --> 07:10:44,680
which is great because we can throw this
10212
07:10:44,680 --> 07:10:46,120
in our documentation and just tell all
10213
07:10:46,120 --> 07:10:49,120
of the users of our API hey this is what
10214
07:10:49,120 --> 07:10:50,798
you should expect when something goes
10215
07:10:50,798 --> 07:10:52,680
wrong now that we have a little bit of
10216
07:10:52,680 --> 07:10:54,200
our boiler plate set up I'm going to
10217
07:10:54,200 --> 07:10:56,200
take the opportunity to commit all of
10218
07:10:56,200 --> 07:10:58,798
this to get uh so that I don't lose it
10219
07:10:58,798 --> 07:11:02,558
um I will say that I generally recommend
10220
07:11:02,558 --> 07:11:04,680
committing the vendor folder so you can
10221
07:11:04,680 --> 07:11:06,040
think of the vendor folder kind of like
10222
07:11:06,040 --> 07:11:07,600
the node modules folder if you're
10223
07:11:07,600 --> 07:11:09,520
familiar with JavaScript land and in
10224
07:11:09,520 --> 07:11:11,040
JavaScript you would never commit it
10225
07:11:11,040 --> 07:11:13,798
it's way too big um but in go we
10226
07:11:13,798 --> 07:11:15,440
typically don't have all that many
10227
07:11:15,440 --> 07:11:17,520
dependencies so it's actually perfectly
10228
07:11:17,520 --> 07:11:20,120
fine to commit the vendor folder in most
10229
07:11:20,120 --> 07:11:22,160
scenarios and I'd even recommend it so
10230
07:11:22,160 --> 07:11:24,200
I'm going to go ahead and add that and
10231
07:11:24,200 --> 07:11:26,200
commit
10232
07:11:26,200 --> 07:11:28,878
it we'll say
10233
07:11:28,878 --> 07:11:32,000
boilerplate or http
10234
07:11:32,000 --> 07:11:33,520
server
10235
07:11:33,520 --> 07:11:35,840
complete for this project we're going to
10236
07:11:35,840 --> 07:11:38,478
use postgress as our SQL database it's a
10237
07:11:38,478 --> 07:11:40,160
production ready database in fact it's
10238
07:11:40,160 --> 07:11:42,440
the one I used to build
10239
07:11:42,440 --> 07:11:45,280
boot. you're going to need to install
10240
07:11:45,280 --> 07:11:47,478
postgress on your local machine make
10241
07:11:47,478 --> 07:11:49,798
sure that the postgress server is up and
10242
07:11:49,798 --> 07:11:51,878
running and that you have a client
10243
07:11:51,878 --> 07:11:54,160
installed that you can use to make kind
10244
07:11:54,160 --> 07:11:57,520
of oneoff SQL queries against it I have
10245
07:11:57,520 --> 07:11:59,200
detailed instructions on how to do all
10246
07:11:59,200 --> 07:12:01,360
of that in the text instructions for
10247
07:12:01,360 --> 07:12:03,760
this project over on boot. so again go
10248
07:12:03,760 --> 07:12:05,280
check those out if you need to figure
10249
07:12:05,280 --> 07:12:08,080
out how to install postgress locally and
10250
07:12:08,080 --> 07:12:10,280
get a postgress client up and running on
10251
07:12:10,280 --> 07:12:12,680
your machine I use PG admin so that's
10252
07:12:12,680 --> 07:12:14,638
what you'll see me using in this
10253
07:12:14,638 --> 07:12:16,920
tutorial so if you followed those
10254
07:12:16,920 --> 07:12:18,320
instructions then you should have a
10255
07:12:18,320 --> 07:12:19,920
postgress server running on your local
10256
07:12:19,920 --> 07:12:22,680
machine and a postgress client installed
10257
07:12:22,680 --> 07:12:24,760
again I use PG admin that's what you're
10258
07:12:24,760 --> 07:12:28,558
seeing here on the screen okay so
10259
07:12:28,558 --> 07:12:30,798
because postgress is running locally I
10260
07:12:30,798 --> 07:12:33,920
have this Local Host server here in PG
10261
07:12:33,920 --> 07:12:35,798
admin that I've connected to again
10262
07:12:35,798 --> 07:12:37,160
that's the postgress server running on
10263
07:12:37,160 --> 07:12:39,398
my own machine and under databases I
10264
07:12:39,398 --> 07:12:41,160
have kind of the built-in postgress
10265
07:12:41,160 --> 07:12:43,120
database but I want to create a new
10266
07:12:43,120 --> 07:12:44,718
database that we're going to use for
10267
07:12:44,718 --> 07:12:47,200
this project so um in this case I'm just
10268
07:12:47,200 --> 07:12:49,840
going to name it uh RSS
10269
07:12:49,840 --> 07:12:52,958
a and we'll create that
10270
07:12:52,958 --> 07:12:56,200
database and then here within the RSS a
10271
07:12:56,200 --> 07:12:59,878
database as long as the uh kind of icons
10272
07:12:59,878 --> 07:13:02,320
are gold then you're connected and
10273
07:13:02,320 --> 07:13:04,360
everything is working at least up to
10274
07:13:04,360 --> 07:13:06,600
this point let's run a quick query
10275
07:13:06,600 --> 07:13:08,360
against the database just to really make
10276
07:13:08,360 --> 07:13:09,878
sure everything's working so I'm right
10277
07:13:09,878 --> 07:13:12,558
clicking here on the RSS a database and
10278
07:13:12,558 --> 07:13:15,478
I'm going to click query
10279
07:13:15,478 --> 07:13:17,958
tool and from this tool I should be able
10280
07:13:17,958 --> 07:13:19,718
to just write some raw SQL so I'm going
10281
07:13:19,718 --> 07:13:21,200
to go ahead and do a
10282
07:13:21,200 --> 07:13:24,360
select version this should just return
10283
07:13:24,360 --> 07:13:25,840
the current version of postgress that
10284
07:13:25,840 --> 07:13:29,878
I'm using I'm on version 14.7 and as
10285
07:13:29,878 --> 07:13:31,638
long as you're on something
10286
07:13:31,638 --> 07:13:34,920
14.7 or newer you should be good to go
10287
07:13:34,920 --> 07:13:36,520
now it's important to keep in mind here
10288
07:13:36,520 --> 07:13:39,200
that PG admin is just a client for
10289
07:13:39,200 --> 07:13:41,680
interacting with an SQL database right
10290
07:13:41,680 --> 07:13:44,440
we're able to write raw SQL code here
10291
07:13:44,440 --> 07:13:47,520
and run it against our database server
10292
07:13:47,520 --> 07:13:49,080
if you think about it kind of in an
10293
07:13:49,080 --> 07:13:51,638
analogous sense PG admin is basically
10294
07:13:51,638 --> 07:13:53,000
just the same thing as the Thunder
10295
07:13:53,000 --> 07:13:55,478
client where the Thunder client is a
10296
07:13:55,478 --> 07:13:57,958
client for running one-off HTTP requests
10297
07:13:57,958 --> 07:14:01,160
against our server PG admin is a client
10298
07:14:01,160 --> 07:14:04,440
for running oneoff SQL requests or SQL
10299
07:14:04,440 --> 07:14:07,320
queries against our database directly
10300
07:14:07,320 --> 07:14:08,840
next we're going to install two command
10301
07:14:08,840 --> 07:14:10,840
line tools that will allow us to work
10302
07:14:10,840 --> 07:14:14,240
with SQL databases from our go code much
10303
07:14:14,240 --> 07:14:16,398
easier now these aren't fully-fledged
10304
07:14:16,398 --> 07:14:18,798
orms if you're familiar with that term
10305
07:14:18,798 --> 07:14:20,520
these are kind of lightweight libraries
10306
07:14:20,520 --> 07:14:22,478
that allow us to work with SQL databases
10307
07:14:22,478 --> 07:14:24,200
using the standard library and just sort
10308
07:14:24,200 --> 07:14:26,080
of streamline the process for us the
10309
07:14:26,080 --> 07:14:27,440
first one is called
10310
07:14:27,440 --> 07:14:30,280
sqlc and again you can find all of these
10311
07:14:30,280 --> 07:14:32,080
commands in in the text instructions
10312
07:14:32,080 --> 07:14:34,160
over on bootd so be sure to be following
10313
07:14:34,160 --> 07:14:35,760
along over there but we're going to use
10314
07:14:35,760 --> 07:14:39,360
the go install command to go grab uh
10315
07:14:39,360 --> 07:14:42,120
sqlc and install it into our command
10316
07:14:42,120 --> 07:14:44,120
line once that's done you should be able
10317
07:14:44,120 --> 07:14:45,240
to just run
10318
07:14:45,240 --> 07:14:49,000
sqlc version to make sure it's working
10319
07:14:49,000 --> 07:14:52,120
next we'll install Goose the same way so
10320
07:14:52,120 --> 07:14:55,280
go install um and then the installation
10321
07:14:55,280 --> 07:14:58,240
path for goose again uh that link is
10322
07:14:58,240 --> 07:15:00,398
over in the text instructions and then
10323
07:15:00,398 --> 07:15:01,840
you can make sure that goose is
10324
07:15:01,840 --> 07:15:03,360
installed working correctly by typing
10325
07:15:03,360 --> 07:15:06,760
Goose Das version the great thing about
10326
07:15:06,760 --> 07:15:09,440
sqlc and goose is that they work based
10327
07:15:09,440 --> 07:15:12,320
on Raw SQL there's no kind of fancy
10328
07:15:12,320 --> 07:15:14,240
query language that's unique to those
10329
07:15:14,240 --> 07:15:16,280
tools we can just write SQL queries and
10330
07:15:16,280 --> 07:15:17,798
we're going to store all of that in our
10331
07:15:17,798 --> 07:15:19,958
repository so I'm going to create a new
10332
07:15:19,958 --> 07:15:22,520
folder is called SQL and in there I'll
10333
07:15:22,520 --> 07:15:25,520
create a new directory called schema and
10334
07:15:25,520 --> 07:15:27,320
this is where we'll store all of our
10335
07:15:27,320 --> 07:15:29,120
table definitions um or more
10336
07:15:29,120 --> 07:15:32,398
specifically our migrations so uh we'll
10337
07:15:32,398 --> 07:15:34,718
start with a users table and the way
10338
07:15:34,718 --> 07:15:37,000
Goose works is it runs the migrations in
10339
07:15:37,000 --> 07:15:39,280
order so we're going to start with
10340
07:15:39,280 --> 07:15:43,558
a01 migration and we'll call it users.
10341
07:15:43,558 --> 07:15:46,798
SQL from a very high level the way that
10342
07:15:46,798 --> 07:15:49,320
database migrations work is they have an
10343
07:15:49,320 --> 07:15:52,000
up and a down statement so for example
10344
07:15:52,000 --> 07:15:54,160
here we're creating a users table the up
10345
07:15:54,160 --> 07:15:56,240
statement will just create a new users
10346
07:15:56,240 --> 07:15:58,680
table and the down statement will delete
10347
07:15:58,680 --> 07:16:01,200
that same table so any down statement
10348
07:16:01,200 --> 07:16:03,440
should just undo the operation of the up
10349
07:16:03,440 --> 07:16:05,600
statement and that just makes it easy to
10350
07:16:05,600 --> 07:16:08,478
roll back changes to our database schema
10351
07:16:08,478 --> 07:16:11,000
if we ever need to the goose command
10352
07:16:11,000 --> 07:16:13,320
line tool Works based off of SQL
10353
07:16:13,320 --> 07:16:15,080
comments so we'll start with a comment
10354
07:16:15,080 --> 07:16:20,080
Das Dash plus Goose
10355
07:16:20,200 --> 07:16:25,958
up and dash dash plus goose down and
10356
07:16:25,958 --> 07:16:28,240
then anything we type here uh will be
10357
07:16:28,240 --> 07:16:30,240
considered an up migration and anything
10358
07:16:30,240 --> 07:16:32,760
here will be a down migration so let's
10359
07:16:32,760 --> 07:16:34,520
start with the up migration it's going
10360
07:16:34,520 --> 07:16:35,558
to be
10361
07:16:35,558 --> 07:16:38,840
create create table
10362
07:16:38,840 --> 07:16:41,120
users and the first field will just be
10363
07:16:41,120 --> 07:16:43,320
called ID it'll be a uyu ID a
10364
07:16:43,320 --> 07:16:45,840
universally unique identifier um I
10365
07:16:45,840 --> 07:16:49,120
prefer uu IDs to integer primary keys
10366
07:16:49,120 --> 07:16:51,360
for a number of reasons um I'll link a
10367
07:16:51,360 --> 07:16:54,040
blog post down in the description below
10368
07:16:54,040 --> 07:16:56,878
um and that's just going to be a primary
10369
07:16:56,878 --> 07:16:58,798
key uh next we're going to need a
10370
07:16:58,798 --> 07:17:02,360
created at which is a a
10371
07:17:02,360 --> 07:17:06,040
timestamp not null we must have must
10372
07:17:06,040 --> 07:17:08,638
have a created at must have an updated
10373
07:17:08,638 --> 07:17:11,280
at same
10374
07:17:12,200 --> 07:17:14,600
thing and then a user will also have a
10375
07:17:14,600 --> 07:17:17,680
name and we'll just make that a text
10376
07:17:17,680 --> 07:17:21,520
field again let's say that's not null I
10377
07:17:21,520 --> 07:17:23,398
need to remember to terminate my SQL
10378
07:17:23,398 --> 07:17:25,840
statements with a semicolon and for the
10379
07:17:25,840 --> 07:17:27,798
down M migration um it's pretty simple
10380
07:17:27,798 --> 07:17:30,520
we'll just drop the table so drop table
10381
07:17:30,520 --> 07:17:33,000
user users all right let's run our
10382
07:17:33,000 --> 07:17:35,120
migration but first we're going to need
10383
07:17:35,120 --> 07:17:36,440
to be able to connect to our local
10384
07:17:36,440 --> 07:17:38,840
database from our program and from our
10385
07:17:38,840 --> 07:17:41,360
command line so uh very first thing is
10386
07:17:41,360 --> 07:17:44,520
we'll need a DB
10387
07:17:44,520 --> 07:17:47,798
URL and we'll set it equal to the URL
10388
07:17:47,798 --> 07:17:49,638
that we use to connect to our local
10389
07:17:49,638 --> 07:17:51,240
postgress server so this isn't to
10390
07:17:51,240 --> 07:17:53,718
connect to PG admin this is the same
10391
07:17:53,718 --> 07:17:56,000
connection string that PG admin uses to
10392
07:17:56,000 --> 07:17:57,680
connect to the database server we want
10393
07:17:57,680 --> 07:18:00,160
to go directly to the database so it's
10394
07:18:00,160 --> 07:18:01,558
going to look something like this
10395
07:18:01,558 --> 07:18:05,680
postgress is the protocol so colon SL um
10396
07:18:05,680 --> 07:18:08,040
again this is just a URL um and then we
10397
07:18:08,040 --> 07:18:10,320
have the authentication part uh which in
10398
07:18:10,320 --> 07:18:13,638
my case is Wags Lane because that's the
10399
07:18:13,638 --> 07:18:17,878
uh user on my machine um and then colon
10400
07:18:17,878 --> 07:18:20,200
and then password if you have a password
10401
07:18:20,200 --> 07:18:22,160
for your local database this is where it
10402
07:18:22,160 --> 07:18:24,120
goes I actually did not set one up
10403
07:18:24,120 --> 07:18:25,680
because it's just my local
10404
07:18:25,680 --> 07:18:28,440
database and it's going to be at Local
10405
07:18:28,440 --> 07:18:31,360
Host col5
10406
07:18:31,360 --> 07:18:34,958
432 which is the standard port for
10407
07:18:34,958 --> 07:18:37,398
postgress and the last part of the URL
10408
07:18:37,398 --> 07:18:39,520
is just going to be the database name uh
10409
07:18:39,520 --> 07:18:41,000
that you created so in my case I believe
10410
07:18:41,000 --> 07:18:45,040
it was RSS a okay so your url will
10411
07:18:45,040 --> 07:18:46,558
should look very similar to this with
10412
07:18:46,558 --> 07:18:48,798
maybe you know the username the database
10413
07:18:48,798 --> 07:18:50,320
name um something like that could be
10414
07:18:50,320 --> 07:18:52,320
could potentially be swapped out on your
10415
07:18:52,320 --> 07:18:56,798
machine okay to run our migration here
10416
07:18:56,798 --> 07:18:59,760
I'm going to copy I'm going to copy this
10417
07:18:59,760 --> 07:19:02,040
database URL
10418
07:19:02,040 --> 07:19:04,320
and then I'm going to CD into this
10419
07:19:04,320 --> 07:19:07,080
directory so CD SQL
10420
07:19:07,080 --> 07:19:09,600
schema and then from here I can run
10421
07:19:09,600 --> 07:19:11,160
Goose
10422
07:19:11,160 --> 07:19:13,360
postgress so I'm telling I'm telling
10423
07:19:13,360 --> 07:19:15,080
Goose that hey I'm using a postgress
10424
07:19:15,080 --> 07:19:16,920
database and then I'll paste in my
10425
07:19:16,920 --> 07:19:17,920
connection
10426
07:19:17,920 --> 07:19:21,040
string and type up so this will run the
10427
07:19:21,040 --> 07:19:24,558
up migration a nasty error here turns
10428
07:19:24,558 --> 07:19:27,120
out I forgot some commas we need to
10429
07:19:27,120 --> 07:19:29,200
separate all of these field names with
10430
07:19:29,200 --> 07:19:33,718
commas cool save that file let's try
10431
07:19:33,718 --> 07:19:38,200
again so we got okay 001 users. SQL no
10432
07:19:38,200 --> 07:19:40,360
more migrations so that should have run
10433
07:19:40,360 --> 07:19:42,200
let's check PG admin to make sure that
10434
07:19:42,200 --> 07:19:44,840
it worked so now over in PG admin under
10435
07:19:44,840 --> 07:19:47,000
my RSS a database I should be able to
10436
07:19:47,000 --> 07:19:52,040
come into the schemas tab the tables tag
10437
07:19:52,040 --> 07:19:54,160
and I can see here that I've now have
10438
07:19:54,160 --> 07:19:56,760
two tables Goose DB version so this is
10439
07:19:56,760 --> 07:19:59,240
an automatic table created and managed
10440
07:19:59,240 --> 07:20:01,080
by goose and then I've got the users
10441
07:20:01,080 --> 07:20:03,000
table that I just created let's go ahead
10442
07:20:03,000 --> 07:20:06,558
and do a select star from users and we
10443
07:20:06,558 --> 07:20:08,680
should just be able to see uh those
10444
07:20:08,680 --> 07:20:10,840
column names come back now let's make
10445
07:20:10,840 --> 07:20:12,798
sure that the down migration works as
10446
07:20:12,798 --> 07:20:15,398
well go ahead and run the exact same
10447
07:20:15,398 --> 07:20:18,000
thing but this time down instead and you
10448
07:20:18,000 --> 07:20:20,320
can see that it down migrated the same
10449
07:20:20,320 --> 07:20:23,440
file now over in PG admin if I
10450
07:20:23,440 --> 07:20:25,878
rightclick on tables and click refresh
10451
07:20:25,878 --> 07:20:27,638
you'll see the users table's gone and
10452
07:20:27,638 --> 07:20:30,000
this query should fail now okay so let's
10453
07:20:30,000 --> 07:20:32,240
reup migrate to get that database table
10454
07:20:32,240 --> 07:20:34,000
created again and then the interesting
10455
07:20:34,000 --> 07:20:35,958
thing about migrations is you can rerun
10456
07:20:35,958 --> 07:20:38,080
the same up migration and you won't get
10457
07:20:38,080 --> 07:20:40,160
any errors because Goose knows that
10458
07:20:40,160 --> 07:20:42,558
you're already migrated up to the most
10459
07:20:42,558 --> 07:20:45,360
recent version of your migrations now
10460
07:20:45,360 --> 07:20:47,680
it's time to write a query so we're
10461
07:20:47,680 --> 07:20:50,320
using sqlc to handle our queries and
10462
07:20:50,320 --> 07:20:52,280
Goose to handle our migrations so to get
10463
07:20:52,280 --> 07:20:55,080
sqlc set up we need to create a new file
10464
07:20:55,080 --> 07:20:57,840
in the root of our project called sqlc
10465
07:20:57,840 --> 07:21:00,000
do yaml I'm going to paste in this
10466
07:21:00,000 --> 07:21:01,680
configuration here basically it's just
10467
07:21:01,680 --> 07:21:04,680
telling sqlc what version we're using um
10468
07:21:04,680 --> 07:21:06,840
what database engine we're using and
10469
07:21:06,840 --> 07:21:09,478
where we're going to store our queries
10470
07:21:09,478 --> 07:21:11,718
the raw SQL for our queries are going to
10471
07:21:11,718 --> 07:21:13,638
live in the SQL directory under a new
10472
07:21:13,638 --> 07:21:16,240
subdirectory called queries we've
10473
07:21:16,240 --> 07:21:19,200
specified that here right and here I'm
10474
07:21:19,200 --> 07:21:20,360
going to create a new file I'm just
10475
07:21:20,360 --> 07:21:24,000
going to call it users.
10476
07:21:24,000 --> 07:21:26,478
SQL and again this is where the SQL will
10477
07:21:26,478 --> 07:21:29,200
live and the way sqlc works is that it
10478
07:21:29,200 --> 07:21:32,040
takes the SQL statements and it
10479
07:21:32,040 --> 07:21:35,558
generates go code Type safe go code that
10480
07:21:35,558 --> 07:21:39,440
matches the SQL every sqlc query starts
10481
07:21:39,440 --> 07:21:42,000
off with a comment that starts with its
10482
07:21:42,000 --> 07:21:45,160
name so name will do a create user
10483
07:21:45,160 --> 07:21:48,878
statement and it returns one record so
10484
07:21:48,878 --> 07:21:51,120
we're saying I want a new function
10485
07:21:51,120 --> 07:21:53,600
called create user oops and it's going
10486
07:21:53,600 --> 07:21:56,558
to return one user that statement will
10487
07:21:56,558 --> 07:22:02,398
be insert into users uh ID created
10488
07:22:02,398 --> 07:22:06,958
Created at updated at and
10489
07:22:06,958 --> 07:22:09,240
name
10490
07:22:09,240 --> 07:22:12,240
values dollar sign
10491
07:22:12,240 --> 07:22:16,558
one dollar sign 2 dollar sign 3 dollar
10492
07:22:16,558 --> 07:22:19,680
sign 4 okay so what's this nonsense
10493
07:22:19,680 --> 07:22:25,120
right in sqlc each dollar sign number is
10494
07:22:25,120 --> 07:22:27,000
interpolated with the parameters for the
10495
07:22:27,000 --> 07:22:29,080
function so this statement will create a
10496
07:22:29,080 --> 07:22:31,000
new function called create user
10497
07:22:31,000 --> 07:22:33,878
with four parameters and the first
10498
07:22:33,878 --> 07:22:36,558
parameter will will go in right here the
10499
07:22:36,558 --> 07:22:38,478
second one the third one the fourth one
10500
07:22:38,478 --> 07:22:40,760
Etc so it allows us to create queries
10501
07:22:40,760 --> 07:22:43,398
that take arguments as input and then
10502
07:22:43,398 --> 07:22:46,520
we'll end the query with just return
10503
07:22:46,520 --> 07:22:48,318
returning
10504
07:22:48,318 --> 07:22:52,958
returning star okay we want to create a
10505
07:22:52,958 --> 07:22:55,478
new user and return that record right we
10506
07:22:55,478 --> 07:22:58,240
we expect one record back now let's use
10507
07:22:58,240 --> 07:23:01,080
sqlc to actually generate the go code
10508
07:23:01,080 --> 07:23:04,478
for this query we always run sqlc from
10509
07:23:04,478 --> 07:23:06,840
the root of our package rather than
10510
07:23:06,840 --> 07:23:09,680
within the query's directory itself um
10511
07:23:09,680 --> 07:23:10,840
and the reason that works is because we
10512
07:23:10,840 --> 07:23:13,680
have this sqlc do yaml file at the top
10513
07:23:13,680 --> 07:23:16,360
level okay so if everything was written
10514
07:23:16,360 --> 07:23:19,600
correctly we should be able to do sqlc
10515
07:23:19,600 --> 07:23:23,040
generate and what happens is it goes and
10516
07:23:23,040 --> 07:23:26,958
reads that query and it also reads our
10517
07:23:26,958 --> 07:23:28,000
table
10518
07:23:28,000 --> 07:23:31,638
definitions which we've specified here
10519
07:23:31,638 --> 07:23:35,200
right SQL schema so it knows the shape
10520
07:23:35,200 --> 07:23:38,040
of our tables and it knows the query we
10521
07:23:38,040 --> 07:23:39,520
want to create and it can go
10522
07:23:39,520 --> 07:23:41,718
automatically generate all of this go
10523
07:23:41,718 --> 07:23:45,280
code in the internal SL database package
10524
07:23:45,280 --> 07:23:47,478
now we need to actually use the database
10525
07:23:47,478 --> 07:23:50,280
in our go code so here in main.go I'm
10526
07:23:50,280 --> 07:23:53,798
going to create a new struct called API
10527
07:23:53,798 --> 07:23:55,478
config and it's going to hold a
10528
07:23:55,478 --> 07:23:58,958
connection to a database now this
10529
07:23:58,958 --> 07:24:01,040
database. queries type is actually
10530
07:24:01,040 --> 07:24:03,680
exposed by that code that we generated
10531
07:24:03,680 --> 07:24:05,360
using sqlc so you can poke around
10532
07:24:05,360 --> 07:24:06,878
through this package and kind of get
10533
07:24:06,878 --> 07:24:09,040
familiar with the generated code we
10534
07:24:09,040 --> 07:24:11,840
never manually update this code that's
10535
07:24:11,840 --> 07:24:14,200
generated by sqlc it's completely
10536
07:24:14,200 --> 07:24:16,000
managed by sqlc we're just going to
10537
07:24:16,000 --> 07:24:19,638
write raw SQL to generate this code okay
10538
07:24:19,638 --> 07:24:22,120
uh next thing we need to do is import
10539
07:24:22,120 --> 07:24:26,478
our database connection so here in EnV
10540
07:24:26,478 --> 07:24:31,160
we have our DB URL and we need to
10541
07:24:31,160 --> 07:24:33,520
grab that um and pull it into our
10542
07:24:33,520 --> 07:24:35,958
application we're also going to need to
10543
07:24:35,958 --> 07:24:39,240
disable SSL mode so SSL mode equals
10544
07:24:39,240 --> 07:24:41,398
disable um and it just this just tells
10545
07:24:41,398 --> 07:24:43,040
our code hey we don't need to be
10546
07:24:43,040 --> 07:24:46,440
connecting to our local database um
10547
07:24:46,440 --> 07:24:49,200
using encryption uh we kind of trust our
10548
07:24:49,200 --> 07:24:52,718
local database so we'll parse that as a
10549
07:24:52,718 --> 07:24:56,398
string so I'll do DB
10550
07:24:56,398 --> 07:25:00,878
URL and if the database URL is not found
10551
07:25:00,878 --> 07:25:01,638
then
10552
07:25:01,638 --> 07:25:04,840
we'll we'll report a message uh or we'll
10553
07:25:04,840 --> 07:25:07,878
log an error message and exit after that
10554
07:25:07,878 --> 07:25:08,718
we need to actually connect to the
10555
07:25:08,718 --> 07:25:10,600
database so the ghost standard library
10556
07:25:10,600 --> 07:25:13,798
has a built-in SQL package we can do SQL
10557
07:25:13,798 --> 07:25:16,478
doop the driver name that we'll be using
10558
07:25:16,478 --> 07:25:18,798
is just
10559
07:25:19,040 --> 07:25:21,360
postgress and then we can pass in the
10560
07:25:21,360 --> 07:25:23,798
connection string and this will return a
10561
07:25:23,798 --> 07:25:25,958
new connection and an
10562
07:25:25,958 --> 07:25:29,240
error and again if there's an
10563
07:25:29,240 --> 07:25:31,680
error we'll just go ahead and log a
10564
07:25:31,680 --> 07:25:34,160
message and
10565
07:25:36,478 --> 07:25:40,600
exit can't connect to
10566
07:25:40,600 --> 07:25:42,878
database now this is kind of a weird
10567
07:25:42,878 --> 07:25:44,718
quirky thing about how go handles
10568
07:25:44,718 --> 07:25:47,760
databases but we actually need to import
10569
07:25:47,760 --> 07:25:51,280
a database driver into our program um
10570
07:25:51,280 --> 07:25:52,440
but we don't actually need to call
10571
07:25:52,440 --> 07:25:54,638
anything from it so the sqlc docs
10572
07:25:54,638 --> 07:25:56,200
mention this but basically we just need
10573
07:25:56,200 --> 07:25:58,318
to include this line at the top of our
10574
07:25:58,318 --> 07:26:01,318
program and we do need to import it so
10575
07:26:01,318 --> 07:26:05,200
I'll do a goget um on that
10576
07:26:05,200 --> 07:26:07,680
libpq and we'll import it using that
10577
07:26:07,680 --> 07:26:10,120
underscore just to say include this code
10578
07:26:10,120 --> 07:26:12,200
in my program um even though I'm not
10579
07:26:12,200 --> 07:26:16,000
calling it directly okay with that there
10580
07:26:16,000 --> 07:26:17,718
uh now we should be able to create a new
10581
07:26:17,718 --> 07:26:19,558
API
10582
07:26:19,558 --> 07:26:24,360
config and let's just call it API
10583
07:26:24,760 --> 07:26:29,040
CFG and it takes as one of its Fields a
10584
07:26:29,040 --> 07:26:31,360
DB
10585
07:26:31,360 --> 07:26:35,478
where am I at I think I scrolled too
10586
07:26:36,240 --> 07:26:40,760
far BB oh and I should probably go mod
10587
07:26:40,760 --> 07:26:44,478
tidy and go mod
10588
07:26:44,478 --> 07:26:46,878
vendor so that I stop getting weird
10589
07:26:46,878 --> 07:26:50,280
errors in my in my vs
10590
07:26:50,280 --> 07:26:53,398
code okay uh this API CFG takes a
10591
07:26:53,398 --> 07:26:55,398
database. queries but if you look here
10592
07:26:55,398 --> 07:26:56,760
we don't have a database. queries we
10593
07:26:56,760 --> 07:26:58,638
have an SQL DB so we actually need to
10594
07:26:58,638 --> 07:27:02,080
convert it into a connection to our
10595
07:27:02,080 --> 07:27:06,040
package and we can do that with
10596
07:27:06,040 --> 07:27:09,600
database. new and we pass it as input
10597
07:27:09,600 --> 07:27:11,878
the connection and we'll get back
10598
07:27:11,878 --> 07:27:14,040
queries
10599
07:27:14,040 --> 07:27:19,360
eror here we can say if er do not equal
10600
07:27:27,240 --> 07:27:30,638
nil and pass in the queries
10601
07:27:30,638 --> 07:27:32,160
to the
10602
07:27:32,160 --> 07:27:34,520
struct no did I do that wrong maybe this
10603
07:27:34,520 --> 07:27:35,958
doesn't return an
10604
07:27:35,958 --> 07:27:38,000
error mismatch two variables but
10605
07:27:38,000 --> 07:27:39,600
database. new returns one okay cool so
10606
07:27:39,600 --> 07:27:41,040
this actually can't fail it's just a
10607
07:27:41,040 --> 07:27:42,958
it's just a simple
10608
07:27:42,958 --> 07:27:44,718
conversion we could actually even just
10609
07:27:44,718 --> 07:27:47,200
do this it's probably
10610
07:27:47,200 --> 07:27:50,840
easier great now we have an API config
10611
07:27:50,840 --> 07:27:53,080
that we can pass into our handlers so
10612
07:27:53,080 --> 07:27:56,360
that they have access to our database
10613
07:27:56,360 --> 07:27:58,680
let's write that create user Handler
10614
07:27:58,680 --> 07:27:59,840
okay so I'm just going to copy paste
10615
07:27:59,840 --> 07:28:02,000
this Handler Readiness and change it to
10616
07:28:02,000 --> 07:28:04,478
Handler
10617
07:28:04,478 --> 07:28:06,798
user and we'll update this to say
10618
07:28:06,798 --> 07:28:10,120
Handler this will be the create user
10619
07:28:10,120 --> 07:28:12,520
Handler now here's the interesting thing
10620
07:28:12,520 --> 07:28:15,398
about HTTP handlers in go the function
10621
07:28:15,398 --> 07:28:18,520
signature can't change but we do want to
10622
07:28:18,520 --> 07:28:22,160
pass into this function an additional
10623
07:28:22,160 --> 07:28:23,958
piece of data we want
10624
07:28:23,958 --> 07:28:28,000
to add this API config so the way we do
10625
07:28:28,000 --> 07:28:31,360
it is by making this function a method
10626
07:28:31,360 --> 07:28:33,280
so we do API
10627
07:28:33,280 --> 07:28:38,240
CFG is a pointer to an API config so our
10628
07:28:38,240 --> 07:28:40,240
function signature Remains the
10629
07:28:40,240 --> 07:28:42,398
Same right it still just accepts these
10630
07:28:42,398 --> 07:28:44,200
two parameters um but now we have some
10631
07:28:44,200 --> 07:28:46,318
additional data stored on the struct
10632
07:28:46,318 --> 07:28:49,440
itself uh that we can gain access to and
10633
07:28:49,440 --> 07:28:51,520
let's hook up this create user Handler
10634
07:28:51,520 --> 07:28:52,760
in
10635
07:28:52,760 --> 07:28:56,520
main so we'll add it to the V1 Handler
10636
07:28:56,520 --> 07:29:00,440
we'll do V1 router Dot
10637
07:29:00,440 --> 07:29:02,798
post we want this to be a post request
10638
07:29:02,798 --> 07:29:04,440
to/
10639
07:29:04,440 --> 07:29:07,958
users and we want to use
10640
07:29:07,958 --> 07:29:12,558
the create Handler create user method
10641
07:29:12,558 --> 07:29:15,080
which we defined on this struct so we
10642
07:29:15,080 --> 07:29:19,760
can pass in API CFG do Handler create
10643
07:29:19,760 --> 07:29:22,160
user and now our Handler will have
10644
07:29:22,160 --> 07:29:26,600
access to um to the database okay
10645
07:29:26,600 --> 07:29:30,840
cool this Handler needs to take as input
10646
07:29:30,840 --> 07:29:33,200
a Json body it should
10647
07:29:33,200 --> 07:29:37,360
expect some parameters so we'll do type
10648
07:29:37,360 --> 07:29:40,558
parameters is instruct and I think for
10649
07:29:40,558 --> 07:29:43,000
now we just need a
10650
07:29:43,000 --> 07:29:46,000
name and we need to parse the request
10651
07:29:46,000 --> 07:29:49,398
body into this struct so we'll do json.
10652
07:29:49,398 --> 07:29:50,478
new
10653
07:29:50,478 --> 07:29:53,440
decoder and r.
10654
07:29:53,440 --> 07:29:56,000
body okay and this respond or this
10655
07:29:56,000 --> 07:29:59,680
returns a decoder
10656
07:30:01,000 --> 07:30:03,478
we do decoder do
10657
07:30:03,478 --> 07:30:07,000
decode and we want to decode into an
10658
07:30:07,000 --> 07:30:08,840
instance of the parameter struct so
10659
07:30:08,840 --> 07:30:12,600
we'll do prams is an empty parameter
10660
07:30:12,600 --> 07:30:15,798
struct and we'll decode
10661
07:30:15,798 --> 07:30:20,160
into a pointer to parameters and this
10662
07:30:20,160 --> 07:30:23,840
returns an error if anything goes
10663
07:30:25,240 --> 07:30:27,878
wrong if there is an error then we
10664
07:30:27,878 --> 07:30:30,040
should use that Handler function that we
10665
07:30:30,040 --> 07:30:32,600
made earlier respond with error and say
10666
07:30:32,600 --> 07:30:35,200
something like well we need to pass in W
10667
07:30:35,200 --> 07:30:36,398
um if something goes wrong here it's
10668
07:30:36,398 --> 07:30:38,000
probably a client side error right so
10669
07:30:38,000 --> 07:30:39,440
I'm just going to pass in a
10670
07:30:39,440 --> 07:30:41,638
400 and we'll
10671
07:30:41,638 --> 07:30:42,670
say
10672
07:30:42,670 --> 07:30:45,710
[Music]
10673
07:30:46,440 --> 07:30:52,318
um let's see error parsing
10674
07:30:55,200 --> 07:30:59,000
Json cool and then we'll return because
10675
07:30:59,000 --> 07:31:00,958
we're done at that that point if there
10676
07:31:00,958 --> 07:31:04,398
is an issue okay uh otherwise we have
10677
07:31:04,398 --> 07:31:07,120
access to a name so we can use our
10678
07:31:07,120 --> 07:31:10,360
database to create a user so we do API
10679
07:31:10,360 --> 07:31:12,478
CFG do
10680
07:31:12,478 --> 07:31:16,558
db. create user now this is the method
10681
07:31:16,558 --> 07:31:19,840
that sqlc generated for us right because
10682
07:31:19,840 --> 07:31:23,558
it it read our create user SQL and it
10683
07:31:23,558 --> 07:31:26,798
created a create user function for us
10684
07:31:26,798 --> 07:31:29,360
right and it created the parameters as a
10685
07:31:29,360 --> 07:31:31,040
struct so that's pretty
10686
07:31:31,040 --> 07:31:33,000
convenient uh let's see how this works
10687
07:31:33,000 --> 07:31:36,520
so create user accepts a context and
10688
07:31:36,520 --> 07:31:38,240
some create user pram so I'm going to
10689
07:31:38,240 --> 07:31:41,080
use uh I think
10690
07:31:41,080 --> 07:31:47,200
it's CTX no r. context there we go so
10691
07:31:47,200 --> 07:31:50,240
that's the context for this request and
10692
07:31:50,240 --> 07:31:52,878
then we pass in database. create user
10693
07:31:52,878 --> 07:31:55,520
prams this is struct and it should have
10694
07:31:55,520 --> 07:31:59,680
yep all of our uh types that we need to
10695
07:31:59,680 --> 07:32:02,398
pass pass into the create user function
10696
07:32:02,398 --> 07:32:05,520
okay so uh first things first an
10697
07:32:05,520 --> 07:32:08,040
ID the ID is a
10698
07:32:08,040 --> 07:32:11,240
uuid um and this is the first point at
10699
07:32:11,240 --> 07:32:12,478
which I think we've needed to use them
10700
07:32:12,478 --> 07:32:14,280
so we're going to have to import this
10701
07:32:14,280 --> 07:32:17,398
package so github.com gooogle uid this
10702
07:32:17,398 --> 07:32:21,600
is a very uh well-known uuid package in
10703
07:32:21,600 --> 07:32:25,718
go we will go get
10704
07:32:26,280 --> 07:32:28,558
it with that installed we should be able
10705
07:32:28,558 --> 07:32:31,398
to do you uu id.
10706
07:32:31,398 --> 07:32:34,160
new and that will just create a new
10707
07:32:34,160 --> 07:32:36,958
random uuid and if you weren't familiar
10708
07:32:36,958 --> 07:32:38,440
this is what a uu ID looks like in
10709
07:32:38,440 --> 07:32:41,318
string form it's basically just this
10710
07:32:41,318 --> 07:32:45,638
really long random uh bit of I mean in
10711
07:32:45,638 --> 07:32:47,478
this case represented as text that we
10712
07:32:47,478 --> 07:32:49,360
can use as a primary identifier for
10713
07:32:49,360 --> 07:32:51,000
every user so every user will get their
10714
07:32:51,000 --> 07:32:53,000
own random
10715
07:32:53,000 --> 07:32:57,760
ID cool um I should probably go mod tidy
10716
07:32:57,760 --> 07:32:59,958
go mod vendor
10717
07:32:59,958 --> 07:33:02,000
it's just good practice every time you
10718
07:33:02,000 --> 07:33:03,920
install a new package to make sure you
10719
07:33:03,920 --> 07:33:06,040
vendor it and go mod tidy kind of cleans
10720
07:33:06,040 --> 07:33:08,440
up any unused Imports um and resolve
10721
07:33:08,440 --> 07:33:09,520
some issues
10722
07:33:09,520 --> 07:33:12,440
there okay uh created at I'm going to
10723
07:33:12,440 --> 07:33:15,958
set to just time. now.
10724
07:33:15,958 --> 07:33:19,000
UTC created now and then updated at
10725
07:33:19,000 --> 07:33:20,398
should represent the last time it was
10726
07:33:20,398 --> 07:33:23,080
updated uh which would also be now right
10727
07:33:23,080 --> 07:33:25,440
because we're creating something new and
10728
07:33:25,440 --> 07:33:28,280
the user's name will just be pam. name
10729
07:33:28,280 --> 07:33:30,478
right it's whatever was passed in
10730
07:33:30,478 --> 07:33:33,520
to this HTTP request in the
10731
07:33:33,520 --> 07:33:36,160
body oh and I just am now realizing that
10732
07:33:36,160 --> 07:33:38,280
I messed up this Json tag should look
10733
07:33:38,280 --> 07:33:40,520
like
10734
07:33:41,440 --> 07:33:45,398
this okay cool um so create user should
10735
07:33:45,398 --> 07:33:47,798
probably return an error yep returns a
10736
07:33:47,798 --> 07:33:50,558
new user and an
10737
07:33:50,558 --> 07:33:52,558
error again if there was an error
10738
07:33:52,558 --> 07:33:54,760
creating the user we'll want to respond
10739
07:33:54,760 --> 07:33:56,000
with an
10740
07:33:56,000 --> 07:33:58,478
error and we'll
10741
07:33:58,478 --> 07:34:00,478
say good
10742
07:34:00,478 --> 07:34:03,318
create
10743
07:34:03,600 --> 07:34:07,638
user uh 400 seems fine and then we'll
10744
07:34:07,638 --> 07:34:11,000
actually respond with the user object
10745
07:34:11,000 --> 07:34:14,200
itself okay database. user and see how
10746
07:34:14,200 --> 07:34:15,680
that goes well let's let's actually take
10747
07:34:15,680 --> 07:34:17,600
a look and see what does a database.
10748
07:34:17,600 --> 07:34:20,360
user even look
10749
07:34:23,318 --> 07:34:25,240
like I'm
10750
07:34:25,240 --> 07:34:27,160
curious yeah so all these I mean all
10751
07:34:27,160 --> 07:34:28,958
these fields are exported so they should
10752
07:34:28,958 --> 07:34:30,878
Marshall to J on just fine let's go
10753
07:34:30,878 --> 07:34:33,280
ahead and run this and see and see what
10754
07:34:33,280 --> 07:34:34,878
we get before we run the code though it
10755
07:34:34,878 --> 07:34:35,878
looks like I've got a couple little
10756
07:34:35,878 --> 07:34:37,558
things to resolve here so errors is
10757
07:34:37,558 --> 07:34:40,878
already defined there and then here oh
10758
07:34:40,878 --> 07:34:42,680
I'm messing something up we need to pass
10759
07:34:42,680 --> 07:34:45,200
that in we need to interpolate that cool
10760
07:34:45,200 --> 07:34:47,398
oh and here as
10761
07:34:47,398 --> 07:34:50,680
well percent V because those are errors
10762
07:34:50,680 --> 07:34:53,360
okay cool um now let's go ahead and run
10763
07:34:53,360 --> 07:34:56,798
build and run the code so go build
10764
07:34:56,798 --> 07:35:00,798
and run RSS a
10765
07:35:00,798 --> 07:35:03,958
okay Ser server has started so let's go
10766
07:35:03,958 --> 07:35:06,280
ahead and open up the Thunder
10767
07:35:06,280 --> 07:35:09,760
client and now we'll be sending a post
10768
07:35:09,760 --> 07:35:12,760
request to the users's
10769
07:35:12,760 --> 07:35:17,760
endpoint and we'll be sending in a Json
10770
07:35:17,760 --> 07:35:23,600
body oh me grow this just a little
10771
07:35:23,680 --> 07:35:26,638
bit and we need to specify a name I'm
10772
07:35:26,638 --> 07:35:29,878
going to create a new user called Lane
10773
07:35:29,878 --> 07:35:32,638
and let's see what happens couldn't
10774
07:35:32,638 --> 07:35:36,798
create user database Wags Lane does not
10775
07:35:36,798 --> 07:35:39,280
exist it looks to me like I probably
10776
07:35:39,280 --> 07:35:41,280
messed up my connection string let's go
10777
07:35:41,280 --> 07:35:42,600
take a look at
10778
07:35:42,600 --> 07:35:45,718
that so here in
10779
07:35:45,718 --> 07:35:48,680
EnV yeah okay we forgot to or I forgot
10780
07:35:48,680 --> 07:35:51,440
to add um the name of the database here
10781
07:35:51,440 --> 07:35:55,160
at the end so uh we we need to do slash
10782
07:35:55,160 --> 07:35:57,000
name of database all right let's try
10783
07:35:57,000 --> 07:36:01,160
that again let's rebuild the server
10784
07:36:01,160 --> 07:36:04,160
and resend that request cool we got a
10785
07:36:04,160 --> 07:36:07,760
200 response it looks like that is a new
10786
07:36:07,760 --> 07:36:11,638
random ID great created at update at and
10787
07:36:11,638 --> 07:36:14,160
the name next just to make sure that the
10788
07:36:14,160 --> 07:36:15,760
record actually was created in the
10789
07:36:15,760 --> 07:36:17,718
database server itself I'm going to pop
10790
07:36:17,718 --> 07:36:22,680
back over here to PG admin um refresh my
10791
07:36:22,680 --> 07:36:24,878
tables there's our users table and rerun
10792
07:36:24,878 --> 07:36:27,798
this select star from users perfect
10793
07:36:27,798 --> 07:36:29,200
looks like we've got one record in here
10794
07:36:29,200 --> 07:36:31,360
with all of the data that I would expect
10795
07:36:31,360 --> 07:36:33,318
now I want to make one more optimization
10796
07:36:33,318 --> 07:36:35,280
to our code here you can see in this
10797
07:36:35,280 --> 07:36:38,120
Json response that the Fe the key names
10798
07:36:38,120 --> 07:36:40,878
in the Json object are the same as the
10799
07:36:40,878 --> 07:36:44,920
exported key names here in the user
10800
07:36:44,920 --> 07:36:47,080
struct in the database package now we
10801
07:36:47,080 --> 07:36:50,240
can't change this struct manually um
10802
07:36:50,240 --> 07:36:52,958
again this is generated by sqlc so what
10803
07:36:52,958 --> 07:36:56,240
I think we should do is instead create a
10804
07:36:56,240 --> 07:37:00,600
new models folder models. go
10805
07:37:00,600 --> 07:37:01,920
in the main
10806
07:37:01,920 --> 07:37:05,318
package and here we'll create our own
10807
07:37:05,318 --> 07:37:09,638
user type so type user struct and it
10808
07:37:09,638 --> 07:37:11,840
will be nearly identical so let me go
10809
07:37:11,840 --> 07:37:14,558
grab this one be nearly
10810
07:37:14,558 --> 07:37:16,520
identical the only difference at this
10811
07:37:16,520 --> 07:37:19,798
point is that I'm going to add Json
10812
07:37:19,798 --> 07:37:23,398
tags so that I can specify you know what
10813
07:37:23,398 --> 07:37:26,080
these names should be and we've been
10814
07:37:26,080 --> 07:37:28,478
using kind of this snake case convention
10815
07:37:28,478 --> 07:37:31,000
so I'm just going to stick with that so
10816
07:37:31,000 --> 07:37:35,000
updated at and name and I'm going to
10817
07:37:35,000 --> 07:37:37,920
create a function uh we'll say database
10818
07:37:37,920 --> 07:37:43,798
user to user and it will take a DB
10819
07:37:45,160 --> 07:37:49,360
user and return a user and all this does
10820
07:37:49,360 --> 07:37:53,280
is return a new user struct where uh
10821
07:37:53,280 --> 07:37:55,798
we've kind of populate it with all of
10822
07:37:55,798 --> 07:37:58,280
the all of the stuff from the database
10823
07:37:58,280 --> 07:38:01,120
user so again the purpose of this is
10824
07:38:01,120 --> 07:38:05,240
really just I want to own the shape um
10825
07:38:05,240 --> 07:38:07,240
that's being returned over the wire
10826
07:38:07,240 --> 07:38:10,240
right on our HTTP responses um and now I
10827
07:38:10,240 --> 07:38:11,878
have the power to configure that easily
10828
07:38:11,878 --> 07:38:13,760
within within my
10829
07:38:13,760 --> 07:38:16,160
application so we'll go ahead and just
10830
07:38:16,160 --> 07:38:20,080
uh paste these in
10831
07:38:22,600 --> 07:38:27,040
here okay and then in my user Handler
10832
07:38:27,040 --> 07:38:28,920
rather than responding with the database
10833
07:38:28,920 --> 07:38:32,398
user I'm going to respond with our
10834
07:38:32,398 --> 07:38:37,080
user cool let's rerun and build
10835
07:38:37,080 --> 07:38:40,680
that and let's run our query again now
10836
07:38:40,680 --> 07:38:43,040
remember we already have a user in our
10837
07:38:43,040 --> 07:38:45,680
database so I'm going
10838
07:38:45,680 --> 07:38:49,240
to create a second one uh let's call
10839
07:38:49,240 --> 07:38:51,520
this one
10840
07:38:51,718 --> 07:38:54,600
Rob and this time you can see we have
10841
07:38:54,600 --> 07:38:56,920
those snake case
10842
07:38:56,920 --> 07:39:00,760
keys and again I'm going to go check in
10843
07:39:00,760 --> 07:39:03,080
PG admin to make sure that Rob is there
10844
07:39:03,080 --> 07:39:05,398
perfect now we've got Lane and Rob and
10845
07:39:05,398 --> 07:39:06,958
you can see they have different randomly
10846
07:39:06,958 --> 07:39:09,120
generated IDs and their timestamps are
10847
07:39:09,120 --> 07:39:11,160
slightly different we're going to be
10848
07:39:11,160 --> 07:39:14,318
using API keys to authenticate our users
10849
07:39:14,318 --> 07:39:16,120
on This Server the nice thing about an
10850
07:39:16,120 --> 07:39:18,120
API key is Not only is a little more
10851
07:39:18,120 --> 07:39:20,360
secure than a username and a password
10852
07:39:20,360 --> 07:39:22,798
but because it's so long it also serves
10853
07:39:22,798 --> 07:39:25,638
as a unique ID for that user so we don't
10854
07:39:25,638 --> 07:39:27,478
even need a combo of username password
10855
07:39:27,478 --> 07:39:30,280
we can just use the API key in order to
10856
07:39:30,280 --> 07:39:33,120
kind of uniquely identify people so we
10857
07:39:33,120 --> 07:39:35,360
need to run a migration that adds a new
10858
07:39:35,360 --> 07:39:38,520
field to the user's table so that we can
10859
07:39:38,520 --> 07:39:40,680
store their API Keys now we've already
10860
07:39:40,680 --> 07:39:42,920
created this migration that creates the
10861
07:39:42,920 --> 07:39:44,478
users's table and we don't want to
10862
07:39:44,478 --> 07:39:46,558
modify this because it's generally a
10863
07:39:46,558 --> 07:39:48,958
really bad idea to go modifying your
10864
07:39:48,958 --> 07:39:50,718
existing migrations instead we create a
10865
07:39:50,718 --> 07:39:52,478
new one so I'm going to create a new one
10866
07:39:52,478 --> 07:39:54,558
and we'll call it 02 because we want it
10867
07:39:54,558 --> 07:39:57,798
to run after uh the first migration and
10868
07:39:57,798 --> 07:39:59,878
again Goose uses these numbers to know
10869
07:39:59,878 --> 07:40:02,200
in which order it should run uh the
10870
07:40:02,200 --> 07:40:07,000
migrations and we'll call it users API
10871
07:40:07,000 --> 07:40:10,440
key and the migration statements are
10872
07:40:10,440 --> 07:40:12,638
going to look a little bit different
10873
07:40:12,638 --> 07:40:14,680
okay so the up statement is going to be
10874
07:40:14,680 --> 07:40:18,638
an alter table so alter table users
10875
07:40:18,638 --> 07:40:20,318
We'll add a
10876
07:40:20,318 --> 07:40:22,718
column and we'll call the column just
10877
07:40:22,718 --> 07:40:26,280
API uncore key it's going to be a varar
10878
07:40:26,280 --> 07:40:27,160
so
10879
07:40:27,160 --> 07:40:29,638
varar 64 now the difference between
10880
07:40:29,638 --> 07:40:31,798
varar and text um at least for our
10881
07:40:31,798 --> 07:40:34,120
purposes here is that the varar is
10882
07:40:34,120 --> 07:40:36,478
exactly 64 characters long so we're
10883
07:40:36,478 --> 07:40:39,120
saying we want our API keys to be 64
10884
07:40:39,120 --> 07:40:42,080
characters long and we want those API
10885
07:40:42,080 --> 07:40:44,398
keys to be unique no two users should
10886
07:40:44,398 --> 07:40:47,000
have the same API key um we also don't
10887
07:40:47,000 --> 07:40:49,160
want them to be null and we're going to
10888
07:40:49,160 --> 07:40:50,600
set a
10889
07:40:50,600 --> 07:40:53,718
default a default API key and this is
10890
07:40:53,718 --> 07:40:55,398
important because if we didn't set a
10891
07:40:55,398 --> 07:40:57,760
default we'd run into an issue when we
10892
07:40:57,760 --> 07:41:00,120
run this migration remember we already
10893
07:41:00,120 --> 07:41:03,440
have two users in our database currently
10894
07:41:03,440 --> 07:41:06,160
so if we just try to add a column that
10895
07:41:06,160 --> 07:41:09,318
has these unique not null constraints on
10896
07:41:09,318 --> 07:41:12,200
it then what's the SQL database going to
10897
07:41:12,200 --> 07:41:15,000
do how is it going to generate new API
10898
07:41:15,000 --> 07:41:17,240
keys that are unique and not null
10899
07:41:17,240 --> 07:41:19,798
typically it would just default the new
10900
07:41:19,798 --> 07:41:21,440
um you you know the field in the
10901
07:41:21,440 --> 07:41:23,600
existing records to null but because
10902
07:41:23,600 --> 07:41:25,760
we've said they can't be null and they
10903
07:41:25,760 --> 07:41:28,920
must be unique we need to provide a
10904
07:41:28,920 --> 07:41:31,120
unique unique default for every new
10905
07:41:31,120 --> 07:41:33,240
record or for excuse me for every
10906
07:41:33,240 --> 07:41:36,520
existing record in the database so the
10907
07:41:36,520 --> 07:41:38,718
default value that we need to add again
10908
07:41:38,718 --> 07:41:41,200
needs to be unique for every person so
10909
07:41:41,200 --> 07:41:43,240
we're actually going to have to use some
10910
07:41:43,240 --> 07:41:45,478
random number generation so that we can
10911
07:41:45,478 --> 07:41:48,240
generate a unique API key for every user
10912
07:41:48,240 --> 07:41:50,000
and this is the snippet of code that
10913
07:41:50,000 --> 07:41:53,360
does that again you can go grab this in
10914
07:41:53,360 --> 07:41:55,958
the text instructions for this project
10915
07:41:55,958 --> 07:41:57,600
over on bootd but let me explain
10916
07:41:57,600 --> 07:41:58,718
basically what it's doing we're
10917
07:41:58,718 --> 07:41:59,680
generating
10918
07:41:59,680 --> 07:42:01,958
some random byes and then we're casting
10919
07:42:01,958 --> 07:42:05,200
it into a bite array and we're using the
10920
07:42:05,200 --> 07:42:10,200
shaw 256 hash function to get kind of a
10921
07:42:10,200 --> 07:42:13,280
a fixed size output so we're saying take
10922
07:42:13,280 --> 07:42:17,958
a a big random slice of bytes hash them
10923
07:42:17,958 --> 07:42:20,160
with straw 256 so that we get a fixed
10924
07:42:20,160 --> 07:42:24,120
size output and then encode it in
10925
07:42:24,120 --> 07:42:27,080
hexadecimal and that's so that we get 64
10926
07:42:27,080 --> 07:42:29,440
unique heximal characters this makes
10927
07:42:29,440 --> 07:42:30,680
more sense when we actually run the
10928
07:42:30,680 --> 07:42:32,840
query and you see what the output looks
10929
07:42:32,840 --> 07:42:35,040
like and then as far as the down
10930
07:42:35,040 --> 07:42:37,440
migration goes we just need to alter
10931
07:42:37,440 --> 07:42:40,280
table users and
10932
07:42:40,280 --> 07:42:45,000
drop column API key again down
10933
07:42:45,000 --> 07:42:47,840
migrations should just undo whatever was
10934
07:42:47,840 --> 07:42:49,958
done in the up migration let's go ahead
10935
07:42:49,958 --> 07:42:51,318
and run this migration so I'm going to
10936
07:42:51,318 --> 07:42:53,760
need to change directory into
10937
07:42:53,760 --> 07:42:55,600
SQL uh
10938
07:42:55,600 --> 07:42:59,718
schema then we'll run goose postgress
10939
07:42:59,718 --> 07:43:01,120
then let me go grab the connection
10940
07:43:01,120 --> 07:43:04,080
string now we do need to peel off this
10941
07:43:04,080 --> 07:43:06,760
SSL mode disable Goose doesn't need that
10942
07:43:06,760 --> 07:43:08,318
um just our code needs that so I'm going
10943
07:43:08,318 --> 07:43:10,840
to grab the rest of the string and we'll
10944
07:43:10,840 --> 07:43:12,280
run an up
10945
07:43:12,280 --> 07:43:14,878
migration cool so it looks like it ran
10946
07:43:14,878 --> 07:43:16,798
successfully let's go see if those
10947
07:43:16,798 --> 07:43:20,398
default values look good run the select
10948
07:43:20,398 --> 07:43:24,040
star statement and there you can see the
10949
07:43:24,040 --> 07:43:25,280
new
10950
07:43:25,280 --> 07:43:28,558
AES so big old heximal strings that
10951
07:43:28,558 --> 07:43:31,080
uniquely identify every user and should
10952
07:43:31,080 --> 07:43:33,478
be kept secret by the user because just
10953
07:43:33,478 --> 07:43:35,878
the API key is enough to authenticate
10954
07:43:35,878 --> 07:43:38,160
the user now that we've got our
10955
07:43:38,160 --> 07:43:40,520
migration and we've updated our schema
10956
07:43:40,520 --> 07:43:43,040
we actually need to go update our query
10957
07:43:43,040 --> 07:43:45,920
right we need to be creating new API
10958
07:43:45,920 --> 07:43:50,000
keys for new users so let's go update
10959
07:43:50,000 --> 07:43:51,878
our create user function it should now
10960
07:43:51,878 --> 07:43:55,920
accept an API key as the last
10961
07:43:55,920 --> 07:44:00,478
parameter and pass it in here
10962
07:44:00,478 --> 07:44:01,760
actually you know
10963
07:44:01,760 --> 07:44:04,398
what if we do it this way we're
10964
07:44:04,398 --> 07:44:06,120
basically telling our application code
10965
07:44:06,120 --> 07:44:08,840
hey you need to go generate an API key
10966
07:44:08,840 --> 07:44:11,240
in the same way that we generated it
10967
07:44:11,240 --> 07:44:13,080
here in our SQL I think it would
10968
07:44:13,080 --> 07:44:15,600
actually be easier what if we just take
10969
07:44:15,600 --> 07:44:18,520
this and plop
10970
07:44:18,520 --> 07:44:20,718
that in
10971
07:44:20,718 --> 07:44:23,160
here right so now we'll use we'll use
10972
07:44:23,160 --> 07:44:25,318
SQL to generate the new API Keys we
10973
07:44:25,318 --> 07:44:26,718
don't even need to update the function
10974
07:44:26,718 --> 07:44:29,120
signature of our create user function
10975
07:44:29,120 --> 07:44:31,080
cool so the SQL will just handle the
10976
07:44:31,080 --> 07:44:33,280
creation of new API Keys every time a
10977
07:44:33,280 --> 07:44:36,280
new user is created all right now we
10978
07:44:36,280 --> 07:44:37,600
should be able to
10979
07:44:37,600 --> 07:44:41,000
run sqlc
10980
07:44:41,000 --> 07:44:43,200
generate insert has more Expressions
10981
07:44:43,200 --> 07:44:45,360
than Target columns let's
10982
07:44:45,360 --> 07:44:48,240
see oh right sorry we we do still need
10983
07:44:48,240 --> 07:44:50,840
to pass in the API key as the column
10984
07:44:50,840 --> 07:44:53,120
name um the difference is because we're
10985
07:44:53,120 --> 07:44:55,638
not using dollar sign 5 our function
10986
07:44:55,638 --> 07:44:57,360
signature won't change this got a little
10987
07:44:57,360 --> 07:44:58,638
confusing I was reading it like a
10988
07:44:58,638 --> 07:45:00,478
function signature even though it is it
10989
07:45:00,478 --> 07:45:04,558
is SQL okay run that again it went off
10990
07:45:04,558 --> 07:45:06,160
without a hitch you can see it updated a
10991
07:45:06,160 --> 07:45:08,200
few files in our database package now we
10992
07:45:08,200 --> 07:45:10,958
should be able to go use that in our
10993
07:45:10,958 --> 07:45:13,840
code but before we test our server let's
10994
07:45:13,840 --> 07:45:16,120
add one more thing let's give us a way
10995
07:45:16,120 --> 07:45:18,798
to get a user so we'll create a new
10996
07:45:18,798 --> 07:45:23,280
function and this one we'll call get
10997
07:45:23,280 --> 07:45:27,798
user by API key it should return a
10998
07:45:27,798 --> 07:45:29,600
single row
10999
07:45:29,600 --> 07:45:30,798
and it's going to be a select statement
11000
07:45:30,798 --> 07:45:33,638
so select star
11001
07:45:33,638 --> 07:45:35,638
from
11002
07:45:35,638 --> 07:45:37,478
users
11003
07:45:37,478 --> 07:45:42,840
where API key equals dollar sign
11004
07:45:42,840 --> 07:45:46,600
one and we'll run sqlc generate again to
11005
07:45:46,600 --> 07:45:49,160
generate the code for that query you can
11006
07:45:49,160 --> 07:45:53,080
see it created it here so in our Handler
11007
07:45:53,080 --> 07:45:55,718
user function we actually don't need to
11008
07:45:55,718 --> 07:45:58,280
make any changes to our create user
11009
07:45:58,280 --> 07:46:00,080
Handler right right we didn't change the
11010
07:46:00,080 --> 07:46:01,318
number of parameters that we need to
11011
07:46:01,318 --> 07:46:03,638
pass in for the API key it's handled
11012
07:46:03,638 --> 07:46:06,718
kind of under the hood by the SQL query
11013
07:46:06,718 --> 07:46:09,080
but we do need a new Handler for getting
11014
07:46:09,080 --> 07:46:12,680
users so let's go ahead and add
11015
07:46:12,878 --> 07:46:16,680
that so I'm going to copy paste that do
11016
07:46:16,680 --> 07:46:21,080
Handler get user by API
11017
07:46:21,080 --> 07:46:22,958
key maybe we can just let's just
11018
07:46:22,958 --> 07:46:24,558
simplify this let's just call it Handler
11019
07:46:24,558 --> 07:46:25,398
get
11020
07:46:25,398 --> 07:46:27,680
user now this Handler is going to look
11021
07:46:27,680 --> 07:46:30,840
very different
11022
07:46:31,240 --> 07:46:34,040
this is an authenticated endpoint so in
11023
07:46:34,040 --> 07:46:36,478
order to create a user on our API
11024
07:46:36,478 --> 07:46:38,240
basically to register a new account you
11025
07:46:38,240 --> 07:46:40,478
don't need to have an API key but if you
11026
07:46:40,478 --> 07:46:43,040
want to get your own user information
11027
07:46:43,040 --> 07:46:46,398
you have to give us an API key first
11028
07:46:46,398 --> 07:46:48,200
this isn't going to be the only
11029
07:46:48,200 --> 07:46:50,398
authenticated endpoint or the endpoint
11030
07:46:50,398 --> 07:46:52,760
that you can only do if you're logged in
11031
07:46:52,760 --> 07:46:55,600
um so I think it makes sense to kind of
11032
07:46:55,600 --> 07:46:58,558
abstract the logic for getting a user by
11033
07:46:58,558 --> 07:47:02,478
their API key into a package so under
11034
07:47:02,478 --> 07:47:04,200
the internal package here where we have
11035
07:47:04,200 --> 07:47:05,878
our database code I'm going to create a
11036
07:47:05,878 --> 07:47:08,240
new package and we'll just call it
11037
07:47:08,240 --> 07:47:10,840
o and in there I'll create a new file
11038
07:47:10,840 --> 07:47:13,360
we'll call it o.o and this whole package
11039
07:47:13,360 --> 07:47:17,398
will just be called
11040
07:47:17,520 --> 07:47:22,080
off now the only function that we care
11041
07:47:22,080 --> 07:47:24,520
to export in this off package is going
11042
07:47:24,520 --> 07:47:27,478
to be this one called get API key and
11043
07:47:27,478 --> 07:47:29,558
its purpose get API key key will'll say
11044
07:47:29,558 --> 07:47:30,440
it
11045
07:47:30,440 --> 07:47:36,878
extracts an API key from the headers of
11046
07:47:36,878 --> 07:47:39,638
an HTTP request so it's going to go into
11047
07:47:39,638 --> 07:47:41,240
the headers look for a specific header
11048
07:47:41,240 --> 07:47:43,920
and see if it can find the API key if it
11049
07:47:43,920 --> 07:47:46,040
can it'll return it otherwise it will
11050
07:47:46,040 --> 07:47:47,440
return an
11051
07:47:47,440 --> 07:47:50,638
error now as the authors of This Server
11052
07:47:50,638 --> 07:47:52,600
we get to decide what we want the
11053
07:47:52,600 --> 07:47:54,120
authentication header to look like so
11054
07:47:54,120 --> 07:47:55,318
I'm just going to
11055
07:47:55,318 --> 07:47:59,160
say um example
11056
07:47:59,160 --> 07:48:01,680
let's expect an authorization header so
11057
07:48:01,680 --> 07:48:03,638
the key of the header will be
11058
07:48:03,638 --> 07:48:07,280
authorization and the value will be API
11059
07:48:07,280 --> 07:48:11,958
key and then some you know like insert
11060
07:48:11,958 --> 07:48:17,718
API key here okay so we're looking for a
11061
07:48:17,718 --> 07:48:19,520
header of this
11062
07:48:19,520 --> 07:48:22,160
format so first let's look and see if we
11063
07:48:22,160 --> 07:48:23,798
can find a value associated with the
11064
07:48:23,798 --> 07:48:26,718
authorization key um we're just using
11065
07:48:26,718 --> 07:48:28,558
the HTTP standard Library here so we can
11066
07:48:28,558 --> 07:48:31,718
do headers do
11067
07:48:31,718 --> 07:48:34,878
getet authorization and this should
11068
07:48:34,878 --> 07:48:37,120
return let's see a string okay so the
11069
07:48:37,120 --> 07:48:40,878
value associated with this with this
11070
07:48:40,878 --> 07:48:44,878
header key now if value is the empty
11071
07:48:44,878 --> 07:48:49,360
string then we can just say uh turn
11072
07:48:49,360 --> 07:48:53,080
empty string and an error say errors.
11073
07:48:53,080 --> 07:48:57,718
new no authentication
11074
07:48:57,718 --> 07:49:02,798
info found so otherwise we have a valid
11075
07:49:02,798 --> 07:49:06,040
value so we could do something like this
11076
07:49:06,040 --> 07:49:07,600
uh
11077
07:49:07,600 --> 07:49:11,080
vows strings.
11078
07:49:11,080 --> 07:49:13,040
split
11079
07:49:13,040 --> 07:49:17,558
vow okay so strings. split takes a
11080
07:49:17,558 --> 07:49:20,280
string as input and a delimiter so we're
11081
07:49:20,280 --> 07:49:22,680
going to say we want to split this
11082
07:49:22,680 --> 07:49:25,478
string here right the the value given to
11083
07:49:25,478 --> 07:49:27,920
us uh by the auth authorization header
11084
07:49:27,920 --> 07:49:31,680
uh we want to split on Spaces okay so
11085
07:49:31,680 --> 07:49:34,478
next we can say if the length of
11086
07:49:34,478 --> 07:49:37,000
vals does not equal
11087
07:49:37,000 --> 07:49:40,120
two then again we can return an error
11088
07:49:40,120 --> 07:49:43,120
saying like you know maybe
11089
07:49:43,120 --> 07:49:46,798
malformed malformed a header right
11090
07:49:46,798 --> 07:49:50,478
because we're expecting that the value
11091
07:49:50,478 --> 07:49:54,280
of this key is two like two specific
11092
07:49:54,280 --> 07:49:56,840
values separated by a space the first
11093
07:49:56,840 --> 07:49:59,478
should be API key and the second should
11094
07:49:59,478 --> 07:50:02,398
be the API key right the first should
11095
07:50:02,398 --> 07:50:04,398
just be the string API key and the
11096
07:50:04,398 --> 07:50:06,440
second should be the actual API
11097
07:50:06,440 --> 07:50:10,360
key okay so if the length is wrong then
11098
07:50:10,360 --> 07:50:11,840
uh next we should probably check and
11099
07:50:11,840 --> 07:50:13,558
make sure they typed this in correctly
11100
07:50:13,558 --> 07:50:17,840
so we can say uh if vals at zero does
11101
07:50:17,840 --> 07:50:21,318
not equal API
11102
07:50:21,680 --> 07:50:24,718
key malformed offhe
11103
07:50:24,718 --> 07:50:28,080
header we could say malformed first part
11104
07:50:28,080 --> 07:50:32,840
of offhe header okay
11105
07:50:32,840 --> 07:50:36,318
otherwise we can just
11106
07:50:36,318 --> 07:50:41,040
return B at one and no error
11107
07:50:41,040 --> 07:50:45,558
right because by that point we sure that
11108
07:50:45,558 --> 07:50:47,760
all all this part was correct and we're
11109
07:50:47,760 --> 07:50:49,680
extracting just the API
11110
07:50:49,680 --> 07:50:52,160
key okay what did I screw up here
11111
07:50:52,160 --> 07:50:53,920
errors. new oh right you're not supposed
11112
07:50:53,920 --> 07:50:57,440
to capitalize errors in go that is a a
11113
07:50:57,440 --> 07:51:00,558
linting error
11114
07:51:01,080 --> 07:51:03,680
a stylistic error Okay
11115
07:51:03,680 --> 07:51:06,920
cool so now we've got the get API key
11116
07:51:06,920 --> 07:51:09,558
function we can go ahead and use this in
11117
07:51:09,558 --> 07:51:12,478
our get user Handler so let's go ahead
11118
07:51:12,478 --> 07:51:15,760
and grab that API key so API key and
11119
07:51:15,760 --> 07:51:20,240
error o. getet API key and we pass in
11120
07:51:20,240 --> 07:51:23,120
the HTTP headers so r.
11121
07:51:23,120 --> 07:51:26,840
header perfect if there is an error
11122
07:51:26,840 --> 07:51:29,558
let's handle it
11123
07:51:29,558 --> 07:51:32,840
we can just respond with an error
11124
07:51:32,840 --> 07:51:35,318
saying off
11125
07:51:35,318 --> 07:51:38,520
error and 400 we should probably do like
11126
07:51:38,520 --> 07:51:40,958
a 403 and in fact now that I'm thinking
11127
07:51:40,958 --> 07:51:43,798
about HTTP codes creating a user
11128
07:51:43,798 --> 07:51:45,878
probably should be a 2011 instead of a
11129
07:51:45,878 --> 07:51:49,160
200 like you probably won't run into any
11130
07:51:49,160 --> 07:51:52,878
issues for using a 200 um but 201 is the
11131
07:51:52,878 --> 07:51:55,558
created code so it's like a little more
11132
07:51:55,558 --> 07:51:57,798
correct uh if you're looking at it from
11133
07:51:57,798 --> 07:52:00,160
kind of a rest full HTTP standpoint and
11134
07:52:00,160 --> 07:52:02,638
then 403 um is one of these kind of
11135
07:52:02,638 --> 07:52:05,000
permissions errors so that should be
11136
07:52:05,000 --> 07:52:08,440
good okay now that we have an API key we
11137
07:52:08,440 --> 07:52:11,920
can use our database query that we
11138
07:52:11,920 --> 07:52:15,558
created. get user by API key again we'll
11139
07:52:15,558 --> 07:52:19,760
pass in the requests context and the API
11140
07:52:19,760 --> 07:52:22,760
key I haven't really touched on this
11141
07:52:22,760 --> 07:52:26,200
yet in go um there is a context package
11142
07:52:26,200 --> 07:52:28,558
in the standard library and basically it
11143
07:52:28,558 --> 07:52:30,080
gives you a way to
11144
07:52:30,080 --> 07:52:32,680
track something that's happening across
11145
07:52:32,680 --> 07:52:35,558
multiple go routines and the most
11146
07:52:35,558 --> 07:52:36,760
important thing that you can do with the
11147
07:52:36,760 --> 07:52:40,080
context is you can cancel it so uh by
11148
07:52:40,080 --> 07:52:41,398
cancelling the context it would
11149
07:52:41,398 --> 07:52:44,080
effectively kill the HTTP request I
11150
07:52:44,080 --> 07:52:46,878
don't want to go too much into detail on
11151
07:52:46,878 --> 07:52:48,840
how all of that works here um you could
11152
07:52:48,840 --> 07:52:50,920
definitely go read up on it um but for
11153
07:52:50,920 --> 07:52:52,318
now just make sure that it's important
11154
07:52:52,318 --> 07:52:54,878
to kind of use the current context so
11155
07:52:54,878 --> 07:52:58,200
every HTTP do request has a context on
11156
07:52:58,200 --> 07:53:01,520
it and you should use that context um in
11157
07:53:01,520 --> 07:53:03,798
any calls you make within the Handler
11158
07:53:03,798 --> 07:53:06,878
that requires a context just in case uh
11159
07:53:06,878 --> 07:53:10,000
kind of cancellations happen Okay cool
11160
07:53:10,000 --> 07:53:14,798
uh that returns a user and an
11161
07:53:14,798 --> 07:53:18,798
error again if there is an
11162
07:53:18,958 --> 07:53:22,798
error Let's do let's use a better
11163
07:53:22,798 --> 07:53:26,558
uh string here
11164
07:53:27,440 --> 07:53:30,760
maybe couldn't get
11165
07:53:30,760 --> 07:53:33,600
user and this one let's just go with a
11166
07:53:33,600 --> 07:53:36,120
404 or a 400 for
11167
07:53:36,120 --> 07:53:41,398
now cool um and then we can respond with
11168
07:53:41,398 --> 07:53:43,958
Json this time it will just be a 200
11169
07:53:43,958 --> 07:53:46,798
code and again we should cast that
11170
07:53:46,798 --> 07:53:50,200
database user to the user uh model that
11171
07:53:50,200 --> 07:53:53,958
we defined here right with the the
11172
07:53:53,958 --> 07:53:56,680
nicely formatted Json tags and that
11173
07:53:56,680 --> 07:53:59,200
should be good okay let's hook up our
11174
07:53:59,200 --> 07:54:01,120
get user
11175
07:54:01,120 --> 07:54:03,760
Handler to our
11176
07:54:03,760 --> 07:54:09,318
router so here we'll do V1 router. getet
11177
07:54:09,318 --> 07:54:11,798
so same path SL
11178
07:54:11,798 --> 07:54:15,318
users but we'll be hooking up the get
11179
07:54:15,318 --> 07:54:18,760
user Handler to the get HTTP method so
11180
07:54:18,760 --> 07:54:21,160
again same path different method all
11181
07:54:21,160 --> 07:54:23,798
right let's test our new
11182
07:54:23,798 --> 07:54:26,240
endpoint um first I'm going to go ahead
11183
07:54:26,240 --> 07:54:28,478
and rerun sqlc generate cuz I can't
11184
07:54:28,478 --> 07:54:30,958
remember if I've done that and then
11185
07:54:30,958 --> 07:54:33,920
we'll build and run the
11186
07:54:35,600 --> 07:54:38,558
server okay with that running let's head
11187
07:54:38,558 --> 07:54:41,040
over to thunder
11188
07:54:41,040 --> 07:54:44,360
client and first let's create another
11189
07:54:44,360 --> 07:54:45,240
new
11190
07:54:45,240 --> 07:54:49,798
user so Json body me minimize this a
11191
07:54:49,798 --> 07:54:51,040
little
11192
07:54:51,040 --> 07:54:53,280
bit um let's keep create a new user
11193
07:54:53,280 --> 07:54:54,920
we'll call him
11194
07:54:54,920 --> 07:54:57,718
Rand and it'll be a post request that
11195
07:54:57,718 --> 07:55:00,040
looks good
11196
07:55:00,040 --> 07:55:03,398
okay response came back Rand was created
11197
07:55:03,398 --> 07:55:06,638
and this is rand's ID ah we screwed
11198
07:55:06,638 --> 07:55:08,840
something up we are not responding with
11199
07:55:08,840 --> 07:55:12,718
the API key let's go update
11200
07:55:12,718 --> 07:55:16,718
that so here in our model I believe it's
11201
07:55:16,718 --> 07:55:21,000
because we're not casting so we need API
11202
07:55:21,000 --> 07:55:22,638
E
11203
07:55:22,638 --> 07:55:24,318
string
11204
07:55:24,318 --> 07:55:26,958
bason API
11205
07:55:26,958 --> 07:55:29,798
key and then
11206
07:55:29,798 --> 07:55:32,200
here need to do that conversion so this
11207
07:55:32,200 --> 07:55:33,760
just getting dropped because we weren't
11208
07:55:33,760 --> 07:55:36,318
we weren't setting the API key
11209
07:55:36,318 --> 07:55:40,638
anywhere okay uh let's
11210
07:55:42,798 --> 07:55:45,318
rebuild and we'll create a new user
11211
07:55:45,318 --> 07:55:47,120
let's call this one
11212
07:55:47,120 --> 07:55:51,840
Joe Okay cool so Joe was created and it
11213
07:55:51,840 --> 07:55:54,478
actually returned the API key perfect
11214
07:55:54,478 --> 07:55:57,200
now let's go ahead and I'm going to
11215
07:55:57,200 --> 07:56:00,240
create a new request
11216
07:56:00,478 --> 07:56:05,360
this one also to Local Host
11217
07:56:05,360 --> 07:56:09,280
8080 slv1 users but this one will be a
11218
07:56:09,280 --> 07:56:12,240
get and we're going to add some headers
11219
07:56:12,240 --> 07:56:13,878
or specifically one header right we're
11220
07:56:13,878 --> 07:56:16,840
going to add our authorization header
11221
07:56:16,840 --> 07:56:19,760
and its value will be API
11222
07:56:19,760 --> 07:56:22,958
key and then the actual API key just
11223
07:56:22,958 --> 07:56:24,080
paste it in
11224
07:56:24,080 --> 07:56:27,878
there okay let's go ahead and run that
11225
07:56:27,878 --> 07:56:31,638
and it it's returning Joe it's good to
11226
07:56:31,638 --> 07:56:33,840
test failure cases too so let's just see
11227
07:56:33,840 --> 07:56:35,600
what happens if
11228
07:56:35,600 --> 07:56:38,638
we update this header and let's just
11229
07:56:38,638 --> 07:56:41,160
like let's just make something broken
11230
07:56:41,160 --> 07:56:42,920
let's just remove a section of the API
11231
07:56:42,920 --> 07:56:44,318
key and see what
11232
07:56:44,318 --> 07:56:46,760
happens cool we get a 400 batter request
11233
07:56:46,760 --> 07:56:48,958
couldn't get user SQL no rows in the
11234
07:56:48,958 --> 07:56:51,000
result set so essentially user is not
11235
07:56:51,000 --> 07:56:54,080
found perfect so we've got our users set
11236
07:56:54,080 --> 07:56:55,840
up and our authentication system now
11237
07:56:55,840 --> 07:56:57,080
it's time to actually get to some
11238
07:56:57,080 --> 07:56:59,040
business logic right this this is an RSS
11239
07:56:59,040 --> 07:57:01,280
feed aggregator so we need a way to
11240
07:57:01,280 --> 07:57:04,798
store feeds let's create a new schema or
11241
07:57:04,798 --> 07:57:06,798
rather a new migration in our schema
11242
07:57:06,798 --> 07:57:10,200
folder this will be O3 we'll call it
11243
07:57:10,200 --> 07:57:14,160
feed feeds dsql now this is going to be
11244
07:57:14,160 --> 07:57:16,080
a create table migration right we want
11245
07:57:16,080 --> 07:57:20,000
to create a feeds table so we'll do
11246
07:57:20,000 --> 07:57:21,558
create table
11247
07:57:21,558 --> 07:57:24,920
feeds now a feed and the drop will also
11248
07:57:24,920 --> 07:57:27,638
drop the feeds table a feed has an ID
11249
07:57:27,638 --> 07:57:29,398
just like a user um it also has a
11250
07:57:29,398 --> 07:57:31,798
created at and an updated at and it also
11251
07:57:31,798 --> 07:57:33,958
has a name like all of that is actually
11252
07:57:33,958 --> 07:57:36,160
very similar um what's unique about a
11253
07:57:36,160 --> 07:57:38,040
feed is it has a
11254
07:57:38,040 --> 07:57:42,398
URL uh which is text as well that is
11255
07:57:42,398 --> 07:57:45,000
unique and not
11256
07:57:45,000 --> 07:57:50,360
null and it also has a user
11257
07:57:50,360 --> 07:57:52,318
ID which
11258
07:57:52,318 --> 07:57:55,718
references sorry it's a user ID is a uu
11259
07:57:55,718 --> 07:57:59,040
ID which references
11260
07:57:59,040 --> 07:58:03,280
users ID and we'll also add the on
11261
07:58:03,280 --> 07:58:04,660
delete
11262
07:58:04,660 --> 07:58:06,160
[Music]
11263
07:58:06,160 --> 07:58:08,440
Cascade essentially what this does is it
11264
07:58:08,440 --> 07:58:11,160
says we have a user ID stored in our
11265
07:58:11,160 --> 07:58:13,240
feeds table that
11266
07:58:13,240 --> 07:58:16,280
references the ID of a user in the user
11267
07:58:16,280 --> 07:58:17,680
table right so this is this is
11268
07:58:17,680 --> 07:58:19,318
relational data this is a relational
11269
07:58:19,318 --> 07:58:22,000
database um essentially what this means
11270
07:58:22,000 --> 07:58:25,398
is if we try to create a feed for a user
11271
07:58:25,398 --> 07:58:27,440
ID that does not exist in the users
11272
07:58:27,440 --> 07:58:29,680
table we'll get an error uh which is
11273
07:58:29,680 --> 07:58:31,200
what we want because we don't want feeds
11274
07:58:31,200 --> 07:58:33,280
to be able to exist without a user who
11275
07:58:33,280 --> 07:58:35,680
created them and then this on delete
11276
07:58:35,680 --> 07:58:38,798
Cascade bit just says when a user is
11277
07:58:38,798 --> 07:58:41,638
deleted I want all of the feeds
11278
07:58:41,638 --> 07:58:43,798
associated with that user to be deleted
11279
07:58:43,798 --> 07:58:46,000
automatically it will Cascade and delete
11280
07:58:46,000 --> 07:58:48,200
all of them and let's run this migration
11281
07:58:48,200 --> 07:58:52,120
so I'm going to hop into the SQL schema
11282
07:58:52,120 --> 07:58:55,080
directory and from here we can run goose
11283
07:58:55,080 --> 07:58:58,360
postgress postgress and Gra my
11284
07:58:58,360 --> 07:59:00,000
connection screen again we don't need
11285
07:59:00,000 --> 07:59:03,440
the SSL mode stuff for goose grab the
11286
07:59:03,440 --> 07:59:08,638
rest of it and up cool now over here in
11287
07:59:08,638 --> 07:59:11,398
PG admin I can do a select star from
11288
07:59:11,398 --> 07:59:13,638
feeds and make sure that that table
11289
07:59:13,638 --> 07:59:16,398
exists with those fields next we'll need
11290
07:59:16,398 --> 07:59:18,520
a query to create a new feed so I'm
11291
07:59:18,520 --> 07:59:20,318
going to go ahead and copy this queries
11292
07:59:20,318 --> 07:59:23,360
file update it to feeds then we'll
11293
07:59:23,360 --> 07:59:24,958
delete this one because we don't need it
11294
07:59:24,958 --> 07:59:29,080
and we'll create a create
11295
07:59:29,080 --> 07:59:33,240
feed and insert into feeds ID created at
11296
07:59:33,240 --> 07:59:35,718
updated at name there will not be an API
11297
07:59:35,718 --> 07:59:40,638
key but let's see we need a name URL and
11298
07:59:40,638 --> 07:59:43,638
user ID okay name
11299
07:59:43,638 --> 07:59:45,840
URL user
11300
07:59:45,840 --> 07:59:48,760
ID we won't be generating an API key
11301
07:59:48,760 --> 07:59:51,798
here instead all of these values I think
11302
07:59:51,798 --> 07:59:53,558
we'll just be passed in from our
11303
07:59:53,558 --> 07:59:58,080
application code so 1 2 3 4 5 6 we need
11304
07:59:58,080 --> 08:00:02,120
six parameters for this function five
11305
08:00:02,120 --> 08:00:04,958
and six and then we'll just return uh
11306
08:00:04,958 --> 08:00:07,040
the entire feed row after it's done
11307
08:00:07,040 --> 08:00:08,680
being created and then I'll just
11308
08:00:08,680 --> 08:00:10,798
navigate back to the root of the
11309
08:00:10,798 --> 08:00:16,080
project and run SQL sqlc
11310
08:00:16,080 --> 08:00:19,000
generate to create the code for that new
11311
08:00:19,000 --> 08:00:21,398
query next we're going to create a new
11312
08:00:21,398 --> 08:00:24,318
Handler that will allow users of our API
11313
08:00:24,318 --> 08:00:27,160
to create a new feed here's the thing
11314
08:00:27,160 --> 08:00:29,958
that hand is also going to need all of
11315
08:00:29,958 --> 08:00:31,680
this same
11316
08:00:31,680 --> 08:00:34,680
logic that we have in the get user
11317
08:00:34,680 --> 08:00:37,318
Handler right we'll need to grab an
11318
08:00:37,318 --> 08:00:40,160
authentication uh token or an API key
11319
08:00:40,160 --> 08:00:42,798
from the authorization header fetch the
11320
08:00:42,798 --> 08:00:44,840
user and then use that user in the
11321
08:00:44,840 --> 08:00:46,638
Handler and rather than copying and
11322
08:00:46,638 --> 08:00:49,718
pasting uh this what 10 lines of code
11323
08:00:49,718 --> 08:00:51,680
into every Handler that's authenticated
11324
08:00:51,680 --> 08:00:53,318
instead we're going to build some
11325
08:00:53,318 --> 08:00:55,840
middleware to kind of dry up the code
11326
08:00:55,840 --> 08:00:58,318
right um let's go ahead and do that so
11327
08:00:58,318 --> 08:00:59,718
I'll create a new file I'm going to call
11328
08:00:59,718 --> 08:01:01,120
it
11329
08:01:01,120 --> 08:01:04,120
middleware
11330
08:01:04,120 --> 08:01:06,520
of.go art of the main
11331
08:01:06,520 --> 08:01:08,798
package and here we're going to define a
11332
08:01:08,798 --> 08:01:12,638
new type and it's our own custom type uh
11333
08:01:12,638 --> 08:01:15,878
I'm calling it off Handler and you'll
11334
08:01:15,878 --> 08:01:19,600
notice it looks almost exactly like a
11335
08:01:19,600 --> 08:01:22,120
regular HTTP Handler the only difference
11336
08:01:22,120 --> 08:01:25,080
is that it includes a third parameter it
11337
08:01:25,080 --> 08:01:28,000
has a user associated with it so if you
11338
08:01:28,000 --> 08:01:29,520
think about this um it makes a lot of
11339
08:01:29,520 --> 08:01:33,040
sense uh for any authenticated Handler
11340
08:01:33,040 --> 08:01:35,000
to accept three parameters where the
11341
08:01:35,000 --> 08:01:38,318
third one is the authenticated user now
11342
08:01:38,318 --> 08:01:41,318
the problem with this off Handler type
11343
08:01:41,318 --> 08:01:43,120
that we created is that it doesn't match
11344
08:01:43,120 --> 08:01:45,958
the function signature of an HTTP do
11345
08:01:45,958 --> 08:01:48,958
Handler Funk right uh those functions
11346
08:01:48,958 --> 08:01:51,200
with just the response writer and the
11347
08:01:51,200 --> 08:01:53,318
request as the only two parameters so
11348
08:01:53,318 --> 08:01:55,318
what we're going to do is create a new
11349
08:01:55,318 --> 08:01:58,478
function called middleware off uh that
11350
08:01:58,478 --> 08:02:00,878
works it's a method on our API config so
11351
08:02:00,878 --> 08:02:03,958
it has access to the database um but it
11352
08:02:03,958 --> 08:02:06,360
its job is to take an off Handler as
11353
08:02:06,360 --> 08:02:09,000
input and return a Handler Funk so that
11354
08:02:09,000 --> 08:02:11,920
we can you know use it with the CH
11355
08:02:11,920 --> 08:02:15,958
router okay let's Implement that the way
11356
08:02:15,958 --> 08:02:18,080
this function will actually work is
11357
08:02:18,080 --> 08:02:20,920
we're going to return a closure so we're
11358
08:02:20,920 --> 08:02:23,680
returning here a new Anonymous function
11359
08:02:23,680 --> 08:02:25,878
with that same function signature as
11360
08:02:25,878 --> 08:02:28,398
your normal HTTP Handler funk the
11361
08:02:28,398 --> 08:02:31,160
difference is that as we Define this
11362
08:02:31,160 --> 08:02:33,360
function we'll have access to everything
11363
08:02:33,360 --> 08:02:35,440
within the API config so we'll be able
11364
08:02:35,440 --> 08:02:37,638
to query the database so we can
11365
08:02:37,638 --> 08:02:39,760
basically just go rip out the code from
11366
08:02:39,760 --> 08:02:43,958
our get user Handler and paste it in
11367
08:02:43,958 --> 08:02:46,798
here right we're going to go get the API
11368
08:02:46,798 --> 08:02:50,398
key from the request well from the
11369
08:02:50,398 --> 08:02:52,958
request headers at least and then we can
11370
08:02:52,958 --> 08:02:57,200
go ahead and grab uh the user using that
11371
08:02:57,200 --> 08:02:58,638
API key
11372
08:02:58,638 --> 08:03:01,120
right so we'll have access to the user
11373
08:03:01,120 --> 08:03:03,718
here in the function finally all we need
11374
08:03:03,718 --> 08:03:07,080
to do is run the Handler that we were
11375
08:03:07,080 --> 08:03:10,200
given with the response writer the
11376
08:03:10,200 --> 08:03:13,478
request and the user right so by the
11377
08:03:13,478 --> 08:03:15,718
time we get to actually calling the a
11378
08:03:15,718 --> 08:03:19,718
Handler we're able to give it an actual
11379
08:03:19,718 --> 08:03:21,920
user from the database and this is
11380
08:03:21,920 --> 08:03:23,958
really great let me show you why so now
11381
08:03:23,958 --> 08:03:26,200
that the middle middleware o function
11382
08:03:26,200 --> 08:03:29,318
exists we can remove all of this code
11383
08:03:29,318 --> 08:03:32,600
from the get user Handler we can update
11384
08:03:32,600 --> 08:03:37,478
the get user Handler to accept as
11385
08:03:38,718 --> 08:03:41,160
input a database
11386
08:03:41,160 --> 08:03:44,558
user user database.
11387
08:03:44,558 --> 08:03:47,520
user look at how clean this function
11388
08:03:47,520 --> 08:03:49,840
becomes right now it's just now it's
11389
08:03:49,840 --> 08:03:52,200
literally just one line cool and now to
11390
08:03:52,200 --> 08:03:53,718
hook it up you'll notice we have an
11391
08:03:53,718 --> 08:03:56,240
error over here we just need to call our
11392
08:03:56,240 --> 08:03:58,920
middleware off
11393
08:03:58,920 --> 08:04:04,080
function apic CFG do middleware
11394
08:04:04,080 --> 08:04:07,558
off we call this function to convert the
11395
08:04:07,558 --> 08:04:11,600
get user Handler into a standard HTTP do
11396
08:04:11,600 --> 08:04:14,280
Handler funk I kind of move fast through
11397
08:04:14,280 --> 08:04:15,840
that hopefully it all make sense though
11398
08:04:15,840 --> 08:04:17,080
basically we're just calling the
11399
08:04:17,080 --> 08:04:20,120
middleware off function first to get the
11400
08:04:20,120 --> 08:04:22,958
authenticated user and then we're
11401
08:04:22,958 --> 08:04:25,558
calling that call back the the get user
11402
08:04:25,558 --> 08:04:27,440
Handler the nice thing is now we'll be
11403
08:04:27,440 --> 08:04:29,840
able to reuse that middleware across
11404
08:04:29,840 --> 08:04:33,160
many different HTTP Handler functions so
11405
08:04:33,160 --> 08:04:35,798
now let's create the create feed Handler
11406
08:04:35,798 --> 08:04:37,478
I'm going to go ahead and just copy this
11407
08:04:37,478 --> 08:04:41,160
Handler user change it to Handler
11408
08:04:41,160 --> 08:04:43,398
feed and for now we just need a create
11409
08:04:43,398 --> 08:04:45,878
function so I'll delete this get and
11410
08:04:45,878 --> 08:04:47,440
we'll call it
11411
08:04:47,440 --> 08:04:49,600
Handler create
11412
08:04:49,600 --> 08:04:52,318
feed and remember it's an authenticated
11413
08:04:52,318 --> 08:04:54,040
endpoint so we can have it accept the
11414
08:04:54,040 --> 08:04:58,520
user directly so user database. user
11415
08:04:58,520 --> 08:05:00,318
we know who's creating the feed by the
11416
08:05:00,318 --> 08:05:02,478
time we get to this function which is
11417
08:05:02,478 --> 08:05:05,398
awesome all right in order to create
11418
08:05:05,398 --> 08:05:08,520
create a feed use our new create feed
11419
08:05:08,520 --> 08:05:12,040
function which takes create feed
11420
08:05:12,040 --> 08:05:16,160
pams and create feed pams have ID
11421
08:05:16,160 --> 08:05:17,878
created at updated at name that's all
11422
08:05:17,878 --> 08:05:19,718
the same the difference is a URL and a
11423
08:05:19,718 --> 08:05:20,798
user
11424
08:05:20,798 --> 08:05:24,160
ID so
11425
08:05:24,280 --> 08:05:29,520
URL and a user ID which is a U ID uh
11426
08:05:29,520 --> 08:05:30,718
which actually exists already on the
11427
08:05:30,718 --> 08:05:33,638
user object so we can just do user. ID
11428
08:05:33,638 --> 08:05:36,718
okay um what do we want as input we need
11429
08:05:36,718 --> 08:05:38,638
a URL so we also are going to want a
11430
08:05:38,638 --> 08:05:41,240
prams
11431
08:05:47,080 --> 08:05:49,920
DOL so we want the user that's creating
11432
08:05:49,920 --> 08:05:52,360
a new feed to be able to just send us a
11433
08:05:52,360 --> 08:05:54,878
name and a URL and we'll go about
11434
08:05:54,878 --> 08:05:57,600
creating the entire uh kind of you know
11435
08:05:57,600 --> 08:05:59,920
feed object in the database or feed Row
11436
08:05:59,920 --> 08:06:00,760
in the
11437
08:06:00,760 --> 08:06:02,840
database so this is what our parameters
11438
08:06:02,840 --> 08:06:04,478
should look like uh what error am I
11439
08:06:04,478 --> 08:06:06,958
running into here cannot use API cf.
11440
08:06:06,958 --> 08:06:09,120
create
11441
08:06:09,120 --> 08:06:12,958
feed no new variables on left side of H
11442
08:06:12,958 --> 08:06:15,920
that's odd create feed should return a
11443
08:06:15,920 --> 08:06:19,680
feed let's take a look at that
11444
08:06:19,680 --> 08:06:22,478
definition yeah it does return a feed
11445
08:06:22,478 --> 08:06:25,398
what am I messing up
11446
08:06:25,718 --> 08:06:28,440
here oh first of all that shouldn't be a
11447
08:06:28,440 --> 08:06:30,360
user that should be a feed okay that's
11448
08:06:30,360 --> 08:06:32,080
the problem I was over I was trying to
11449
08:06:32,080 --> 08:06:35,160
overwrite the database. user type with a
11450
08:06:35,160 --> 08:06:37,080
feed type that won't
11451
08:06:37,080 --> 08:06:40,040
work okay so we're creating a feed we're
11452
08:06:40,040 --> 08:06:41,878
generating a new uid that's great we're
11453
08:06:41,878 --> 08:06:45,360
using the current time perfect um this
11454
08:06:45,360 --> 08:06:48,360
is getting messed up uh variable of Type
11455
08:06:48,360 --> 08:06:54,878
U id. uid as uu id. null U ID ah okay I
11456
08:06:54,878 --> 08:06:59,000
see the problem the create feed
11457
08:06:59,000 --> 08:07:02,920
pams except a uu id. null uuid that's a
11458
08:07:02,920 --> 08:07:05,760
problem we don't ever want a u the null
11459
08:07:05,760 --> 08:07:08,760
uuid type from the uid package is a
11460
08:07:08,760 --> 08:07:11,760
nullable uuid but we don't want it to be
11461
08:07:11,760 --> 08:07:14,318
nullable because we expect that every
11462
08:07:14,318 --> 08:07:16,318
feed will be created by a user so let's
11463
08:07:16,318 --> 08:07:18,878
go update
11464
08:07:18,878 --> 08:07:22,000
our our uh I think it's our is it our
11465
08:07:22,000 --> 08:07:25,240
migration let's go look schema
11466
08:07:25,240 --> 08:07:29,360
feeds yeah user
11467
08:07:29,360 --> 08:07:31,600
uid not
11468
08:07:31,600 --> 08:07:34,200
null cool it doesn't need to be unique a
11469
08:07:34,200 --> 08:07:35,638
user can have multiple feeds but it
11470
08:07:35,638 --> 08:07:39,360
should never be null all right um with
11471
08:07:39,360 --> 08:07:43,760
that we're actually going to need to
11472
08:07:43,878 --> 08:07:47,200
go uh rerun our migrations so
11473
08:07:47,200 --> 08:07:51,360
SQL um
11474
08:07:52,040 --> 08:07:56,360
schema and we'll do a down to drop the
11475
08:07:56,360 --> 08:07:58,558
table
11476
08:07:58,558 --> 08:08:01,280
down and then back up to create the new
11477
08:08:01,280 --> 08:08:03,798
table with the proper
11478
08:08:03,798 --> 08:08:06,958
schema and then we should
11479
08:08:06,958 --> 08:08:10,638
rerun SQL C
11480
08:08:10,638 --> 08:08:13,680
generate okay did that
11481
08:08:13,680 --> 08:08:16,318
work create feed create feed pams looks
11482
08:08:16,318 --> 08:08:18,840
like that error is gone it's now just a
11483
08:08:18,840 --> 08:08:22,120
uuid type perfect now at this point we
11484
08:08:22,120 --> 08:08:24,798
have a valid database feed should
11485
08:08:24,798 --> 08:08:26,280
probably update this error so that it
11486
08:08:26,280 --> 08:08:28,398
actually says feed um and we want to
11487
08:08:28,398 --> 08:08:32,520
return it um in our HTTP response
11488
08:08:32,520 --> 08:08:34,478
trouble is remember we don't want to
11489
08:08:34,478 --> 08:08:36,478
just directly return the struct let's go
11490
08:08:36,478 --> 08:08:38,718
create a new model for a
11491
08:08:38,718 --> 08:08:41,398
feed so we'll do
11492
08:08:41,398 --> 08:08:46,638
type feed and then I'm going to go just
11493
08:08:47,680 --> 08:08:52,558
copy the types from here and we'll use
11494
08:08:52,840 --> 08:08:55,798
those and we'll make our own Json tags
11495
08:08:55,798 --> 08:08:59,240
for the type
11496
08:09:02,120 --> 08:09:03,080
user
11497
08:09:03,080 --> 08:09:05,558
ID
11498
08:09:05,558 --> 08:09:12,520
URL name updated at and create at okay
11499
08:09:12,520 --> 08:09:15,878
and then we'll want
11500
08:09:15,920 --> 08:09:19,080
a what is it database
11501
08:09:19,080 --> 08:09:24,440
database feed to feed
11502
08:09:30,000 --> 08:09:33,160
and we'll return a
11503
08:09:42,920 --> 08:09:47,440
feed all of this should be pretty
11504
08:09:47,440 --> 08:09:49,120
straightforward and again this just
11505
08:09:49,120 --> 08:09:52,160
gives us more control right now we in
11506
08:09:52,160 --> 08:09:55,600
our code that's not generated by SQL c
11507
08:09:55,600 --> 08:09:59,080
um are able to Define you know what the
11508
08:09:59,080 --> 08:10:01,120
shape of the response will look like if
11509
08:10:01,120 --> 08:10:02,798
for whatever reason we needed to store
11510
08:10:02,798 --> 08:10:04,280
some data in the database but never
11511
08:10:04,280 --> 08:10:06,840
wanted to respond with it in our Json
11512
08:10:06,840 --> 08:10:08,920
API we could make those changes here in
11513
08:10:08,920 --> 08:10:11,000
this struct okay so now we've got
11514
08:10:11,000 --> 08:10:14,080
database feed to feed we'll call
11515
08:10:14,080 --> 08:10:18,040
that and now we should be good to go all
11516
08:10:18,040 --> 08:10:20,920
right let's test out our new Handler so
11517
08:10:20,920 --> 08:10:25,440
going to rebuild our server and run
11518
08:10:25,558 --> 08:10:29,160
it and over in the Thunder client let's
11519
08:10:29,160 --> 08:10:31,798
see so we just created a new user Joe so
11520
08:10:31,798 --> 08:10:34,080
we have our authentication key here or
11521
08:10:34,080 --> 08:10:39,360
our API key going to do a new request to
11522
08:10:39,360 --> 08:10:42,000
http
11523
08:10:42,000 --> 08:10:46,478
localhost 880 slv1 feeds ah now that I
11524
08:10:46,478 --> 08:10:48,600
type this out I realize that we never
11525
08:10:48,600 --> 08:10:49,558
hooked it
11526
08:10:49,558 --> 08:10:53,878
up let's go hook up that feed so feed
11527
08:10:53,878 --> 08:10:55,840
Handler Handler create feed we need to
11528
08:10:55,840 --> 08:10:58,520
go paste this in
11529
08:10:58,520 --> 08:11:02,120
to the main function so this one will go
11530
08:11:02,120 --> 08:11:04,840
under slash feeds because we're creating
11531
08:11:04,840 --> 08:11:07,478
a resource we're going to use a post
11532
08:11:07,478 --> 08:11:10,440
request Handler create
11533
08:11:10,440 --> 08:11:12,600
feed okay that should be hooked up now
11534
08:11:12,600 --> 08:11:15,600
let's uh restart our
11535
08:11:16,840 --> 08:11:20,798
server and over here again I need to
11536
08:11:20,798 --> 08:11:25,478
grab that API key all right
11537
08:11:27,760 --> 08:11:31,120
what do we want here post
11538
08:11:31,240 --> 08:11:36,040
request Local Host 8080 V1
11539
08:11:36,040 --> 08:11:40,558
feeds we do need to authenticate again
11540
08:11:40,558 --> 08:11:43,958
so qu
11541
08:11:44,360 --> 08:11:46,080
headers
11542
08:11:46,080 --> 08:11:47,920
auen
11543
08:11:47,920 --> 08:11:50,200
authorization API
11544
08:11:50,200 --> 08:11:52,680
key paste in that API
11545
08:11:52,680 --> 08:11:55,600
key okay uh what do we send in as the
11546
08:11:55,600 --> 08:11:57,798
body
11547
08:11:57,798 --> 08:12:00,398
let's take a look at our Handler again a
11548
08:12:00,398 --> 08:12:05,280
name and a URL okay so name now remember
11549
08:12:05,280 --> 08:12:07,558
this is this is this is not a person
11550
08:12:07,558 --> 08:12:11,478
this is a feed right and a feed is a URL
11551
08:12:11,478 --> 08:12:14,440
that kind of links to an RSS feed out on
11552
08:12:14,440 --> 08:12:16,318
the internet so this one I'm going to
11553
08:12:16,318 --> 08:12:19,638
put just uh Lanes Lan's
11554
08:12:19,638 --> 08:12:25,040
blog and then the URL is going to be
11555
08:12:25,040 --> 08:12:27,240
https
11556
08:12:27,240 --> 08:12:30,040
tags lane.
11557
08:12:30,040 --> 08:12:34,318
deev SL
11558
08:12:34,440 --> 08:12:36,520
index.xml so in case you're not familiar
11559
08:12:36,520 --> 08:12:38,360
with what an RSS feed is let me just
11560
08:12:38,360 --> 08:12:40,638
show you really quick um I'm here on my
11561
08:12:40,638 --> 08:12:43,240
blog Wags lane. deev and if you click
11562
08:12:43,240 --> 08:12:45,600
RSS up at the top it'll take you to my
11563
08:12:45,600 --> 08:12:49,718
RSS feed now every RSS feed um will have
11564
08:12:49,718 --> 08:12:51,958
a different URL it's kind of up to the
11565
08:12:51,958 --> 08:12:53,958
author of the blog or the podcast what
11566
08:12:53,958 --> 08:12:56,360
that feed URL is but you can usually
11567
08:12:56,360 --> 08:12:57,680
find it by poke looking around on their
11568
08:12:57,680 --> 08:12:59,840
website so in my case um it's just
11569
08:12:59,840 --> 08:13:03,520
waglan dodev index.xml and it will look
11570
08:13:03,520 --> 08:13:05,558
something like this if you open it up in
11571
08:13:05,558 --> 08:13:08,160
a browser it's basically this structured
11572
08:13:08,160 --> 08:13:11,718
XML document that describes what each
11573
08:13:11,718 --> 08:13:15,040
post on the blog says at least from a
11574
08:13:15,040 --> 08:13:16,478
high level it'll usually have something
11575
08:13:16,478 --> 08:13:18,760
like a link to the post maybe a short
11576
08:13:18,760 --> 08:13:21,600
description um basic stuff like that
11577
08:13:21,600 --> 08:13:24,638
again podcasts also work on the same RSS
11578
08:13:24,638 --> 08:13:26,318
structure so for testing you can use my
11579
08:13:26,318 --> 08:13:28,360
blog or if you know of any other RSS
11580
08:13:28,360 --> 08:13:31,440
feeds um out on the web you can use them
11581
08:13:31,440 --> 08:13:34,280
so now that I've pasted in that URL uh
11582
08:13:34,280 --> 08:13:36,718
let's go ahead and create that
11583
08:13:36,718 --> 08:13:39,920
feed and what do we get
11584
08:13:39,920 --> 08:13:43,080
back cool the feed's got a new URL
11585
08:13:43,080 --> 08:13:45,958
created at updated at the name and the
11586
08:13:45,958 --> 08:13:48,638
URL seem to have persisted correctly and
11587
08:13:48,638 --> 08:13:52,080
that is the user ID associated with the
11588
08:13:52,080 --> 08:13:54,840
API key that we use to create the feed
11589
08:13:54,840 --> 08:13:57,240
next we're going to add the ability for
11590
08:13:57,240 --> 08:14:00,318
any user to get all of the feeds in the
11591
08:14:00,318 --> 08:14:02,360
database this is not an authenticated
11592
08:14:02,360 --> 08:14:05,718
endpoint okay so we need new query I'm
11593
08:14:05,718 --> 08:14:07,958
going to go ahead and use the same file
11594
08:14:07,958 --> 08:14:10,680
um this query will just be called get
11595
08:14:10,680 --> 08:14:14,638
feeds and it will return many rows
11596
08:14:14,638 --> 08:14:17,638
instead of just one all right and this
11597
08:14:17,638 --> 08:14:21,360
one will be uh
11598
08:14:21,478 --> 08:14:24,120
select star from
11599
08:14:24,120 --> 08:14:27,360
feeds super super simple query here
11600
08:14:27,360 --> 08:14:28,718
we're just going to go grab all the
11601
08:14:28,718 --> 08:14:32,638
feeds and return them okay um from there
11602
08:14:32,638 --> 08:14:36,040
we should be able to sqlc
11603
08:14:36,040 --> 08:14:38,600
generate and let's go hook up that
11604
08:14:38,600 --> 08:14:41,840
Handler I'm going to use the same uh
11605
08:14:41,840 --> 08:14:44,878
Handler feed file U but this one will be
11606
08:14:44,878 --> 08:14:45,920
a little bit
11607
08:14:45,920 --> 08:14:49,558
different we going
11608
08:14:49,840 --> 08:14:55,520
to call this one Handler get
11609
08:14:55,520 --> 08:14:58,360
feeds it's not authenticated so we don't
11610
08:14:58,360 --> 08:15:00,760
need to pass in a user and it doesn't
11611
08:15:00,760 --> 08:15:02,638
even take any parameters right it's just
11612
08:15:02,638 --> 08:15:05,040
going to go get all of the feeds so um
11613
08:15:05,040 --> 08:15:07,558
apic
11614
08:15:25,920 --> 08:15:30,398
cfg.init' to return all of the feeds
11615
08:15:30,398 --> 08:15:33,558
this is not a single feed this is now a
11616
08:15:33,558 --> 08:15:36,958
slice of database. feeds so not only do
11617
08:15:36,958 --> 08:15:38,280
we need to return them but we need to
11618
08:15:38,280 --> 08:15:40,040
actually convert them so let's go update
11619
08:15:40,040 --> 08:15:42,440
our models a little bit let's create a
11620
08:15:42,440 --> 08:15:43,558
new
11621
08:15:43,558 --> 08:15:46,520
function this one will be database feeds
11622
08:15:46,520 --> 08:15:48,798
to
11623
08:15:48,798 --> 08:15:50,840
feeds and the difference is it will
11624
08:15:50,840 --> 08:15:52,680
accept a slice of database feeds and it
11625
08:15:52,680 --> 08:15:55,680
will'll return a slice of
11626
08:15:55,760 --> 08:15:58,760
feeds let's let's do this slice feed
11627
08:15:58,760 --> 08:16:00,600
we'll create a new empty slice of feeds
11628
08:16:00,600 --> 08:16:01,920
and then
11629
08:16:01,920 --> 08:16:05,558
four DB
11630
08:16:06,360 --> 08:16:10,558
feed range DB
11631
08:16:11,600 --> 08:16:15,798
feeds feeds equals
11632
08:16:15,798 --> 08:16:17,638
append
11633
08:16:17,638 --> 08:16:22,280
feeds database feeds or database feed
11634
08:16:22,280 --> 08:16:26,040
and return feeds sorry not we don't want
11635
08:16:26,040 --> 08:16:27,760
to append it directly we have to we have
11636
08:16:27,760 --> 08:16:31,638
to call our conversion function okay so
11637
08:16:31,638 --> 08:16:33,160
this function will just iterate over all
11638
08:16:33,160 --> 08:16:35,478
of the database feeds one by one
11639
08:16:35,478 --> 08:16:37,040
converting them into our new feed
11640
08:16:37,040 --> 08:16:39,840
structure and then returning them cool
11641
08:16:39,840 --> 08:16:42,120
now here we can use that
11642
08:16:42,120 --> 08:16:44,878
function to do that
11643
08:16:44,878 --> 08:16:48,440
mapping great let's hook up this Handler
11644
08:16:48,440 --> 08:16:52,638
so in main.go we'll create a new entry
11645
08:16:52,638 --> 08:16:57,280
here this is going to be a get request
11646
08:16:57,280 --> 08:17:00,040
and it's not
11647
08:17:00,760 --> 08:17:03,080
authenticated it will be
11648
08:17:03,080 --> 08:17:05,040
Handler yet
11649
08:17:05,040 --> 08:17:08,878
feeds cool let's regenerate I can't
11650
08:17:08,878 --> 08:17:10,600
remember if I generated my SQL C so I'll
11651
08:17:10,600 --> 08:17:13,238
do that couldn't hurt and then we'll
11652
08:17:13,238 --> 08:17:15,840
build and run the
11653
08:17:18,280 --> 08:17:20,478
server okay with that running let's go
11654
08:17:20,478 --> 08:17:24,120
ahead and create a couple more RSS feeds
11655
08:17:24,120 --> 08:17:25,398
so
11656
08:17:25,398 --> 08:17:28,600
here update the
11657
08:17:28,600 --> 08:17:31,280
body of my request sorry I'm so zoomed
11658
08:17:31,280 --> 08:17:32,638
in so that you guys can see and it just
11659
08:17:32,638 --> 08:17:33,760
makes it
11660
08:17:33,760 --> 08:17:37,760
hard um no this was to create users this
11661
08:17:37,760 --> 08:17:40,238
is users here's
11662
08:17:40,238 --> 08:17:43,638
feeds okay let's let's just add the same
11663
08:17:43,638 --> 08:17:46,638
URL with a couple well no we can't we
11664
08:17:46,638 --> 08:17:48,238
can't add the same URL let's just use
11665
08:17:48,238 --> 08:17:52,558
some garbage URLs just to test
11666
08:17:57,920 --> 08:17:59,200
all
11667
08:17:59,200 --> 08:18:03,120
right okay that created properly now
11668
08:18:03,120 --> 08:18:05,680
let's test our new
11669
08:18:05,680 --> 08:18:08,478
endpoint this one is going to be a get
11670
08:18:08,478 --> 08:18:11,200
request to feeds and we don't need to
11671
08:18:11,200 --> 08:18:13,958
add any authentication information okay
11672
08:18:13,958 --> 08:18:16,280
run
11673
08:18:16,878 --> 08:18:19,080
that awesome this looks good to me we've
11674
08:18:19,080 --> 08:18:21,238
got an array at the top level and then
11675
08:18:21,238 --> 08:18:23,958
two feed objects one for garbage blog
11676
08:18:23,958 --> 08:18:26,280
and one's for one for Lane's blog so it
11677
08:18:26,280 --> 08:18:28,200
looks like everything's working so we've
11678
08:18:28,200 --> 08:18:30,080
given users a way to create feeds and a
11679
08:18:30,080 --> 08:18:32,360
way to query all of the feeds now we're
11680
08:18:32,360 --> 08:18:34,238
going to give users a way to follow
11681
08:18:34,238 --> 08:18:36,360
specific feeds so that they can see kind
11682
08:18:36,360 --> 08:18:38,798
of an aggregated view of all of the
11683
08:18:38,798 --> 08:18:41,520
feeds that they care about on the system
11684
08:18:41,520 --> 08:18:44,878
okay so uh let's go ahead and add a new
11685
08:18:44,878 --> 08:18:48,200
migration we need a new table so this
11686
08:18:48,200 --> 08:18:50,040
will be the fourth migration and we'll
11687
08:18:50,040 --> 08:18:53,120
call this new table feed follows and
11688
08:18:53,120 --> 08:18:55,160
this table is just going to store the
11689
08:18:55,160 --> 08:18:57,638
relationship between a user and all of
11690
08:18:57,638 --> 08:18:59,238
the feeds they're following so it'll be
11691
08:18:59,238 --> 08:19:02,120
a many to many uh kind of table of user
11692
08:19:02,120 --> 08:19:04,080
IDs to feed
11693
08:19:04,080 --> 08:19:06,958
IDs all right um the table is going to
11694
08:19:06,958 --> 08:19:08,360
be called feed
11695
08:19:08,360 --> 08:19:11,280
follows so create table feed follows
11696
08:19:11,280 --> 08:19:13,718
every feed follow like every other
11697
08:19:13,718 --> 08:19:15,840
record in our database will have an ID a
11698
08:19:15,840 --> 08:19:18,760
created at and an updated at but its
11699
08:19:18,760 --> 08:19:20,478
unique Fields will be a little bit
11700
08:19:20,478 --> 08:19:22,478
different first it's going to need a
11701
08:19:22,478 --> 08:19:25,160
user
11702
08:19:25,200 --> 08:19:27,160
ID which is
11703
08:19:27,160 --> 08:19:30,638
is oh my gosh why can't I type fingers
11704
08:19:30,638 --> 08:19:32,760
the wrong place in the keyboard so a
11705
08:19:32,760 --> 08:19:37,280
user ID is a uu ID um that can be it
11706
08:19:37,280 --> 08:19:38,718
doesn't let's see it doesn't need to be
11707
08:19:38,718 --> 08:19:43,798
unique um but it does need to be not
11708
08:19:43,798 --> 08:19:47,478
null then we need a feed
11709
08:19:47,478 --> 08:19:52,200
ID also a uu ID not null and then we're
11710
08:19:52,200 --> 08:19:55,600
going to create a unique constraint on
11711
08:19:55,600 --> 08:20:00,000
the comb ination of user ID to feed ID
11712
08:20:00,000 --> 08:20:01,798
so
11713
08:20:01,798 --> 08:20:08,638
unique user ID feed ID so again this
11714
08:20:08,638 --> 08:20:10,280
constraint is going to make it so that
11715
08:20:10,280 --> 08:20:13,958
we can never have two instances of a
11716
08:20:13,958 --> 08:20:17,000
follow for the same user feed
11717
08:20:17,000 --> 08:20:19,360
relationship right you as a user can
11718
08:20:19,360 --> 08:20:21,520
only follow a certain feed once you
11719
08:20:21,520 --> 08:20:23,440
can't follow it twice that doesn't
11720
08:20:23,440 --> 08:20:24,600
really make sense right so we're going
11721
08:20:24,600 --> 08:20:26,760
to ensure that that's unique um also so
11722
08:20:26,760 --> 08:20:29,160
I missed a couple things here the user
11723
08:20:29,160 --> 08:20:32,120
ID uh should reference so
11724
08:20:32,120 --> 08:20:34,958
[Music]
11725
08:20:34,958 --> 08:20:38,040
references uh the users
11726
08:20:38,040 --> 08:20:42,718
table ID field and on delete we'll
11727
08:20:42,718 --> 08:20:46,000
Cascade so if a user is deleted we're
11728
08:20:46,000 --> 08:20:48,600
going to go delete all of the data about
11729
08:20:48,600 --> 08:20:49,958
what feeds they're
11730
08:20:49,958 --> 08:20:52,000
following um and then this one's going
11731
08:20:52,000 --> 08:20:54,878
to be very similar except it references
11732
08:20:54,878 --> 08:20:57,638
the feeds table
11733
08:20:57,638 --> 08:20:59,398
with its ID and again if a feed gets
11734
08:20:59,398 --> 08:21:01,318
deleted then we'll go delete all of the
11735
08:21:01,318 --> 08:21:04,840
following data related to that
11736
08:21:04,840 --> 08:21:08,398
feed cool okay let's go ahead and run
11737
08:21:08,398 --> 08:21:11,798
this migration so I'm going to go back
11738
08:21:11,798 --> 08:21:14,798
up into the SQL or I should say back
11739
08:21:14,798 --> 08:21:16,958
down into the SQL schema
11740
08:21:16,958 --> 08:21:19,040
directory and from
11741
08:21:19,040 --> 08:21:23,200
here I'll need my connection string do
11742
08:21:23,200 --> 08:21:24,798
goose
11743
08:21:24,798 --> 08:21:27,200
postgress connection string
11744
08:21:27,200 --> 08:21:29,120
ah I didn't grab the whole thing let's
11745
08:21:29,120 --> 08:21:31,318
try that
11746
08:21:31,318 --> 08:21:35,680
again all of that boo
11747
08:21:35,680 --> 08:21:38,000
postgress
11748
08:21:38,000 --> 08:21:41,958
up cool feed follows databases or feed
11749
08:21:41,958 --> 08:21:44,638
follows table is there so now we need a
11750
08:21:44,638 --> 08:21:48,040
way for users to follow feeds all right
11751
08:21:48,040 --> 08:21:49,798
let's go ahead and go create that so I'm
11752
08:21:49,798 --> 08:21:53,120
going to copy and paste the feed Handler
11753
08:21:53,120 --> 08:21:54,840
file and we'll call it
11754
08:21:54,840 --> 08:21:58,520
Handler feed
11755
08:21:58,520 --> 08:22:01,718
follows and update this so Handler
11756
08:22:01,718 --> 08:22:04,238
create feed follow so remember in order
11757
08:22:04,238 --> 08:22:06,680
for a user to follow a feed all we need
11758
08:22:06,680 --> 08:22:09,558
to do is create a new feed follow record
11759
08:22:09,558 --> 08:22:12,360
with that user feed
11760
08:22:12,360 --> 08:22:14,200
relationship okay this is an
11761
08:22:14,200 --> 08:22:16,680
authenticated endpoint right we so we we
11762
08:22:16,680 --> 08:22:18,718
need a user and we need them to be
11763
08:22:18,718 --> 08:22:21,878
authenticated have passed an API key
11764
08:22:21,878 --> 08:22:24,398
right and let's see what do we need them
11765
08:22:24,398 --> 08:22:27,440
to give us as input I think all we need
11766
08:22:27,440 --> 08:22:28,718
is a feed
11767
08:22:28,718 --> 08:22:31,160
ID right they just need to tell us which
11768
08:22:31,160 --> 08:22:32,840
feed they want
11769
08:22:32,840 --> 08:22:34,760
to
11770
08:22:34,760 --> 08:22:39,040
follow so a feed ID is a uu
11771
08:22:40,000 --> 08:22:43,398
ID all right and now we should be able
11772
08:22:43,398 --> 08:22:46,680
to create feed oh we we never we never
11773
08:22:46,680 --> 08:22:48,398
made we never made the squl query what
11774
08:22:48,398 --> 08:22:49,718
am I doing what am I doing I'm getting
11775
08:22:49,718 --> 08:22:52,638
way ahead of myself let's go add that
11776
08:22:52,638 --> 08:22:54,958
query quickly so
11777
08:22:54,958 --> 08:22:58,160
feed follows
11778
08:22:58,160 --> 08:23:02,318
and to start we'll need a create feed
11779
08:23:02,318 --> 08:23:05,080
follow okay what's in a feed follow
11780
08:23:05,080 --> 08:23:10,360
right got all these all of these fields
11781
08:23:10,360 --> 08:23:11,638
and I think yeah we're just going to
11782
08:23:11,638 --> 08:23:14,040
have them all past in directly that
11783
08:23:14,040 --> 08:23:17,440
seems like the easiest way so insert
11784
08:23:17,440 --> 08:23:18,760
into feed
11785
08:23:18,760 --> 08:23:22,318
follows ID created at updated
11786
08:23:22,318 --> 08:23:28,440
at user ID feed ID
11787
08:23:28,718 --> 08:23:30,558
that's five parameters right one two
11788
08:23:30,558 --> 08:23:33,760
three four five cool that looks
11789
08:23:33,760 --> 08:23:36,718
good now I should be able to go back and
11790
08:23:36,718 --> 08:23:39,958
run sqlc
11791
08:23:40,120 --> 08:23:43,040
generate cool now I should
11792
08:23:43,040 --> 08:23:45,280
have
11793
08:23:45,280 --> 08:23:50,000
a create feed follow function with
11794
08:23:50,000 --> 08:23:52,958
create feed follow
11795
08:23:52,958 --> 08:23:57,600
pams all right it accepts a user ID and
11796
08:23:57,600 --> 08:23:59,398
a feed ID so the user ID is just the
11797
08:23:59,398 --> 08:24:01,798
auth authenticated user the feed ID is
11798
08:24:01,798 --> 08:24:04,760
going to be passed in his params
11799
08:24:04,760 --> 08:24:09,398
right cool couldn't create feed
11800
08:24:09,638 --> 08:24:12,440
follow don't need a get Handler quite
11801
08:24:12,440 --> 08:24:14,840
yet and then we're going to just need to
11802
08:24:14,840 --> 08:24:18,200
make uh make that uh mapping function as
11803
08:24:18,200 --> 08:24:22,080
well for feed
11804
08:24:23,120 --> 08:24:25,600
follows so in our models file I'll
11805
08:24:25,600 --> 08:24:28,638
create a new feed follow struct and it's
11806
08:24:28,638 --> 08:24:34,120
going to have a user ID and a feed
11807
08:24:38,798 --> 08:24:43,638
ID and a new function database feed
11808
08:24:43,638 --> 08:24:49,120
follow to feed follow
11809
08:25:00,878 --> 08:25:04,360
all right DB feed
11810
08:25:13,280 --> 08:25:15,680
fall. by the way I'm not using GitHub
11811
08:25:15,680 --> 08:25:18,958
co-pilot in this video just so that you
11812
08:25:18,958 --> 08:25:22,080
could just just so you can see more of
11813
08:25:22,080 --> 08:25:24,760
my thought process um but I typically do
11814
08:25:24,760 --> 08:25:26,760
use GitHub co-pilot
11815
08:25:26,760 --> 08:25:29,920
and it makes this kind of function just
11816
08:25:29,920 --> 08:25:32,440
like way faster to write um it would
11817
08:25:32,440 --> 08:25:34,280
guess this kind of function almost
11818
08:25:34,280 --> 08:25:37,520
perfectly um so just so you know I I do
11819
08:25:37,520 --> 08:25:39,120
recommend those kinds of tools to speed
11820
08:25:39,120 --> 08:25:41,600
up the development process um I'm just
11821
08:25:41,600 --> 08:25:43,238
not using it uh right now so that you
11822
08:25:43,238 --> 08:25:45,238
can see how I think through you know
11823
08:25:45,238 --> 08:25:46,920
architecting this this application
11824
08:25:46,920 --> 08:25:48,760
without all the AI prompts getting in
11825
08:25:48,760 --> 08:25:52,200
the way okay now we should be able to
11826
08:25:52,200 --> 08:25:54,478
database feed follow to feed follow and
11827
08:25:54,478 --> 08:25:56,000
we're going to be clear that this is a
11828
08:25:56,000 --> 08:25:57,760
feed follow not a
11829
08:25:57,760 --> 08:26:01,200
feed and that goes
11830
08:26:01,200 --> 08:26:03,600
there
11831
08:26:03,600 --> 08:26:06,558
Perfect all right let's hook this up so
11832
08:26:06,558 --> 08:26:09,080
we're going to need to go into main.go
11833
08:26:09,080 --> 08:26:14,080
V1 router. poost is we're creating a
11834
08:26:14,080 --> 08:26:17,920
resource slash feed
11835
08:26:17,920 --> 08:26:21,160
follows and this is an
11836
08:26:21,160 --> 08:26:24,798
authenticated authenticated
11837
08:26:25,238 --> 08:26:29,200
Handler Handler create feed follow okay
11838
08:26:29,200 --> 08:26:31,360
let's test this new endpoint so we'll
11839
08:26:31,360 --> 08:26:33,920
build and run the
11840
08:26:36,760 --> 08:26:40,120
server and we'll need a new
11841
08:26:40,120 --> 08:26:44,760
request this one will be kind of similar
11842
08:26:44,760 --> 08:26:45,520
it'll
11843
08:26:45,520 --> 08:26:49,440
be oops a post request to the feed
11844
08:26:49,440 --> 08:26:52,000
follows end
11845
08:26:52,000 --> 08:26:55,200
point and we're going to need to
11846
08:26:55,200 --> 08:26:57,238
authenticate so let's go grab some
11847
08:26:57,238 --> 08:26:59,600
authentication
11848
08:26:59,600 --> 08:27:02,398
information let's see get users let's go
11849
08:27:02,398 --> 08:27:03,160
ahead
11850
08:27:03,160 --> 08:27:05,840
and send this couldn't get user sequel
11851
08:27:05,840 --> 08:27:09,318
no result okay I need to figure out what
11852
08:27:09,318 --> 08:27:11,920
users I have available to me oh that's
11853
08:27:11,920 --> 08:27:14,558
right we we changed this API key we
11854
08:27:14,558 --> 08:27:18,840
wanted it to break let's go create a new
11855
08:27:19,398 --> 08:27:22,440
user we'll make a new one
11856
08:27:22,440 --> 08:27:26,360
called uh Billy
11857
08:27:26,360 --> 08:27:28,798
and there's Billy's API
11858
08:27:28,798 --> 08:27:31,718
key cool we've got some
11859
08:27:31,718 --> 08:27:34,238
feeds but our feed
11860
08:27:34,238 --> 08:27:37,878
follows need an off
11861
08:27:37,878 --> 08:27:40,238
section sorry in the
11862
08:27:40,238 --> 08:27:42,558
headers we're doing it
11863
08:27:42,558 --> 08:27:44,878
manually
11864
08:27:44,878 --> 08:27:48,558
authorization API key there's Billy's
11865
08:27:48,558 --> 08:27:51,238
key and then in the body we need to pass
11866
08:27:51,238 --> 08:27:54,878
in the ID of the feed that we want to
11867
08:27:54,878 --> 08:27:58,000
follow so so let's do a get on all of
11868
08:27:58,000 --> 08:28:00,600
the feeds and we can follow either of
11869
08:28:00,600 --> 08:28:03,360
these let's follow Lane's
11870
08:28:03,360 --> 08:28:06,760
block there's our feed
11871
08:28:06,760 --> 08:28:11,600
ID paste that in there and
11872
08:28:12,680 --> 08:28:15,478
create amazing new ID for the feed
11873
08:28:15,478 --> 08:28:18,638
follow there's the user ID the feed ID
11874
08:28:18,638 --> 08:28:21,440
what happens if we try to recreate it
11875
08:28:21,440 --> 08:28:23,040
cool couldn't create feed follow
11876
08:28:23,040 --> 08:28:25,120
duplicate key value violates unique
11877
08:28:25,120 --> 08:28:26,718
constraint that's what we'd expect right
11878
08:28:26,718 --> 08:28:29,120
we shouldn't be able to follow the same
11879
08:28:29,120 --> 08:28:30,840
feed multiple times we're already
11880
08:28:30,840 --> 08:28:33,600
following it we already have a record uh
11881
08:28:33,600 --> 08:28:35,200
indicating that we are following it
11882
08:28:35,200 --> 08:28:37,200
everything appears to be working just
11883
08:28:37,200 --> 08:28:40,600
fine next let's give users a way to see
11884
08:28:40,600 --> 08:28:42,080
all of the different feeds that they are
11885
08:28:42,080 --> 08:28:48,638
currently following so we'll do get feed
11886
08:28:48,638 --> 08:28:51,760
follows and it will return
11887
08:28:51,760 --> 08:28:55,638
many and the query will be select star
11888
08:28:55,638 --> 08:28:57,760
from
11889
08:28:57,760 --> 08:29:03,398
e follows where user ID equals dollar
11890
08:29:03,398 --> 08:29:06,238
sign one right so get all the feed
11891
08:29:06,238 --> 08:29:09,398
follows for a given
11892
08:29:09,398 --> 08:29:12,080
ID let's get that hooked up need to run
11893
08:29:12,080 --> 08:29:16,000
SQL C generate to create that query and
11894
08:29:16,000 --> 08:29:19,878
then down here we'll create a new
11895
08:29:20,680 --> 08:29:24,878
Handler this Handler will also be
11896
08:29:24,878 --> 08:29:27,798
authenticated but it's going to be get
11897
08:29:27,798 --> 08:29:29,080
feed
11898
08:29:29,080 --> 08:29:32,200
follows have the user we don't need any
11899
08:29:32,200 --> 08:29:33,440
parameters
11900
08:29:33,440 --> 08:29:37,080
here and we're just going to call get
11901
08:29:37,080 --> 08:29:39,840
feed follows and we'll just need to pass
11902
08:29:39,840 --> 08:29:42,478
in the user's
11903
08:29:42,478 --> 08:29:47,360
ID couldn't get feed
11904
08:29:47,360 --> 08:29:50,080
follows cool now we've got a list of
11905
08:29:50,080 --> 08:29:52,398
feed follows or a slice of feed follows
11906
08:29:52,398 --> 08:29:54,160
so we're going to need to convert an
11907
08:29:54,160 --> 08:29:57,600
entire slice so again here we'll write
11908
08:29:57,600 --> 08:30:00,318
this type of a function it's going to be
11909
08:30:00,318 --> 08:30:02,318
database
11910
08:30:02,318 --> 08:30:05,200
feed
11911
08:30:05,200 --> 08:30:09,120
follows to feed
11912
08:30:21,440 --> 08:30:25,718
follows all right
11913
08:30:26,040 --> 08:30:30,040
lots of copying and pasting here feed
11914
08:30:35,558 --> 08:30:37,760
follows okay so now we have a way to
11915
08:30:37,760 --> 08:30:40,360
convert an entire slice of database feed
11916
08:30:40,360 --> 08:30:42,718
follows to our own
11917
08:30:42,718 --> 08:30:46,478
struct that looks good to
11918
08:30:47,160 --> 08:30:49,050
me there feed
11919
08:30:49,050 --> 08:30:50,238
[Music]
11920
08:30:50,238 --> 08:30:52,638
follows okay cool now we have a Handler
11921
08:30:52,638 --> 08:30:54,478
for getting feed follows let's go ahead
11922
08:30:54,478 --> 08:30:57,638
and update this
11923
08:30:57,638 --> 08:31:01,200
so we need a new V1 router.
11924
08:31:01,200 --> 08:31:06,160
getet SL feed
11925
08:31:06,878 --> 08:31:10,520
follows middle wear
11926
08:31:10,920 --> 08:31:13,238
off get feed
11927
08:31:13,238 --> 08:31:15,920
follows Perfect all right let's give
11928
08:31:15,920 --> 08:31:16,920
that a
11929
08:31:16,920 --> 08:31:21,878
shot so we'll build and run again
11930
08:31:27,280 --> 08:31:32,478
and now let's see so this is um this is
11931
08:31:32,478 --> 08:31:35,398
the request that we used to
11932
08:31:35,398 --> 08:31:38,080
create so let's
11933
08:31:38,080 --> 08:31:41,958
grab oh so hardworking on such a small
11934
08:31:41,958 --> 08:31:46,000
screen let's grab our API key and create
11935
08:31:46,000 --> 08:31:48,360
a new
11936
08:31:51,520 --> 08:31:56,360
request 80 slv1 feed follows it's going
11937
08:31:56,360 --> 08:32:00,160
to be a get request it does need to be
11938
08:32:03,120 --> 08:32:06,478
authenticated okay see if that
11939
08:32:06,478 --> 08:32:10,040
works cool we got the one feedback that
11940
08:32:10,040 --> 08:32:12,558
we are currently following finally we
11941
08:32:12,558 --> 08:32:15,398
need a way to unfollow feeds or to
11942
08:32:15,398 --> 08:32:17,680
delete feed follows so let's create a
11943
08:32:17,680 --> 08:32:19,440
new one new
11944
08:32:19,440 --> 08:32:24,398
query we'll do delete feed follow now
11945
08:32:24,398 --> 08:32:26,040
this one is going to be our first quy
11946
08:32:26,040 --> 08:32:27,878
that doesn't actually return
11947
08:32:27,878 --> 08:32:31,080
anything um it's just going to be an
11948
08:32:31,080 --> 08:32:32,840
execute right we're not returning one
11949
08:32:32,840 --> 08:32:34,478
record we're not returning many records
11950
08:32:34,478 --> 08:32:35,840
we're returning no records we're just
11951
08:32:35,840 --> 08:32:39,878
going to run a a SQL query so uh it'll
11952
08:32:39,878 --> 08:32:41,360
it's going to be
11953
08:32:41,360 --> 08:32:43,760
delete
11954
08:32:43,760 --> 08:32:46,478
from bead
11955
08:32:46,478 --> 08:32:52,360
follows where ID equals dollar sign one
11956
08:32:52,360 --> 08:32:57,318
and user ID equals sign too now it's
11957
08:32:57,318 --> 08:32:59,478
important it's important to point out
11958
08:32:59,478 --> 08:33:02,318
that we don't actually need the user ID
11959
08:33:02,318 --> 08:33:04,558
here for this query to work right the ID
11960
08:33:04,558 --> 08:33:07,398
is already a unique identifier the
11961
08:33:07,398 --> 08:33:10,680
reason I'm tacking on this user ID is
11962
08:33:10,680 --> 08:33:13,360
because this will prevent someone who
11963
08:33:13,360 --> 08:33:16,920
doesn't own a feed follow from trying to
11964
08:33:16,920 --> 08:33:19,520
unfollow a feed on behalf of somebody
11965
08:33:19,520 --> 08:33:24,160
else that makes sense uh if for whatever
11966
08:33:24,160 --> 08:33:26,238
reason another user
11967
08:33:26,238 --> 08:33:28,760
got access let's say if if for some
11968
08:33:28,760 --> 08:33:31,798
reason user B got access to the feed
11969
08:33:31,798 --> 08:33:33,920
follow ID of user
11970
08:33:33,920 --> 08:33:38,600
a if we didn't have this check here then
11971
08:33:38,600 --> 08:33:41,840
that user who hijacked a feed follow ID
11972
08:33:41,840 --> 08:33:43,920
would be able to like
11973
08:33:43,920 --> 08:33:46,920
unfollow like force the other user to do
11974
08:33:46,920 --> 08:33:49,318
an unfollow if that makes sense this
11975
08:33:49,318 --> 08:33:51,878
ensures that only the user who actually
11976
08:33:51,878 --> 08:33:54,958
owns the follow record can execute the
11977
08:33:54,958 --> 08:33:57,718
unfollow Comm command hope hopefully
11978
08:33:57,718 --> 08:34:01,200
that makes sense okay uh from here let's
11979
08:34:01,200 --> 08:34:04,680
just go ahead and generate
11980
08:34:05,000 --> 08:34:09,840
that and go hook it up to a new
11981
08:34:10,680 --> 08:34:14,238
endpoint so we'll do
11982
08:34:14,238 --> 08:34:17,680
Handler delete feed
11983
08:34:17,680 --> 08:34:19,760
follow now this one's going to be a
11984
08:34:19,760 --> 08:34:21,160
little
11985
08:34:21,160 --> 08:34:23,840
different in that it it is authenticated
11986
08:34:23,840 --> 08:34:27,360
but we need to get a feed follow ID and
11987
08:34:27,360 --> 08:34:29,878
delete requests so like HTTP delete
11988
08:34:29,878 --> 08:34:32,760
requests the delete HTTP method they
11989
08:34:32,760 --> 08:34:35,360
don't typically have a body in the
11990
08:34:35,360 --> 08:34:37,280
payload it's it's possible but I would
11991
08:34:37,280 --> 08:34:39,798
argue it's not super conventional um
11992
08:34:39,798 --> 08:34:41,440
it's a little more conventional to pass
11993
08:34:41,440 --> 08:34:45,638
the ID in the HTTP path so um it's going
11994
08:34:45,638 --> 08:34:48,680
to look something like
11995
08:34:50,600 --> 08:34:54,600
this view on router. delete feed follows
11996
08:34:54,600 --> 08:34:56,280
slash
11997
08:34:56,280 --> 08:34:59,478
feed follow
11998
08:34:59,478 --> 08:35:02,280
ID and then this will be
11999
08:35:02,280 --> 08:35:06,478
Handler uh Delete feed follow right so
12000
08:35:06,478 --> 08:35:09,398
we want the feed follow ID dynamically
12001
08:35:09,398 --> 08:35:12,638
passed in the path of the request so the
12002
08:35:12,638 --> 08:35:14,520
question is how do we grab this feed
12003
08:35:14,520 --> 08:35:18,160
follow ID um in our Handler itself well
12004
08:35:18,160 --> 08:35:21,160
the chai router has or Chi oh I'm I'm
12005
08:35:21,160 --> 08:35:23,478
never going to say that the proper way
12006
08:35:23,478 --> 08:35:26,558
uh the chi router has a I think it's p
12007
08:35:26,558 --> 08:35:29,440
is it URL let's see
12008
08:35:29,440 --> 08:35:33,798
URL parameter that's the one uh Ur URL
12009
08:35:33,798 --> 08:35:35,478
parameter function where we can pass in
12010
08:35:35,478 --> 08:35:37,958
the request and a key and in this case
12011
08:35:37,958 --> 08:35:39,638
it's going to have to match so feed
12012
08:35:39,638 --> 08:35:42,718
follow ID matches whatever we type in
12013
08:35:42,718 --> 08:35:45,520
here between the open and close
12014
08:35:45,520 --> 08:35:48,000
brackets okay and that's going to return
12015
08:35:48,000 --> 08:35:53,040
a string so this is the feed follow ID
12016
08:35:53,040 --> 08:35:54,878
string great we're going to take that
12017
08:35:54,878 --> 08:35:57,558
and we're going to par it into a uuid so
12018
08:35:57,558 --> 08:36:01,160
we'll do U id.
12019
08:36:01,160 --> 08:36:05,440
parse and that will return a feed follow
12020
08:36:05,440 --> 08:36:09,000
ID and potentially an
12021
08:36:09,798 --> 08:36:13,520
error if the error does not equal nil
12022
08:36:13,520 --> 08:36:19,520
we'll say couldn't parse feed follow
12023
08:36:19,520 --> 08:36:22,958
ID and that will be a 400 level errror
12024
08:36:22,958 --> 08:36:25,840
perfect okay from here we should be able
12025
08:36:25,840 --> 08:36:29,878
to do apic CFG do database. delete feed
12026
08:36:29,878 --> 08:36:32,840
follow and we need to pass in the
12027
08:36:32,840 --> 08:36:34,040
request
12028
08:36:34,040 --> 08:36:36,280
context
12029
08:36:36,280 --> 08:36:42,080
and feed follow params so database. feed
12030
08:36:42,080 --> 08:36:45,120
delete feed follow parameters it takes
12031
08:36:45,120 --> 08:36:47,520
an ID and a user ID so the ID of the
12032
08:36:47,520 --> 08:36:48,558
feed
12033
08:36:48,558 --> 08:36:52,638
follow we just parsed and then the user
12034
08:36:52,638 --> 08:36:55,040
ID comes in with that user object
12035
08:36:55,040 --> 08:36:57,238
because this is an authenticated
12036
08:36:57,238 --> 08:36:59,798
request cool and that should return just
12037
08:36:59,798 --> 08:37:01,958
an
12038
08:37:04,440 --> 08:37:06,920
error right oh we it's just it's just
12039
08:37:06,920 --> 08:37:08,318
giv me yellow squigglies because I need
12040
08:37:08,318 --> 08:37:09,798
to handle the
12041
08:37:09,798 --> 08:37:11,318
air
12042
08:37:11,318 --> 08:37:13,798
couldn't elete
12043
08:37:13,798 --> 08:37:15,798
speed
12044
08:37:15,798 --> 08:37:18,520
follow perfect uh what do we respond
12045
08:37:18,520 --> 08:37:19,680
with here I guess we have a couple
12046
08:37:19,680 --> 08:37:21,680
different options um the simplest thing
12047
08:37:21,680 --> 08:37:23,080
would just be to respond with like an
12048
08:37:23,080 --> 08:37:26,120
empty Json object I guess
12049
08:37:26,120 --> 08:37:28,638
uh what matters to the client is
12050
08:37:28,638 --> 08:37:32,160
probably the 200 Response Code um so we
12051
08:37:32,160 --> 08:37:34,318
could like for the sake of Simplicity
12052
08:37:34,318 --> 08:37:36,000
just so we can use our respond with Json
12053
08:37:36,000 --> 08:37:38,760
function we'll just return an empty Json
12054
08:37:38,760 --> 08:37:41,280
object alternatively maybe we could
12055
08:37:41,280 --> 08:37:44,600
return an object that says like message
12056
08:37:44,600 --> 08:37:46,958
you know unfollow successful or
12057
08:37:46,958 --> 08:37:49,958
something um but it it doesn't matter
12058
08:37:49,958 --> 08:37:51,680
too much I think as long as it's a 200
12059
08:37:51,680 --> 08:37:53,558
level code uh we're pretty much good to
12060
08:37:53,558 --> 08:37:55,558
go
12061
08:37:55,558 --> 08:37:57,238
okay and that's already been hooked
12062
08:37:57,238 --> 08:38:00,798
up so let's go ahead and test
12063
08:38:00,798 --> 08:38:02,920
it uh I can't remember if I generated
12064
08:38:02,920 --> 08:38:04,440
let me do that again and then we'll
12065
08:38:04,440 --> 08:38:06,958
restart the
12066
08:38:07,798 --> 08:38:11,600
server and take a
12067
08:38:11,600 --> 08:38:15,798
look okay so this was our endpoint it's
12068
08:38:15,798 --> 08:38:18,080
returning the feeds that we're currently
12069
08:38:18,080 --> 08:38:21,398
following let's go ahead and delete this
12070
08:38:21,398 --> 08:38:25,958
feed follow so we need new request
12071
08:38:27,840 --> 08:38:30,080
this is going to be a delete request
12072
08:38:30,080 --> 08:38:32,318
we're going to unfollow a specific ID
12073
08:38:32,318 --> 08:38:35,000
we're going to unfollow this we're going
12074
08:38:35,000 --> 08:38:37,958
to delete this feed follow right feed
12075
08:38:37,958 --> 08:38:40,280
follow with that with that
12076
08:38:40,280 --> 08:38:43,120
ID and the headers we do need to be
12077
08:38:43,120 --> 08:38:46,760
authenticated as the same
12078
08:38:48,840 --> 08:38:52,280
person so
12079
08:38:54,360 --> 08:38:58,360
authorization same API key okay let's
12080
08:38:58,360 --> 08:39:02,000
run that delete we got a 200 response
12081
08:39:02,000 --> 08:39:04,718
now let's go do a get and make sure that
12082
08:39:04,718 --> 08:39:09,040
it's gone yep empty list or empty array
12083
08:39:09,040 --> 08:39:11,280
we're good to go okay we've built out
12084
08:39:11,280 --> 08:39:14,398
the majority of the crud section of our
12085
08:39:14,398 --> 08:39:16,318
API but we haven't built the most
12086
08:39:16,318 --> 08:39:18,160
interesting part which is the part of
12087
08:39:18,160 --> 08:39:20,238
the server that actually goes out and
12088
08:39:20,238 --> 08:39:22,638
fetches posts from the different RSS
12089
08:39:22,638 --> 08:39:25,440
feeds that exist in our database again
12090
08:39:25,440 --> 08:39:27,440
the whole purpose of this server that
12091
08:39:27,440 --> 08:39:29,360
we're building is so that it can keep
12092
08:39:29,360 --> 08:39:31,360
track of all of these different feeds in
12093
08:39:31,360 --> 08:39:33,160
the database and then go out
12094
08:39:33,160 --> 08:39:35,680
periodically and actually download all
12095
08:39:35,680 --> 08:39:38,840
of the posts that are on each individual
12096
08:39:38,840 --> 08:39:40,958
feed so for example we have a feed for
12097
08:39:40,958 --> 08:39:43,558
my personal blog post this server will
12098
08:39:43,558 --> 08:39:46,478
actually go out to my blog every I don't
12099
08:39:46,478 --> 08:39:48,840
know 10 minutes and check to see if
12100
08:39:48,840 --> 08:39:51,558
there's a new blog post to download and
12101
08:39:51,558 --> 08:39:53,638
store in the database so the first thing
12102
08:39:53,638 --> 08:39:57,200
we need to do is update the feeds table
12103
08:39:57,200 --> 08:39:59,558
to have one more column we need a new
12104
08:39:59,558 --> 08:40:02,318
column called last fetched at and it's
12105
08:40:02,318 --> 08:40:04,200
just so we can keep track of when we
12106
08:40:04,200 --> 08:40:06,878
last fetched the posts for a given feed
12107
08:40:06,878 --> 08:40:07,878
so let's go ahead and add that we'll
12108
08:40:07,878 --> 08:40:10,638
need new migration um and it will look
12109
08:40:10,638 --> 08:40:12,878
kind of like this migration uh it's
12110
08:40:12,878 --> 08:40:15,558
going to be our fifth migration so far
12111
08:40:15,558 --> 08:40:17,558
it's going to be on the feeds table and
12112
08:40:17,558 --> 08:40:19,958
we're going to be adding the last
12113
08:40:19,958 --> 08:40:25,878
fetched at last fetched at field okay so
12114
08:40:25,878 --> 08:40:30,160
alter table feeds add column last
12115
08:40:30,160 --> 08:40:33,120
fetched
12116
08:40:33,238 --> 08:40:37,398
at and this one is going to
12117
08:40:37,398 --> 08:40:39,398
be
12118
08:40:39,398 --> 08:40:41,840
timestamp and it will be nullable so we
12119
08:40:41,840 --> 08:40:45,000
don't need a notnull constraint
12120
08:40:45,000 --> 08:40:47,878
um in fact that's it
12121
08:40:47,878 --> 08:40:50,200
um it's okay like we don't need to
12122
08:40:50,200 --> 08:40:52,080
specify any defaults uh that should be
12123
08:40:52,080 --> 08:40:54,520
it um and then as far as the down
12124
08:40:54,520 --> 08:40:57,520
migration goes we'll just be deleting or
12125
08:40:57,520 --> 08:41:00,440
dropping the column from the feeds table
12126
08:41:00,440 --> 08:41:05,280
okay cool let's run that
12127
08:41:06,000 --> 08:41:10,360
migration so Goose
12128
08:41:15,680 --> 08:41:18,558
postgress perfect so we don't need to
12129
08:41:18,558 --> 08:41:21,440
update the create feed uh
12130
08:41:21,440 --> 08:41:24,160
function we want the last fetch St field
12131
08:41:24,160 --> 08:41:25,878
to default to null so no changes are
12132
08:41:25,878 --> 08:41:28,280
necessary there but we do need a new we
12133
08:41:28,280 --> 08:41:29,798
do need a new query this one's going to
12134
08:41:29,798 --> 08:41:31,840
be
12135
08:41:31,840 --> 08:41:37,120
called get next oh my gosh get next feed
12136
08:41:37,120 --> 08:41:39,920
to fetch can't type today get next feed
12137
08:41:39,920 --> 08:41:42,280
to fetch and it will return a single
12138
08:41:42,280 --> 08:41:45,440
row and this one should say select
12139
08:41:45,440 --> 08:41:49,040
star from
12140
08:41:49,080 --> 08:41:51,398
feeds order
12141
08:41:51,398 --> 08:41:56,120
by last fetched at descending
12142
08:41:56,120 --> 08:41:57,958
NS
12143
08:41:57,958 --> 08:42:01,238
first limit
12144
08:42:01,238 --> 08:42:05,080
one okay so we always this the purpose
12145
08:42:05,080 --> 08:42:07,318
of this function is to go get the feed
12146
08:42:07,318 --> 08:42:10,558
that next needs to be fetched like we
12147
08:42:10,558 --> 08:42:14,238
need to go get posts for this feed next
12148
08:42:14,238 --> 08:42:17,160
and the whole idea is first we want to
12149
08:42:17,160 --> 08:42:19,160
go find any feeds that have never been
12150
08:42:19,160 --> 08:42:20,798
fetched before those need to take
12151
08:42:20,798 --> 08:42:24,080
priority after that if every feed has
12152
08:42:24,080 --> 08:42:26,440
been fetched then we want to go find the
12153
08:42:26,440 --> 08:42:29,000
one that was fetched the longest ago
12154
08:42:29,000 --> 08:42:31,000
like the farthest in the past right so
12155
08:42:31,000 --> 08:42:33,280
we're ordering by last fetched at um
12156
08:42:33,280 --> 08:42:37,200
nulls first in descending
12157
08:42:37,200 --> 08:42:39,558
order actually scratch that we're going
12158
08:42:39,558 --> 08:42:43,000
to want to do a ascending right
12159
08:42:43,000 --> 08:42:45,840
ascending would put the lowest the
12160
08:42:45,840 --> 08:42:47,520
smallest time stamps right the ones
12161
08:42:47,520 --> 08:42:50,080
further in the past at the top and then
12162
08:42:50,080 --> 08:42:54,160
Ascend into the present okay so order by
12163
08:42:54,160 --> 08:42:57,200
last fetch thatat ascend ending NS first
12164
08:42:57,200 --> 08:42:59,200
perfect okay just to make sure that my
12165
08:42:59,200 --> 08:43:02,440
SQL code is valid we'll generate that
12166
08:43:02,440 --> 08:43:04,680
looks good okay next we need one more
12167
08:43:04,680 --> 08:43:06,638
query this one will be
12168
08:43:06,638 --> 08:43:09,840
called uh Mark feed
12169
08:43:09,840 --> 08:43:13,080
fetched Mark feed I guess as
12170
08:43:13,080 --> 08:43:15,080
fetched this is the one we'll call after
12171
08:43:15,080 --> 08:43:17,238
we fetch a feed to say that we fetched
12172
08:43:17,238 --> 08:43:21,120
it um and we'll return the updated feed
12173
08:43:21,120 --> 08:43:22,760
okay so it's going to be
12174
08:43:22,760 --> 08:43:26,000
update feeds
12175
08:43:26,000 --> 08:43:30,000
set last fetched at equal to
12176
08:43:30,000 --> 08:43:36,080
now and updated at also equal to now so
12177
08:43:36,080 --> 08:43:37,840
we haven't really gone over this but the
12178
08:43:37,840 --> 08:43:39,718
updated at and created at fields are
12179
08:43:39,718 --> 08:43:41,718
mostly for auditing purposes it's pretty
12180
08:43:41,718 --> 08:43:44,638
standard practice to set these fields on
12181
08:43:44,638 --> 08:43:46,760
basically every record in an SQL
12182
08:43:46,760 --> 08:43:48,878
database just so you can see when
12183
08:43:48,878 --> 08:43:50,840
they've been created and updated it's
12184
08:43:50,840 --> 08:43:52,718
kind of again auditing
12185
08:43:52,718 --> 08:43:57,040
purposes okay uh where
12186
08:43:57,040 --> 08:44:00,840
ID equals dollar sign
12187
08:44:00,840 --> 08:44:02,680
one
12188
08:44:02,680 --> 08:44:05,680
and returning
12189
08:44:05,680 --> 08:44:09,040
star okay so we update the feeds we set
12190
08:44:09,040 --> 08:44:10,958
the last fetch at and the updated at to
12191
08:44:10,958 --> 08:44:14,280
the current time for the given ID that
12192
08:44:14,280 --> 08:44:15,520
looks good to me let's go ahead and
12193
08:44:15,520 --> 08:44:19,440
generate that perfect next we need a way
12194
08:44:19,440 --> 08:44:23,000
to kind of take an RSS URL or a feed URL
12195
08:44:23,000 --> 08:44:26,160
and parse it into an an actual response
12196
08:44:26,160 --> 08:44:27,958
body and in this case we're going to
12197
08:44:27,958 --> 08:44:29,840
represent it as a struct let me show you
12198
08:44:29,840 --> 08:44:32,040
what I mean so let's create a new file
12199
08:44:32,040 --> 08:44:35,878
I'm just going to call it rs.
12200
08:44:36,080 --> 08:44:40,000
Go and it's going to be part of the main
12201
08:44:40,000 --> 08:44:42,958
package and we need a new function and
12202
08:44:42,958 --> 08:44:45,920
we're going to call it RSS
12203
08:44:45,920 --> 08:44:49,040
to or actually let's call it
12204
08:44:49,040 --> 08:44:51,718
url url to
12205
08:44:51,718 --> 08:44:53,558
feed
12206
08:44:53,558 --> 08:44:57,478
okay and it's going to take as input a
12207
08:44:57,478 --> 08:45:00,360
URL which is just a string and it will
12208
08:45:00,360 --> 08:45:02,760
return a new type so we need to specify
12209
08:45:02,760 --> 08:45:07,958
the new type type um RSS
12210
08:45:08,478 --> 08:45:12,360
feed it will return both an RSS feed and
12211
08:45:12,360 --> 08:45:13,520
potentially an error if there's
12212
08:45:13,520 --> 08:45:15,318
something wrong uh with the request that
12213
08:45:15,318 --> 08:45:19,160
it's making now that RSS feed struct
12214
08:45:19,160 --> 08:45:20,558
that we just created is going to
12215
08:45:20,558 --> 08:45:23,558
represent basically this giant this
12216
08:45:23,558 --> 08:45:25,878
giant document here right so if you go
12217
08:45:25,878 --> 08:45:29,878
to Wags lane. deev index.xml which is a
12218
08:45:29,878 --> 08:45:33,318
valid RSS feed then you'll see this
12219
08:45:33,318 --> 08:45:35,120
giant document and really you can think
12220
08:45:35,120 --> 08:45:38,478
of RSS as just structured data in XML
12221
08:45:38,478 --> 08:45:40,958
format and XML is just kind of like
12222
08:45:40,958 --> 08:45:44,520
crappy Json so the way we parse XML in
12223
08:45:44,520 --> 08:45:48,000
go is very similar to The Way We parse
12224
08:45:48,000 --> 08:45:50,200
Json let me show you what I mean I've
12225
08:45:50,200 --> 08:45:52,200
done the Dirty Work of scanning all of
12226
08:45:52,200 --> 08:45:56,000
the valid um values in that big RSS
12227
08:45:56,000 --> 08:45:58,840
document and I found that basically
12228
08:45:58,840 --> 08:46:00,160
these are the
12229
08:46:00,160 --> 08:46:05,638
keys um for the RSS entries in my blog
12230
08:46:05,638 --> 08:46:09,000
so RSS is kind of a standardized set of
12231
08:46:09,000 --> 08:46:12,000
keys within XML um and basically what
12232
08:46:12,000 --> 08:46:13,680
I'm saying is these are the keys that we
12233
08:46:13,680 --> 08:46:15,440
care about right at the top level of an
12234
08:46:15,440 --> 08:46:19,238
RSS feed we expect a channel key right
12235
08:46:19,238 --> 08:46:21,318
in the XML document and we expect a
12236
08:46:21,318 --> 08:46:23,040
channel to have a title a link a
12237
08:46:23,040 --> 08:46:26,238
description a language and then a slice
12238
08:46:26,238 --> 08:46:28,638
of items and then items are kind of
12239
08:46:28,638 --> 08:46:30,520
these nested objects that each have
12240
08:46:30,520 --> 08:46:32,878
their own title link descriptions and
12241
08:46:32,878 --> 08:46:35,600
publication dates right and each item is
12242
08:46:35,600 --> 08:46:38,478
a new blog post and if you're asking how
12243
08:46:38,478 --> 08:46:41,440
I came up with those names of all of the
12244
08:46:41,440 --> 08:46:42,680
different Keys it's because I went and
12245
08:46:42,680 --> 08:46:44,638
looked here in this document I saw okay
12246
08:46:44,638 --> 08:46:46,958
at the top level we have a channel right
12247
08:46:46,958 --> 08:46:49,318
and then we have um this entry with a
12248
08:46:49,318 --> 08:46:52,318
title a link a description right so I
12249
08:46:52,318 --> 08:46:54,120
just kind of manually looked through
12250
08:46:54,120 --> 08:46:56,160
this document and found all the stuff
12251
08:46:56,160 --> 08:46:58,080
that I wanted to parse out so let's fill
12252
08:46:58,080 --> 08:47:00,958
in the rest of this URL to feed function
12253
08:47:00,958 --> 08:47:02,718
so first we're going to need an HTTP
12254
08:47:02,718 --> 08:47:05,318
client um I'm just creating a new client
12255
08:47:05,318 --> 08:47:07,558
using the HTTP Library um we'll set it
12256
08:47:07,558 --> 08:47:09,280
to a timeout of 10 seconds if it takes
12257
08:47:09,280 --> 08:47:11,280
more than 10 seconds to fetch an RSS
12258
08:47:11,280 --> 08:47:13,478
feed uh we don't want that feed anyway
12259
08:47:13,478 --> 08:47:16,398
probably broken okay uh then we can use
12260
08:47:16,398 --> 08:47:19,280
that client to make a get request
12261
08:47:19,280 --> 08:47:22,638
to the URL of the feed and that's going
12262
08:47:22,638 --> 08:47:25,440
to return an HTTP response and
12263
08:47:25,440 --> 08:47:28,040
potentially an
12264
08:47:28,080 --> 08:47:30,760
error if there's an error we'll just
12265
08:47:30,760 --> 08:47:32,920
return let's just
12266
08:47:32,920 --> 08:47:36,558
do um for cons for ease of use I'm going
12267
08:47:36,558 --> 08:47:38,360
to make this a pointer to an RSS feed so
12268
08:47:38,360 --> 08:47:41,440
we can just return nil and the
12269
08:47:41,440 --> 08:47:45,080
airor cool um if everything's okay then
12270
08:47:45,080 --> 08:47:47,520
we're going to defer a
12271
08:47:47,520 --> 08:47:51,760
close on let's close on the resp sorry
12272
08:47:51,760 --> 08:47:53,398
it's not it's not the close function
12273
08:47:53,398 --> 08:47:56,760
it's resp. body
12274
08:47:57,878 --> 08:48:00,440
close Okay and then after that we want
12275
08:48:00,440 --> 08:48:03,600
to get all of the data from the response
12276
08:48:03,600 --> 08:48:06,398
body so it's going to be io. readall we
12277
08:48:06,398 --> 08:48:10,520
have to read everything from resp. body
12278
08:48:10,520 --> 08:48:13,080
and that comes back as a slice of bites
12279
08:48:13,080 --> 08:48:15,478
and an
12280
08:48:18,000 --> 08:48:21,520
error okay this slice of bytes we want
12281
08:48:21,520 --> 08:48:23,200
to read
12282
08:48:23,200 --> 08:48:27,840
into this RSS feed so dealing with XML
12283
08:48:27,840 --> 08:48:31,718
in go is very similar to dealing with
12284
08:48:31,718 --> 08:48:34,160
Json and go it's actually going to be
12285
08:48:34,160 --> 08:48:36,160
XML
12286
08:48:36,160 --> 08:48:37,680
dot
12287
08:48:37,680 --> 08:48:41,238
unmarshall pass in the data and a
12288
08:48:41,238 --> 08:48:43,680
pointer to where we want to unmarshal
12289
08:48:43,680 --> 08:48:44,920
the data so actually I need to create an
12290
08:48:44,920 --> 08:48:47,520
empty struct we need RSS
12291
08:48:47,520 --> 08:48:51,520
feed is an empty RSS feed
12292
08:48:51,520 --> 08:48:55,200
struct then we'll unmarshall into that
12293
08:48:55,200 --> 08:48:56,718
location in
12294
08:48:56,718 --> 08:49:00,360
memory that will return an
12295
08:49:00,360 --> 08:49:02,680
error if everything goes well then we
12296
08:49:02,680 --> 08:49:07,878
can just return the new populated RSS
12297
08:49:10,558 --> 08:49:13,798
feed perfect now as I type this out I'm
12298
08:49:13,798 --> 08:49:15,840
already kind of dissatisfied with this
12299
08:49:15,840 --> 08:49:17,238
pointer solution I don't think that
12300
08:49:17,238 --> 08:49:19,080
needs to be a pointer I think we should
12301
08:49:19,080 --> 08:49:21,760
just return empty
12302
08:49:21,760 --> 08:49:24,840
structs um either way would work I think
12303
08:49:24,840 --> 08:49:26,360
this is a little cleaner though because
12304
08:49:26,360 --> 08:49:29,958
it means the user of this function us
12305
08:49:29,958 --> 08:49:32,080
right uh will will get an actual RSS
12306
08:49:32,080 --> 08:49:33,760
feedback and not a pointer to an RSS
12307
08:49:33,760 --> 08:49:35,958
feed okay let's go ahead and test this
12308
08:49:35,958 --> 08:49:37,318
really quick I'm just going to do a
12309
08:49:37,318 --> 08:49:40,120
little kind of hacky
12310
08:49:40,120 --> 08:49:42,478
thing just right at the top of main I'm
12311
08:49:42,478 --> 08:49:45,558
going to call URL to feed and give it
12312
08:49:45,558 --> 08:49:51,000
the URL of um my blog so waglan
12313
08:49:51,000 --> 08:49:55,000
dodev index.xml
12314
08:49:55,000 --> 08:49:58,760
that should return a feed and an
12315
08:49:58,760 --> 08:50:04,000
error right and then if error not equal
12316
08:50:04,000 --> 08:50:06,360
nil log.
12317
08:50:06,360 --> 08:50:09,398
fatal error otherwise I want to just
12318
08:50:09,398 --> 08:50:14,120
print out fmt do print line let's just
12319
08:50:14,120 --> 08:50:15,638
print out the whole feed it'll be
12320
08:50:15,638 --> 08:50:17,920
disgusting but at least we'll get to see
12321
08:50:17,920 --> 08:50:21,200
if it kind of worked okay let's build
12322
08:50:21,200 --> 08:50:24,718
and run that
12323
08:50:30,718 --> 08:50:32,200
there we
12324
08:50:32,200 --> 08:50:35,160
go cool so if you kind of scroll through
12325
08:50:35,160 --> 08:50:37,520
this you'll see it looks like I mean
12326
08:50:37,520 --> 08:50:39,600
there was no errors and then it looks
12327
08:50:39,600 --> 08:50:41,318
like we
12328
08:50:41,318 --> 08:50:44,200
properly at least you know at first
12329
08:50:44,200 --> 08:50:45,638
glance looks like we properly filled out
12330
08:50:45,638 --> 08:50:47,638
that struct it's kind of just dumping
12331
08:50:47,638 --> 08:50:50,360
all of the data so now that we've done a
12332
08:50:50,360 --> 08:50:53,398
sanity test on our URL to feed function
12333
08:50:53,398 --> 08:50:55,520
let's go write the actual ual
12334
08:50:55,520 --> 08:51:00,600
scraper create a new file just call this
12335
08:51:19,440 --> 08:51:22,200
scraper.com so we can really see so we
12336
08:51:22,200 --> 08:51:25,040
can actually see what uh what we're
12337
08:51:25,040 --> 08:51:27,080
dealing with here so it'll take three
12338
08:51:27,080 --> 08:51:31,360
inputs a connection to the database um a
12339
08:51:31,360 --> 08:51:32,840
number of
12340
08:51:32,840 --> 08:51:35,238
concurrency units I guess the best way
12341
08:51:35,238 --> 08:51:36,638
to think about this is how many
12342
08:51:36,638 --> 08:51:38,760
different go routines we want to do the
12343
08:51:38,760 --> 08:51:43,120
scraping on and then how much time uh we
12344
08:51:43,120 --> 08:51:45,200
want in between each request to go
12345
08:51:45,200 --> 08:51:49,318
scrape a new RSS feed cool and it
12346
08:51:49,318 --> 08:51:50,600
shouldn't return anything because this
12347
08:51:50,600 --> 08:51:52,840
is going to be a long running job now
12348
08:51:52,840 --> 08:51:54,840
because this worker this scrap rper is
12349
08:51:54,840 --> 08:51:56,160
going to be running in the background of
12350
08:51:56,160 --> 08:51:57,680
our server I think it's really important
12351
08:51:57,680 --> 08:51:59,920
that we have good logging um that kind
12352
08:51:59,920 --> 08:52:02,238
of tells us what's going on as it's
12353
08:52:02,238 --> 08:52:04,718
happening so when we start scraping I'm
12354
08:52:04,718 --> 08:52:07,398
going to do a a little log message here
12355
08:52:07,398 --> 08:52:09,280
so log.
12356
08:52:09,280 --> 08:52:13,200
printf we say
12357
08:52:13,200 --> 08:52:18,558
scraping on percent V go
12358
08:52:18,558 --> 08:52:24,878
routines every percent s duration
12359
08:52:24,878 --> 08:52:27,120
pass in the concurrency and the time
12360
08:52:27,120 --> 08:52:28,718
between
12361
08:52:28,718 --> 08:52:32,280
requests cool after that we need to
12362
08:52:32,280 --> 08:52:34,718
figure out like how we're going to make
12363
08:52:34,718 --> 08:52:37,798
our requests on this interval and
12364
08:52:37,798 --> 08:52:40,718
there's a really cool um mechanism in
12365
08:52:40,718 --> 08:52:42,478
the standard library and go called a
12366
08:52:42,478 --> 08:52:45,920
ticker so we can create a new ticker uh
12367
08:52:45,920 --> 08:52:48,478
using the standard Library so time. new
12368
08:52:48,478 --> 08:52:50,798
ticker and we give it a duration in this
12369
08:52:50,798 --> 08:52:53,238
case time between
12370
08:52:53,238 --> 08:52:56,840
requests and it responds with a
12371
08:52:56,840 --> 08:53:00,760
ticker and then we can use a for
12372
08:53:00,760 --> 08:53:04,680
Loop to execute the body of the for Loop
12373
08:53:04,680 --> 08:53:08,160
every time a new value comes across the
12374
08:53:08,160 --> 08:53:10,638
ticker's channel so the ticker Has a
12375
08:53:10,638 --> 08:53:14,798
Field called C which is a channel where
12376
08:53:14,798 --> 08:53:17,280
every kind of let's say that you know
12377
08:53:17,280 --> 08:53:18,760
time between request was set to one
12378
08:53:18,760 --> 08:53:21,718
minute in that case every one minute a
12379
08:53:21,718 --> 08:53:23,558
value would be sent across the channel
12380
08:53:23,558 --> 08:53:25,920
so by using this syntax here we could
12381
08:53:25,920 --> 08:53:29,160
say run this for Loop every one minute
12382
08:53:29,160 --> 08:53:32,160
and the reason I'm passing in an empty
12383
08:53:32,160 --> 08:53:34,878
initializes and an empty um middle
12384
08:53:34,878 --> 08:53:36,798
section to the for Loop is so that it
12385
08:53:36,798 --> 08:53:39,318
executes immediately the first time so
12386
08:53:39,318 --> 08:53:41,520
the very first time we get to line 17
12387
08:53:41,520 --> 08:53:43,840
the body of the for Loop will requ will
12388
08:53:43,840 --> 08:53:47,280
will fire immediately and then it will
12389
08:53:47,280 --> 08:53:50,160
wait for the for the uh interval on the
12390
08:53:50,160 --> 08:53:52,000
ticker if that makes sense if we just
12391
08:53:52,000 --> 08:53:55,878
did this oops if we just did what is it
12392
08:53:55,878 --> 08:53:57,680
for
12393
08:53:57,680 --> 08:54:00,680
range tier. C uh then it would actually
12394
08:54:00,680 --> 08:54:02,200
wait for the minute up front but I want
12395
08:54:02,200 --> 08:54:04,680
to do it once immediately um it'll make
12396
08:54:04,680 --> 08:54:06,798
it easier to debug and work with now at
12397
08:54:06,798 --> 08:54:08,638
this point I realized that I've made a
12398
08:54:08,638 --> 08:54:11,520
mistake the purpose of this concurrency
12399
08:54:11,520 --> 08:54:13,920
parameter here is to uh you know
12400
08:54:13,920 --> 08:54:16,318
indicate to the start scraping function
12401
08:54:16,318 --> 08:54:18,360
how many go routines we want to use to
12402
08:54:18,360 --> 08:54:21,478
go fetch um all these different feeds
12403
08:54:21,478 --> 08:54:23,160
and the whole point is that we can fetch
12404
08:54:23,160 --> 08:54:25,680
them at the same time time so that means
12405
08:54:25,680 --> 08:54:27,718
that each time that this ticker fires we
12406
08:54:27,718 --> 08:54:29,878
need to be potentially go you know going
12407
08:54:29,878 --> 08:54:33,760
out to the internet to fetch 10 20 30
12408
08:54:33,760 --> 08:54:36,318
different RSS feeds and download all of
12409
08:54:36,318 --> 08:54:39,160
their blog posts at the same time which
12410
08:54:39,160 --> 08:54:42,000
means we'll actually need to be able to
12411
08:54:42,000 --> 08:54:44,520
grab a multiple number of feeds we'll
12412
08:54:44,520 --> 08:54:47,040
need to grab more than just one at a
12413
08:54:47,040 --> 08:54:48,920
time so rather than get next feed to
12414
08:54:48,920 --> 08:54:51,120
fetch let's change this to get next
12415
08:54:51,120 --> 08:54:54,000
feeds to fetch and we'll have it return
12416
08:54:54,000 --> 08:54:54,920
many
12417
08:54:54,920 --> 08:54:56,798
and then rather than limiting to one
12418
08:54:56,798 --> 08:54:59,440
let's limit to dollar sign one so we can
12419
08:54:59,440 --> 08:55:03,280
actually pass in how many feeds we want
12420
08:55:03,280 --> 08:55:06,000
as a parameter to this function okay
12421
08:55:06,000 --> 08:55:10,398
then we should be able to regenerate
12422
08:55:12,558 --> 08:55:15,760
that and we should oh we're not even
12423
08:55:15,760 --> 08:55:17,878
using the function yet so okay so that
12424
08:55:17,878 --> 08:55:19,840
was actually the perfect time to do that
12425
08:55:19,840 --> 08:55:21,558
okay let's fill out the body of this for
12426
08:55:21,558 --> 08:55:23,958
Loop so every interval time between
12427
08:55:23,958 --> 08:55:26,638
request we want to go grab the next
12428
08:55:26,638 --> 08:55:28,558
batch of feeds to fetch so we can just
12429
08:55:28,558 --> 08:55:30,478
call that function that we just wrote
12430
08:55:30,478 --> 08:55:33,878
database. getet next feeds to fetch it
12431
08:55:33,878 --> 08:55:37,558
takes a context and a limit so the first
12432
08:55:37,558 --> 08:55:41,318
thing we'll just use context. background
12433
08:55:41,318 --> 08:55:43,280
so again I haven't gone into a ton of
12434
08:55:43,280 --> 08:55:45,318
detail on the context package but
12435
08:55:45,318 --> 08:55:47,478
basically context. background is like
12436
08:55:47,478 --> 08:55:50,000
the global context it's what you use if
12437
08:55:50,000 --> 08:55:51,760
you don't have access to a scoped
12438
08:55:51,760 --> 08:55:54,360
context like we do for our individual
12439
08:55:54,360 --> 08:55:57,120
TTP requests okay so that'll work for
12440
08:55:57,120 --> 08:55:59,520
now and then we also need to pass in a
12441
08:55:59,520 --> 08:56:03,638
limit so we'll just cast int 32 and the
12442
08:56:03,638 --> 08:56:07,160
limit or the sorry the
12443
08:56:08,920 --> 08:56:11,478
concurrency and that should return some
12444
08:56:11,478 --> 08:56:14,200
feeds and an
12445
08:56:16,200 --> 08:56:18,360
err if there's an error we should
12446
08:56:18,360 --> 08:56:22,040
probably print something
12447
08:56:31,478 --> 08:56:33,840
now notice I'm continuing here that's
12448
08:56:33,840 --> 08:56:36,600
because this function should always be
12449
08:56:36,600 --> 08:56:39,040
running as our
12450
08:56:39,040 --> 08:56:42,000
server operates like there's no time in
12451
08:56:42,000 --> 08:56:44,080
which we want this function to ever stop
12452
08:56:44,080 --> 08:56:45,638
so if I returned here that would be a
12453
08:56:45,638 --> 08:56:47,638
problem it would actually stop scraping
12454
08:56:47,638 --> 08:56:49,200
completely just because maybe I don't
12455
08:56:49,200 --> 08:56:50,760
know our database connection was down
12456
08:56:50,760 --> 08:56:52,558
temporarily so for now we're just going
12457
08:56:52,558 --> 08:56:55,478
to log and continue now that we have a
12458
08:56:55,478 --> 08:56:57,878
slice of feeds let's write some logic
12459
08:56:57,878 --> 08:56:59,718
that goes and fetches each feed
12460
08:56:59,718 --> 08:57:01,958
individually and importantly fetches
12461
08:57:01,958 --> 08:57:05,318
each individually at the same time so
12462
08:57:05,318 --> 08:57:07,000
we're going to need a synchronization
12463
08:57:07,000 --> 08:57:08,798
mechanism uh I'm going to use a weight
12464
08:57:08,798 --> 08:57:11,360
group so the standard library has this
12465
08:57:11,360 --> 08:57:15,080
awesome thing called a sync. weight
12466
08:57:15,120 --> 08:57:17,600
group then we can iterate over all of
12467
08:57:17,600 --> 08:57:24,798
the feeds so four feed range feeds
12468
08:57:26,120 --> 08:57:27,878
okay so the way that the weight group
12469
08:57:27,878 --> 08:57:31,080
works is anytime you want to spawn a new
12470
08:57:31,080 --> 08:57:33,280
go routine within the context of the
12471
08:57:33,280 --> 08:57:37,080
weight group you do a weight group. add
12472
08:57:37,080 --> 08:57:39,440
and you add some number to it so here
12473
08:57:39,440 --> 08:57:41,718
I'm iterating over all of the feeds that
12474
08:57:41,718 --> 08:57:43,558
we want to fetch on individual go
12475
08:57:43,558 --> 08:57:45,798
routines and I'm going to add one to the
12476
08:57:45,798 --> 08:57:46,760
weight
12477
08:57:46,760 --> 08:57:49,680
group then at the end of the loop I can
12478
08:57:49,680 --> 08:57:52,958
do a weight group.
12479
08:57:52,958 --> 08:57:56,398
weight and and within the loop I can
12480
08:57:56,398 --> 08:57:58,600
spawn a new go routine so we're going to
12481
08:57:58,600 --> 08:58:01,318
go do some function in fact I guess I
12482
08:58:01,318 --> 08:58:03,238
should just name it kind of what we'll
12483
08:58:03,238 --> 08:58:07,718
be doing uh let's call it scrape feed go
12484
08:58:07,718 --> 08:58:10,798
scrape feed and here we're actually
12485
08:58:10,798 --> 08:58:13,680
going to pass the weight group in as one
12486
08:58:13,680 --> 08:58:14,520
of the
12487
08:58:14,520 --> 08:58:17,318
parameters and
12488
08:58:17,318 --> 08:58:20,360
within scrape
12489
08:58:20,360 --> 08:58:23,000
bead takes a weight group which is a
12490
08:58:23,000 --> 08:58:25,478
pointer to a
12491
08:58:25,478 --> 08:58:28,238
sync. weight
12492
08:58:28,238 --> 08:58:31,318
group within this function we'll defer a
12493
08:58:31,318 --> 08:58:33,360
weight group.
12494
08:58:33,360 --> 08:58:38,080
done okay so what happens here
12495
08:58:38,080 --> 08:58:40,878
basically we're iterating over the the
12496
08:58:40,878 --> 08:58:43,958
the all of the feeds on the same go
12497
08:58:43,958 --> 08:58:45,958
routine as the you know the start
12498
08:58:45,958 --> 08:58:49,280
scraping uh function so on the main go
12499
08:58:49,280 --> 08:58:52,080
routine on the main go routine we are
12500
08:58:52,080 --> 08:58:54,920
adding one to the weight group for every
12501
08:58:54,920 --> 08:58:57,238
feed right so say we had a concurrency
12502
08:58:57,238 --> 08:59:00,440
of 30 we would be adding 30 to the
12503
08:59:00,440 --> 08:59:03,600
weight group now we'll be spawning all
12504
08:59:03,600 --> 08:59:06,160
of these separate go routines as we do
12505
08:59:06,160 --> 08:59:07,878
that and when we get to the end of the
12506
08:59:07,878 --> 08:59:10,238
loop we're going to be waiting on the
12507
08:59:10,238 --> 08:59:14,318
weight group for 30 30
12508
08:59:14,318 --> 08:59:18,440
distinct calls to done so done
12509
08:59:18,440 --> 08:59:21,160
effectively decrements the counter by
12510
08:59:21,160 --> 08:59:23,398
one right done decrements the counter by
12511
08:59:23,398 --> 08:59:26,000
one so we're adding one every time we
12512
08:59:26,000 --> 08:59:28,440
iterate over the slice and then we're
12513
08:59:28,440 --> 08:59:30,360
calling done when we're done actually
12514
08:59:30,360 --> 08:59:32,520
scraping the feed so what this does is
12515
08:59:32,520 --> 08:59:35,440
it allows us to call scrape feed at the
12516
08:59:35,440 --> 08:59:38,920
same time 30 times we go spawn 30
12517
08:59:38,920 --> 08:59:41,120
different go routines to scrape 30
12518
08:59:41,120 --> 08:59:42,600
different RSS
12519
08:59:42,600 --> 08:59:47,558
feeds and when they're all done line 35
12520
08:59:47,558 --> 08:59:49,680
will kind of execute and we'll move past
12521
08:59:49,680 --> 08:59:51,760
that until they're like before they're
12522
08:59:51,760 --> 08:59:53,840
done we'll be blocking on line 35 which
12523
08:59:53,840 --> 08:59:55,360
is what we want to do because we don't
12524
08:59:55,360 --> 08:59:57,318
want to continue on to the next
12525
08:59:57,318 --> 09:00:00,558
iteration of the loop until we are sure
12526
09:00:00,558 --> 09:00:02,478
that we've actually scraped all of the
12527
09:00:02,478 --> 09:00:05,000
feeds so we've sort of stubbed out this
12528
09:00:05,000 --> 09:00:06,160
scrape feed function right now it
12529
09:00:06,160 --> 09:00:07,718
doesn't do anything other than call
12530
09:00:07,718 --> 09:00:09,760
weight group. let's actually go scrape
12531
09:00:09,760 --> 09:00:12,600
some feeds so it's going to need access
12532
09:00:12,600 --> 09:00:14,280
to a database
12533
09:00:14,280 --> 09:00:17,160
connection and it's also going to need a
12534
09:00:17,160 --> 09:00:20,080
specific feed to go fetch so feed is a
12535
09:00:20,080 --> 09:00:24,238
datab base. feed
12536
09:00:24,238 --> 09:00:26,760
cool and then here we can pass in
12537
09:00:26,760 --> 09:00:29,478
database and
12538
09:00:29,478 --> 09:00:33,238
feed great the first thing scrape feed
12539
09:00:33,238 --> 09:00:35,280
should do and and keep in mind we're
12540
09:00:35,280 --> 09:00:37,000
deferring the weight group. dun so this
12541
09:00:37,000 --> 09:00:40,000
will always be called at the end of this
12542
09:00:40,000 --> 09:00:41,878
function um the first thing we should do
12543
09:00:41,878 --> 09:00:44,160
is Mark that we've fetched this feed or
12544
09:00:44,160 --> 09:00:45,958
that we're fetching this feed so it's
12545
09:00:45,958 --> 09:00:47,958
going to be database. Mark feed as
12546
09:00:47,958 --> 09:00:50,600
fetched we can just use the background
12547
09:00:50,600 --> 09:00:52,920
context
12548
09:00:52,920 --> 09:00:55,558
again and we need the ID of the feed so
12549
09:00:55,558 --> 09:00:58,120
feed dot
12550
09:00:58,120 --> 09:01:01,398
ID cool that should return an error if
12551
09:01:01,398 --> 09:01:03,318
there was an error I think oh it also
12552
09:01:03,318 --> 09:01:04,920
Returns the updated feed I don't think
12553
09:01:04,920 --> 09:01:06,238
we care about the updated feed so I
12554
09:01:06,238 --> 09:01:08,440
think we can ignore
12555
09:01:08,440 --> 09:01:12,080
that say if air is not equal nil now
12556
09:01:12,080 --> 09:01:13,600
keep in mind we are not returning
12557
09:01:13,600 --> 09:01:14,958
anything from this function remember
12558
09:01:14,958 --> 09:01:16,840
we're calling it on a new go routine so
12559
09:01:16,840 --> 09:01:18,120
there's nothing to return here if
12560
09:01:18,120 --> 09:01:19,638
there's an error instead we'll just log
12561
09:01:19,638 --> 09:01:23,040
there was an issue
12562
09:01:31,318 --> 09:01:34,200
and return nothing and next we need to
12563
09:01:34,200 --> 09:01:35,478
actually do the heavy lifting which is
12564
09:01:35,478 --> 09:01:37,318
to go out and scrape the feed so we
12565
09:01:37,318 --> 09:01:39,958
already wrote Our URL to feed function
12566
09:01:39,958 --> 09:01:43,958
let's just use that so URL to feed and
12567
09:01:43,958 --> 09:01:47,200
we'll pass in the feed. URL and we
12568
09:01:47,200 --> 09:01:52,238
should get back an RSS feed and an
12569
09:01:52,238 --> 09:01:56,958
air and if error does not equal
12570
09:02:00,520 --> 09:02:04,600
nil error fetching
12571
09:02:06,958 --> 09:02:09,920
feed and we'll return
12572
09:02:09,920 --> 09:02:13,638
there otherwise we need to do
12573
09:02:13,638 --> 09:02:17,120
some logging so in the future what we'll
12574
09:02:17,120 --> 09:02:19,958
do is instead of iterating over all of
12575
09:02:19,958 --> 09:02:23,718
the um items in the RSS struct that we
12576
09:02:23,718 --> 09:02:25,160
get get back and just printing them to
12577
09:02:25,160 --> 09:02:27,280
the console we'll be saving them into
12578
09:02:27,280 --> 09:02:29,558
the database but for now just so that we
12579
09:02:29,558 --> 09:02:33,200
can test our scrape feed function um
12580
09:02:33,200 --> 09:02:34,840
we're just going to log log all of this
12581
09:02:34,840 --> 09:02:37,238
to the console so we're going to log um
12582
09:02:37,238 --> 09:02:39,280
each individual post or rather that we
12583
09:02:39,280 --> 09:02:42,160
found a post um and then how many posts
12584
09:02:42,160 --> 09:02:45,360
we found the last thing we need to do is
12585
09:02:45,360 --> 09:02:47,638
go hook up this start scraping function
12586
09:02:47,638 --> 09:02:49,840
to our main function so that it actually
12587
09:02:49,840 --> 09:02:52,798
starts okay so start scraping takes
12588
09:02:52,798 --> 09:02:54,280
database concurrency actually I'll just
12589
09:02:54,280 --> 09:02:56,558
open this uh my screen's too small to be
12590
09:02:56,558 --> 09:02:59,600
working in two tabs at the same time
12591
09:02:59,600 --> 09:03:01,600
okay um we're going to need to call it
12592
09:03:01,600 --> 09:03:04,440
before listen and serve because remember
12593
09:03:04,440 --> 09:03:06,680
this is where our server kind of blocks
12594
09:03:06,680 --> 09:03:09,040
and waits forever for incoming requests
12595
09:03:09,040 --> 09:03:10,798
so we should probably call it I don't
12596
09:03:10,798 --> 09:03:12,840
know
12597
09:03:12,840 --> 09:03:16,160
right here seems like a good
12598
09:03:16,160 --> 09:03:19,760
spot so um it's just it's just a
12599
09:03:19,760 --> 09:03:21,760
function right yeah it's not a method
12600
09:03:21,760 --> 09:03:23,478
takes database concurrency and time
12601
09:03:23,478 --> 09:03:27,478
between request okay so we go go start
12602
09:03:27,478 --> 09:03:28,840
scraping remember we want to call it on
12603
09:03:28,840 --> 09:03:31,120
a new go routine so it doesn't interrupt
12604
09:03:31,120 --> 09:03:33,558
uh this main flow because remember start
12605
09:03:33,558 --> 09:03:35,360
scraping is never going to return it's a
12606
09:03:35,360 --> 09:03:37,478
long running function uh this is an
12607
09:03:37,478 --> 09:03:41,160
infinite for Loop okay it needs a
12608
09:03:41,160 --> 09:03:42,200
database connection so we'll actually
12609
09:03:42,200 --> 09:03:44,638
need to save this
12610
09:03:44,638 --> 09:03:48,600
in a new variable so that we can use it
12611
09:03:48,600 --> 09:03:50,280
in the API config and in the start
12612
09:03:50,280 --> 09:03:52,000
scraping
12613
09:03:52,000 --> 09:03:55,878
function next we need the currency um
12614
09:03:55,878 --> 09:03:58,238
let's just start with 10 seems good and
12615
09:03:58,238 --> 09:04:00,000
then time between requests let's do
12616
09:04:00,000 --> 09:04:02,398
time.
12617
09:04:02,398 --> 09:04:05,680
minute perfect I went ahead and added a
12618
09:04:05,680 --> 09:04:07,558
second RSS feed so let's go ahead and
12619
09:04:07,558 --> 09:04:10,040
check the database and see what feeds we
12620
09:04:10,040 --> 09:04:13,040
have currently so I've got Lane's blog
12621
09:04:13,040 --> 09:04:15,000
and the boot Dev blog so there's two now
12622
09:04:15,000 --> 09:04:16,760
remember we were setting a concurrency
12623
09:04:16,760 --> 09:04:19,680
of 10 so we should definitely be able to
12624
09:04:19,680 --> 09:04:21,638
fetch both of these blogs at the same
12625
09:04:21,638 --> 09:04:24,558
time on the first iteration of that Loop
12626
09:04:24,558 --> 09:04:26,280
if we say deployed this production and
12627
09:04:26,280 --> 09:04:28,318
allowed users to start creating feeds
12628
09:04:28,318 --> 09:04:31,360
maybe we'd get up to 100 200 400
12629
09:04:31,360 --> 09:04:32,878
different feeds in here then we'd only
12630
09:04:32,878 --> 09:04:35,000
be fetching 10 at a time right just so
12631
09:04:35,000 --> 09:04:36,680
we understand how that mechanism works
12632
09:04:36,680 --> 09:04:38,000
but for now this should be good enough
12633
09:04:38,000 --> 09:04:40,360
to test I'm going to update our logs
12634
09:04:40,360 --> 09:04:42,958
just a bit um so that we can see which
12635
09:04:42,958 --> 09:04:45,680
blog each post is from so found post
12636
09:04:45,680 --> 09:04:47,200
item.
12637
09:04:47,200 --> 09:04:49,638
tile on
12638
09:04:49,638 --> 09:04:52,958
feed feed. name okay let's go ahead and
12639
09:04:52,958 --> 09:04:55,638
run that
12640
09:05:01,760 --> 09:05:03,638
bound post the property sub pointers in
12641
09:05:03,638 --> 09:05:07,360
go on feed boot Dev blog perfect we kind
12642
09:05:07,360 --> 09:05:09,318
of scroll up we should be able to see
12643
09:05:09,318 --> 09:05:12,718
some the boot Dev Blog has way more blog
12644
09:05:12,718 --> 09:05:16,040
posts than my personal blog here it is
12645
09:05:16,040 --> 09:05:18,360
here's some Lane's blog stuff okay so
12646
09:05:18,360 --> 09:05:19,958
that looks like it's working we should
12647
09:05:19,958 --> 09:05:21,558
be able to move on to the next step now
12648
09:05:21,558 --> 09:05:24,238
where we'll actually save these blog
12649
09:05:24,238 --> 09:05:26,760
posts into the database rather than just
12650
09:05:26,760 --> 09:05:29,120
logging the titles to the console we're
12651
09:05:29,120 --> 09:05:31,040
going to need a new table in our
12652
09:05:31,040 --> 09:05:33,520
database so let's start there we'll call
12653
09:05:33,520 --> 09:05:34,360
it
12654
09:05:34,360 --> 09:05:37,878
posts so the purpose of this table is to
12655
09:05:37,878 --> 09:05:39,238
store all of the posts that we are
12656
09:05:39,238 --> 09:05:42,318
fetching from all of the different uh
12657
09:05:42,318 --> 09:05:45,558
from all of the different RSS feeds okay
12658
09:05:45,558 --> 09:05:47,120
um what am I doing this is this is
12659
09:05:47,120 --> 09:05:49,080
queries we need to start with a
12660
09:05:49,080 --> 09:05:52,160
migration so let's grab this we'll make
12661
09:05:52,160 --> 09:05:55,318
it 006
12662
09:05:55,638 --> 09:05:57,958
posts.
12663
09:05:57,958 --> 09:06:00,760
SQL all right Goose up is going to be
12664
09:06:00,760 --> 09:06:02,520
create table
12665
09:06:02,520 --> 09:06:06,360
posts what goes in a posts table um we
12666
09:06:06,360 --> 09:06:08,398
are going to need an ID created at an
12667
09:06:08,398 --> 09:06:10,078
updated at that pretty much never
12668
09:06:10,078 --> 09:06:13,000
changes um what else does a post have
12669
09:06:13,000 --> 09:06:15,680
well it has a
12670
09:06:16,078 --> 09:06:17,918
title
12671
09:06:17,918 --> 09:06:21,398
title um is that text. null that makes
12672
09:06:21,398 --> 09:06:24,438
sense uh posts also typically have a
12673
09:06:24,438 --> 09:06:26,558
description text um I'm going to allow
12674
09:06:26,558 --> 09:06:28,000
that one to be nullable I think it's
12675
09:06:28,000 --> 09:06:29,960
okay if a post is missing its
12676
09:06:29,960 --> 09:06:32,918
description posts also typically have a
12677
09:06:32,918 --> 09:06:37,398
published at date so published at is a
12678
09:06:37,398 --> 09:06:39,398
timestamp um should we allow that one to
12679
09:06:39,398 --> 09:06:40,320
be
12680
09:06:40,320 --> 09:06:43,558
nullable no no let's make that not
12681
09:06:43,558 --> 09:06:47,398
null what else does a post have it has a
12682
09:06:47,398 --> 09:06:52,078
URL a URL should be not null for
12683
09:06:52,078 --> 09:06:54,398
sure um I'm also going to say that it
12684
09:06:54,398 --> 09:06:55,598
should be
12685
09:06:55,598 --> 09:06:57,200
unique
12686
09:06:57,200 --> 09:06:59,680
unique I don't think we ever want to
12687
09:06:59,680 --> 09:07:03,718
store the same Post in the database
12688
09:07:03,718 --> 09:07:06,520
twice there's no point right if we have
12689
09:07:06,520 --> 09:07:08,598
a post I don't see why we would need it
12690
09:07:08,598 --> 09:07:10,078
a second time so let's let's go ahead
12691
09:07:10,078 --> 09:07:12,680
and make that one unique and then lastly
12692
09:07:12,680 --> 09:07:15,398
let's just put in a feed
12693
09:07:15,398 --> 09:07:18,320
ID and the feed ID is going to be a uu
12694
09:07:18,320 --> 09:07:21,480
ID that
12695
09:07:21,480 --> 09:07:24,160
uh we're gonna want it to be a reference
12696
09:07:24,160 --> 09:07:25,640
so
12697
09:07:25,640 --> 09:07:29,122
references um feeds
12698
09:07:29,122 --> 09:07:32,960
ID right and that's going to
12699
09:07:32,960 --> 09:07:35,680
be does that need to be unique it
12700
09:07:35,680 --> 09:07:36,878
doesn't need to be unique but it should
12701
09:07:36,878 --> 09:07:39,480
be not null we should always have the
12702
09:07:39,480 --> 09:07:43,800
feed ID of a post and let's here put on
12703
09:07:43,800 --> 09:07:46,238
delete Cascade if we delete a feed we'll
12704
09:07:46,238 --> 09:07:48,078
Cascade and delete all of its posts and
12705
09:07:48,078 --> 09:07:50,438
I forgot to put the type here so URL
12706
09:07:50,438 --> 09:07:53,238
text. nil unique okay that looks good to
12707
09:07:53,238 --> 09:07:55,480
me let's go ahead and run our migration
12708
09:07:55,480 --> 09:07:58,718
so it's going to be uh we need to CD
12709
09:07:58,718 --> 09:08:01,000
into SQL
12710
09:08:01,000 --> 09:08:06,078
schema and run Goose
12711
09:08:06,078 --> 09:08:10,238
postgress we'll need this connection
12712
09:08:11,878 --> 09:08:14,278
string
12713
09:08:14,278 --> 09:08:17,480
up perfect next we'll need a couple of
12714
09:08:17,480 --> 09:08:19,598
queries to interact with this table uh
12715
09:08:19,598 --> 09:08:21,160
the first one's going to be just a way
12716
09:08:21,160 --> 09:08:24,160
to create a post so let's do posts
12717
09:08:24,160 --> 09:08:25,438
and we'll
12718
09:08:25,438 --> 09:08:26,960
do
12719
09:08:26,960 --> 09:08:28,520
create
12720
09:08:28,520 --> 09:08:33,598
oops create post return one thing and
12721
09:08:33,598 --> 09:08:35,598
we'll just kind of be inserting a bunch
12722
09:08:35,598 --> 09:08:37,480
of stuff I think let's take a look at
12723
09:08:37,480 --> 09:08:39,200
the post table so we've got ID created
12724
09:08:39,200 --> 09:08:41,718
at update at let me just grab this so I
12725
09:08:41,718 --> 09:08:44,238
don't forget
12726
09:08:47,480 --> 09:08:51,640
it okay so insert into
12727
09:08:51,640 --> 09:08:54,520
posts ID created updated
12728
09:08:54,520 --> 09:08:57,438
at we also have we have a lot of stuff
12729
09:08:57,438 --> 09:08:58,960
so I'm actually going to start spacing
12730
09:08:58,960 --> 09:09:00,238
this out a little
12731
09:09:00,238 --> 09:09:05,840
bit cre at update at it's going to be a
12732
09:09:06,360 --> 09:09:10,800
title and a
12733
09:09:14,238 --> 09:09:16,680
description publish
12734
09:09:16,680 --> 09:09:18,718
that
12735
09:09:18,718 --> 09:09:23,438
URL and a feed ID
12736
09:09:23,558 --> 09:09:28,078
okay and the values 1 2 3 4 how many do
12737
09:09:28,078 --> 09:09:31,160
we got just
12738
09:09:31,160 --> 09:09:33,040
eight
12739
09:09:33,040 --> 09:09:36,598
five 6
12740
09:09:36,598 --> 09:09:40,480
7 eight returning
12741
09:09:40,480 --> 09:09:42,878
star straightforward right insert into
12742
09:09:42,878 --> 09:09:47,078
posts all of these fields no fancy logic
12743
09:09:47,078 --> 09:09:50,360
that should be good okay let's run sqlc
12744
09:09:50,360 --> 09:09:53,520
generate to add that function to our
12745
09:09:53,520 --> 09:09:55,878
internal package and then we just need
12746
09:09:55,878 --> 09:09:58,960
to go use it so down in the scraper now
12747
09:09:58,960 --> 09:10:00,960
instead of just logging all of these
12748
09:10:00,960 --> 09:10:03,480
posts to the console let's save them to
12749
09:10:03,480 --> 09:10:05,960
the database um I'm going to leave this
12750
09:10:05,960 --> 09:10:08,840
log message it says feed blank collected
12751
09:10:08,840 --> 09:10:11,398
blank posts found so that'll just log
12752
09:10:11,398 --> 09:10:12,718
all of the different feeds we're
12753
09:10:12,718 --> 09:10:14,278
collecting but each individual post I
12754
09:10:14,278 --> 09:10:16,918
think it's wasteful and kind of busy to
12755
09:10:16,918 --> 09:10:18,320
log everything so we're not going to do
12756
09:10:18,320 --> 09:10:22,238
that instead we'll just call db. create
12757
09:10:22,238 --> 09:10:25,238
post context.
12758
09:10:25,238 --> 09:10:28,200
background and what does it take create
12759
09:10:28,200 --> 09:10:30,718
post prams database. create post prams
12760
09:10:30,718 --> 09:10:33,480
okay cool I kind of like how
12761
09:10:33,480 --> 09:10:38,000
sqlc breaks down the parameters into um
12762
09:10:38,000 --> 09:10:40,040
into a struct makes it pretty simple to
12763
09:10:40,040 --> 09:10:43,918
work with Okay um we've got an ID
12764
09:10:43,918 --> 09:10:46,438
created at updated at okay um ID is just
12765
09:10:46,438 --> 09:10:50,558
going to be a new ID
12766
09:10:53,640 --> 09:10:55,122
created at updated at that'll just be
12767
09:10:55,122 --> 09:10:57,078
time.
12768
09:10:57,078 --> 09:11:00,078
now
12769
09:11:05,598 --> 09:11:11,718
UTC what's next title description
12770
09:11:14,238 --> 09:11:17,200
tile item.
12771
09:11:17,200 --> 09:11:20,278
tile I just realized I just realized now
12772
09:11:20,278 --> 09:11:22,480
that I'm not putting the field names
12773
09:11:22,480 --> 09:11:25,238
it's kind of
12774
09:11:27,122 --> 09:11:31,398
embarrassing okay title
12775
09:11:33,800 --> 09:11:35,480
description do they not have a
12776
09:11:35,480 --> 09:11:38,438
description what does an item
12777
09:11:38,438 --> 09:11:42,758
have let's take a look at an item items
12778
09:11:42,758 --> 09:11:45,320
have title link description yeah it does
12779
09:11:45,320 --> 09:11:47,558
have a description what am I messing up
12780
09:11:47,558 --> 09:11:49,800
here can I use item. description
12781
09:11:49,800 --> 09:11:52,122
variable of type string as SQL n string
12782
09:11:52,122 --> 09:11:53,758
ah right okay
12783
09:11:53,758 --> 09:11:56,960
so we need to do SQL do null string a
12784
09:11:56,960 --> 09:11:58,800
null string has the string itself and
12785
09:11:58,800 --> 09:12:01,000
whether or not it's valid so we just uh
12786
09:12:01,000 --> 09:12:03,398
put in the string and then we say it is
12787
09:12:03,398 --> 09:12:08,160
valid string do valid is a bolean
12788
09:12:08,160 --> 09:12:10,558
true although actually this is a problem
12789
09:12:10,558 --> 09:12:13,122
right this is a problem because if item.
12790
09:12:13,122 --> 09:12:14,960
description is blank if it's an empty
12791
09:12:14,960 --> 09:12:16,558
string we're going to be putting in an
12792
09:12:16,558 --> 09:12:19,360
empty string and saying that it's there
12793
09:12:19,360 --> 09:12:22,360
even though it's not so let's not do
12794
09:12:22,360 --> 09:12:25,558
this let's do something a little
12795
09:12:25,558 --> 09:12:27,598
different let's
12796
09:12:27,598 --> 09:12:29,200
go
12797
09:12:29,200 --> 09:12:33,520
description is a new sq.
12798
09:12:35,878 --> 09:12:38,558
nring why is why is that giving me
12799
09:12:38,558 --> 09:12:40,878
trouble oh because because I'm doing it
12800
09:12:40,878 --> 09:12:42,758
within the call to create post do it
12801
09:12:42,758 --> 09:12:45,360
right here okay so we'll create a new
12802
09:12:45,360 --> 09:12:49,000
SQL n string and then we'll
12803
09:12:49,000 --> 09:12:53,438
say if item. description does not equal
12804
09:12:53,438 --> 09:12:57,122
the empty string then we get to set
12805
09:12:57,122 --> 09:13:01,278
description. string equal to item.
12806
09:13:01,278 --> 09:13:04,360
description and description.
12807
09:13:04,360 --> 09:13:06,320
valid equals
12808
09:13:06,320 --> 09:13:08,800
true and then we'll use the description
12809
09:13:08,800 --> 09:13:11,918
here does that make sense so if if the
12810
09:13:11,918 --> 09:13:14,160
item's description is blank then we'll
12811
09:13:14,160 --> 09:13:16,598
set the value to null in the database
12812
09:13:16,598 --> 09:13:20,480
effectively um otherwise we'll create
12813
09:13:20,480 --> 09:13:24,320
the valid uh description entity
12814
09:13:24,320 --> 09:13:27,200
okay next we need a publish
12815
09:13:27,200 --> 09:13:31,122
dat let's see we've got an item. pubdate
12816
09:13:31,122 --> 09:13:32,238
which is a string okay so we're going to
12817
09:13:32,238 --> 09:13:35,398
need to parse that string to parse that
12818
09:13:35,398 --> 09:13:38,598
date there is a time. parse function in
12819
09:13:38,598 --> 09:13:40,558
the standard library and we're going to
12820
09:13:40,558 --> 09:13:43,360
use this RFC 111
12821
09:13:43,360 --> 09:13:46,278
23z layout so this is the layout that
12822
09:13:46,278 --> 09:13:48,360
I'm using on the boot Dev blog and on my
12823
09:13:48,360 --> 09:13:51,278
blog to be more robust and support all
12824
09:13:51,278 --> 09:13:53,878
of the different publishing format for
12825
09:13:53,878 --> 09:13:55,078
all the different blogs that we want to
12826
09:13:55,078 --> 09:13:57,040
scrip we'd probably need to make this
12827
09:13:57,040 --> 09:13:59,878
logic a little bit more robust but for
12828
09:13:59,878 --> 09:14:03,078
now I'm just going to say we're parsing
12829
09:14:03,078 --> 09:14:05,480
it this way if it's not that way I guess
12830
09:14:05,480 --> 09:14:09,078
we take a hike okay um if there's an
12831
09:14:09,078 --> 09:14:12,078
error so if error does not equal
12832
09:14:12,078 --> 09:14:16,918
nil we can say log. print
12833
09:14:18,398 --> 09:14:22,960
line parse date
12834
09:14:24,320 --> 09:14:29,960
sent V with air sent V and we'll pass in
12835
09:14:29,960 --> 09:14:32,078
the actual Pub
12836
09:14:32,078 --> 09:14:34,800
date and an error and that's going to be
12837
09:14:34,800 --> 09:14:35,878
a print
12838
09:14:35,878 --> 09:14:39,598
F oops cool and then if that's an issue
12839
09:14:39,598 --> 09:14:40,960
we'll just continue so if we don't get a
12840
09:14:40,960 --> 09:14:44,040
valid time uh then we'll just we'll just
12841
09:14:44,040 --> 09:14:45,878
log it log and move
12842
09:14:45,878 --> 09:14:50,160
on okay so published at pass in that I
12843
09:14:50,160 --> 09:14:51,800
shouldn't use single name variables like
12844
09:14:51,800 --> 09:14:55,480
this let's do Hub
12845
09:14:56,438 --> 09:15:00,160
at okay what else do we got a URL and a
12846
09:15:00,160 --> 09:15:01,840
feed ID so
12847
09:15:01,840 --> 09:15:05,558
URL is just going to be the item.
12848
09:15:05,558 --> 09:15:07,718
link and feed
12849
09:15:07,718 --> 09:15:11,640
ID do we have access to the feed ID
12850
09:15:11,640 --> 09:15:14,040
here we do we have the feed right
12851
09:15:14,040 --> 09:15:17,238
because we passed in the feed here
12852
09:15:17,238 --> 09:15:20,238
perfect
12853
09:15:21,480 --> 09:15:24,520
b.id now db. cre post does return an
12854
09:15:24,520 --> 09:15:27,878
error so we need to handle that
12855
09:15:27,878 --> 09:15:31,680
error what am I screwing up here oh it
12856
09:15:31,680 --> 09:15:33,960
also Returns the post itself I don't
12857
09:15:33,960 --> 09:15:35,238
think we care about the new post though
12858
09:15:35,238 --> 09:15:36,398
I think all we care about is if it
12859
09:15:36,398 --> 09:15:38,360
failed so if
12860
09:15:38,360 --> 09:15:41,680
error equal
12861
09:15:47,320 --> 09:15:51,238
nil fa to create post with
12862
09:15:51,238 --> 09:15:54,360
error oh okay let's give that a shot
12863
09:15:54,360 --> 09:15:57,122
okay build and
12864
09:15:57,278 --> 09:15:59,680
run now remember we're expecting this
12865
09:15:59,680 --> 09:16:01,680
time to get logs that just say that the
12866
09:16:01,680 --> 09:16:04,520
blogs were collected so 21 posts from
12867
09:16:04,520 --> 09:16:07,398
Lane's blog 321 posts from the boot Dev
12868
09:16:07,398 --> 09:16:09,360
blog were collected I'm going to go
12869
09:16:09,360 --> 09:16:11,360
ahead and kill the server and let's
12870
09:16:11,360 --> 09:16:14,520
check PG admin so now if we select star
12871
09:16:14,520 --> 09:16:15,640
from
12872
09:16:15,640 --> 09:16:18,598
Posts we should see a bunch of stuff in
12873
09:16:18,598 --> 09:16:23,520
here IDs created at titles descriptions
12874
09:16:23,520 --> 09:16:26,360
published at dates awesome this is
12875
09:16:26,360 --> 09:16:27,598
looking
12876
09:16:27,598 --> 09:16:30,078
fantastic we scroll down to see how many
12877
09:16:30,078 --> 09:16:32,520
rows there are 342 that looks right to
12878
09:16:32,520 --> 09:16:35,918
me now I think we have an issue here let
12879
09:16:35,918 --> 09:16:37,680
me show you what I mean if we run this
12880
09:16:37,680 --> 09:16:39,598
again so remember we've scraped both of
12881
09:16:39,598 --> 09:16:42,078
the feeds and pulled in all of the posts
12882
09:16:42,078 --> 09:16:44,480
so if I rerun my server at this
12883
09:16:44,480 --> 09:16:47,640
point yeah we're getting all of these
12884
09:16:47,640 --> 09:16:50,360
issues fail to create post duplicate key
12885
09:16:50,360 --> 09:16:52,438
value violates unique constraint posts
12886
09:16:52,438 --> 09:16:55,200
URL key right now this makes sense we
12887
09:16:55,200 --> 09:16:57,598
didn't want to store duplicate posts in
12888
09:16:57,598 --> 09:16:59,078
our database so we have a unique
12889
09:16:59,078 --> 09:17:01,278
constraint on the post URL which means
12890
09:17:01,278 --> 09:17:04,398
when we go try to recreate the posts it
12891
09:17:04,398 --> 09:17:06,078
fails because we already have the posts
12892
09:17:06,078 --> 09:17:08,878
in our database so let's do a little
12893
09:17:08,878 --> 09:17:11,800
string uh a string detection so that we
12894
09:17:11,800 --> 09:17:14,200
don't log this crap every time this
12895
09:17:14,200 --> 09:17:15,800
happens because this isn't really an
12896
09:17:15,800 --> 09:17:19,278
error this is expected Behavior so um we
12897
09:17:19,278 --> 09:17:21,360
can do something like
12898
09:17:21,360 --> 09:17:24,278
if string do
12899
09:17:24,278 --> 09:17:27,960
contains air.
12900
09:17:28,000 --> 09:17:30,420
error uh duplicate
12901
09:17:30,420 --> 09:17:31,718
[Music]
12902
09:17:31,718 --> 09:17:34,718
duplicate
12903
09:17:36,160 --> 09:17:39,000
e then do we continue what are we doing
12904
09:17:39,000 --> 09:17:42,480
here yeah then we
12905
09:17:42,480 --> 09:17:45,360
continue otherwise we'll log the eror so
12906
09:17:45,360 --> 09:17:47,480
we're only going to log the error if
12907
09:17:47,480 --> 09:17:50,918
it's not a duplicate key error okay so
12908
09:17:50,918 --> 09:17:53,598
let's run that again and make sure we
12909
09:17:53,598 --> 09:17:55,520
don't get those
12910
09:17:55,520 --> 09:17:59,398
errors perfect we have one last feature
12911
09:17:59,398 --> 09:18:01,598
to add to our RSS aggregator we need a
12912
09:18:01,598 --> 09:18:04,040
way for users to be able to get a list
12913
09:18:04,040 --> 09:18:06,598
of all of the newest posts from the
12914
09:18:06,598 --> 09:18:08,758
feeds that they're following so we'll
12915
09:18:08,758 --> 09:18:10,078
need a new
12916
09:18:10,078 --> 09:18:14,078
query uh we can call this
12917
09:18:14,438 --> 09:18:19,238
one get posts for user and it will
12918
09:18:19,238 --> 09:18:21,718
return many posts now let's think about
12919
09:18:21,718 --> 09:18:22,878
this query for a second it's a little
12920
09:18:22,878 --> 09:18:24,238
more complex than the other queries
12921
09:18:24,238 --> 09:18:25,438
we've done and that I think we need to
12922
09:18:25,438 --> 09:18:29,398
do a join so we have our posts
12923
09:18:29,398 --> 09:18:32,122
table right post have IDs created at
12924
09:18:32,122 --> 09:18:33,758
updated at but importantly they have a
12925
09:18:33,758 --> 09:18:37,558
feed ID so we know what feed every Post
12926
09:18:37,558 --> 09:18:39,878
in the database belongs to and we also
12927
09:18:39,878 --> 09:18:43,520
have a feed follows table that tells us
12928
09:18:43,520 --> 09:18:46,278
which feeds an individual user is
12929
09:18:46,278 --> 09:18:49,122
following so if we join those two tables
12930
09:18:49,122 --> 09:18:51,160
together right if we take all of the
12931
09:18:51,160 --> 09:18:53,558
feed follow information kind of join it
12932
09:18:53,558 --> 09:18:55,680
to the posts table then we should be
12933
09:18:55,680 --> 09:18:58,918
able to filter by all of the feeds that
12934
09:18:58,918 --> 09:19:00,960
a user is actually following so what
12935
09:19:00,960 --> 09:19:02,480
does that look
12936
09:19:02,480 --> 09:19:07,878
like you can do select posts. star so
12937
09:19:07,878 --> 09:19:09,640
everything from the post
12938
09:19:09,640 --> 09:19:12,640
table from
12939
09:19:12,640 --> 09:19:14,480
Posts
12940
09:19:14,480 --> 09:19:17,276
join feed
12941
09:19:17,276 --> 09:19:19,596
follows
12942
09:19:19,596 --> 09:19:26,320
on oops on post do feed ID equals feed
12943
09:19:26,320 --> 09:19:30,880
follows. feed ID okay so this adds
12944
09:19:30,880 --> 09:19:32,240
essentially all the feed follow
12945
09:19:32,240 --> 09:19:35,160
information to our like the virtual
12946
09:19:35,160 --> 09:19:37,520
table for this query right we're joining
12947
09:19:37,520 --> 09:19:38,840
those two tables together so now we
12948
09:19:38,840 --> 09:19:41,480
should be able to filter um the way we
12949
09:19:41,480 --> 09:19:44,000
want Okay so we've we've joined them
12950
09:19:44,000 --> 09:19:45,720
together uh
12951
09:19:45,720 --> 09:19:51,436
where posts dot wait posts no where feed
12952
09:19:51,436 --> 09:19:53,240
follows. user
12953
09:19:53,240 --> 09:19:55,276
ID
12954
09:19:55,276 --> 09:19:59,160
equals dollar sign one okay so we join
12955
09:19:59,160 --> 09:20:01,360
the tables and then we filter all the
12956
09:20:01,360 --> 09:20:04,360
posts down or rather the entire table
12957
09:20:04,360 --> 09:20:07,160
down by the specific user ID so all of
12958
09:20:07,160 --> 09:20:09,520
the posts that belong to feeds that the
12959
09:20:09,520 --> 09:20:11,680
user is not following should at this
12960
09:20:11,680 --> 09:20:14,360
step get trimmed
12961
09:20:14,360 --> 09:20:19,080
out then we can order by let's do post.
12962
09:20:19,080 --> 09:20:21,276
published at descending so it give us
12963
09:20:21,276 --> 09:20:24,200
the newest stuff first
12964
09:20:24,200 --> 09:20:26,756
and we'll limmit by a configurable
12965
09:20:26,756 --> 09:20:29,080
amount so dollar sign
12966
09:20:29,080 --> 09:20:32,720
two cool let's go ahead and try to
12967
09:20:32,720 --> 09:20:34,000
generate
12968
09:20:34,000 --> 09:20:37,000
that looks like it worked let's see if
12969
09:20:37,000 --> 09:20:38,520
uh see if when we run the actual
12970
09:20:38,520 --> 09:20:40,640
application it does what we expect let's
12971
09:20:40,640 --> 09:20:43,916
hook that query up to a new endpoint so
12972
09:20:43,916 --> 09:20:46,276
I'm here in the users file that seems
12973
09:20:46,276 --> 09:20:49,520
like a reasonable place we'll do
12974
09:20:49,520 --> 09:20:53,360
Handler get posts for user
12975
09:20:53,360 --> 09:20:55,320
it will be an authenticated endpoint so
12976
09:20:55,320 --> 09:20:58,480
we'll need that that user data um but
12977
09:20:58,480 --> 09:21:01,960
here we're going to call DB dot or sorry
12978
09:21:01,960 --> 09:21:03,400
API
12979
09:21:03,400 --> 09:21:08,400
config DB doget posts for user and then
12980
09:21:08,400 --> 09:21:13,040
we can pass in the request. context and
12981
09:21:13,040 --> 09:21:18,040
user. ID oh we also need I think a
12982
09:21:18,040 --> 09:21:21,276
limit oh get no no no sorry we take we
12983
09:21:21,276 --> 09:21:24,360
take database. get post for user params
12984
09:21:24,360 --> 09:21:25,756
right because we had multiple parameters
12985
09:21:25,756 --> 09:21:27,596
here so we'll need the user's ID and a
12986
09:21:27,596 --> 09:21:31,436
limit the user. ID and for now let's
12987
09:21:31,436 --> 09:21:33,480
just say a limit of 10 and that will
12988
09:21:33,480 --> 09:21:35,800
return to us some posts and potentially
12989
09:21:35,800 --> 09:21:37,560
an
12990
09:21:37,560 --> 09:21:41,320
error if we get an error we'll respond
12991
09:21:41,320 --> 09:21:42,800
with
12992
09:21:42,800 --> 09:21:46,040
it couldn't get
12993
09:21:46,040 --> 09:21:48,120
posts otherwise we need to return the
12994
09:21:48,120 --> 09:21:53,040
post themselves now we should go create
12995
09:21:53,040 --> 09:21:56,320
a special posts model right so that we
12996
09:21:56,320 --> 09:22:00,320
get our our own tag so type post
12997
09:22:00,320 --> 09:22:03,840
struct go mostly copy this
12998
09:22:03,840 --> 09:22:05,640
from our
12999
09:22:05,640 --> 09:22:07,596
internal post
13000
09:22:07,596 --> 09:22:11,880
model wherever it ended up here it
13001
09:22:14,640 --> 09:22:16,840
is
13002
09:22:16,840 --> 09:22:21,720
okay add some Json tags
13003
09:22:29,200 --> 09:22:32,800
goodness typing is
13004
09:22:46,840 --> 09:22:49,436
hard now here's an interesting
13005
09:22:49,436 --> 09:22:53,840
thing this SQL null string um is not
13006
09:22:53,840 --> 09:22:56,160
something that we're going to want to
13007
09:22:56,160 --> 09:22:59,240
use um in this struct because this is a
13008
09:22:59,240 --> 09:23:01,560
struct that Marshalls to Json the null
13009
09:23:01,560 --> 09:23:05,240
string object is a nested struct so if
13010
09:23:05,240 --> 09:23:07,480
we Marshal it directly to Json we would
13011
09:23:07,480 --> 09:23:10,040
actually get description as a Json key
13012
09:23:10,040 --> 09:23:12,160
and then string as a Json key and then
13013
09:23:12,160 --> 09:23:13,960
valid as a Json key so be a little
13014
09:23:13,960 --> 09:23:16,916
nested object there that's pretty bad
13015
09:23:16,916 --> 09:23:19,400
user experience because Json natively
13016
09:23:19,400 --> 09:23:21,680
supports kind of null in the sense that
13017
09:23:21,680 --> 09:23:24,800
you can just omit the the key um or use
13018
09:23:24,800 --> 09:23:28,200
like the actual value null um so what
13019
09:23:28,200 --> 09:23:30,400
we're going to do is instead do a
13020
09:23:30,400 --> 09:23:32,040
pointer to a
13021
09:23:32,040 --> 09:23:35,080
string and the way Json marshalling and
13022
09:23:35,080 --> 09:23:36,680
go works is if you have a pointer to a
13023
09:23:36,680 --> 09:23:39,040
string and it is nil then it will
13024
09:23:39,040 --> 09:23:40,916
Marshal to what you'd expect in Json
13025
09:23:40,916 --> 09:23:42,880
land which is that null
13026
09:23:42,880 --> 09:23:47,240
value okay then publish
13027
09:23:49,080 --> 09:23:53,080
that URL
13028
09:23:53,436 --> 09:23:55,680
and feed
13029
09:23:55,680 --> 09:23:58,480
ID okay did I miss anything let me look
13030
09:23:58,480 --> 09:24:00,000
over this really
13031
09:24:00,000 --> 09:24:02,840
quick that's looking
13032
09:24:02,840 --> 09:24:06,960
good and next we need the conversion so
13033
09:24:06,960 --> 09:24:08,880
we'll
13034
09:24:08,880 --> 09:24:14,680
do database post to post
13035
09:24:44,320 --> 09:24:46,756
now this one gets a little hairy right
13036
09:24:46,756 --> 09:24:48,400
um we probably need to do some logic
13037
09:24:48,400 --> 09:24:53,756
here so we'll say bar description
13038
09:24:53,756 --> 09:24:55,400
pointer to a
13039
09:24:55,400 --> 09:24:58,320
string and then if DB
13040
09:24:58,320 --> 09:25:01,640
post. description.
13041
09:25:01,640 --> 09:25:05,756
valid then we'll set description equal
13042
09:25:05,756 --> 09:25:10,160
to the address of DB post. description.
13043
09:25:10,160 --> 09:25:12,360
string cool then we can just directly
13044
09:25:12,360 --> 09:25:15,720
use the description variable
13045
09:25:15,720 --> 09:25:20,640
there all right published that
13046
09:25:25,200 --> 09:25:29,040
what else we got URL on Feed
13047
09:25:33,360 --> 09:25:36,520
ID okay and last but not least we need a
13048
09:25:36,520 --> 09:25:38,560
way to do it uh do the conversion for an
13049
09:25:38,560 --> 09:25:44,436
entire slice bunk DB or database posts
13050
09:25:44,436 --> 09:25:48,040
to posts
13051
09:25:58,400 --> 09:26:01,120
and the logic will look pretty much
13052
09:26:01,120 --> 09:26:02,596
identical to that but I actually think
13053
09:26:02,596 --> 09:26:04,000
it'll be easier to type it out so we'll
13054
09:26:04,000 --> 09:26:10,640
do uh posts slice post
13055
09:26:25,200 --> 09:26:28,160
it database post
13056
09:26:28,160 --> 09:26:31,840
post the database
13057
09:26:32,960 --> 09:26:34,720
post
13058
09:26:34,720 --> 09:26:37,436
okay there we
13059
09:26:37,436 --> 09:26:41,436
go lot of conversion logic there but now
13060
09:26:41,436 --> 09:26:44,160
we should be good to just respond with
13061
09:26:44,160 --> 09:26:44,960
some
13062
09:26:44,960 --> 09:26:48,000
Json and we can pass
13063
09:26:48,000 --> 09:26:51,880
in those posts as database posts cool
13064
09:26:51,880 --> 09:26:53,840
what am I get in
13065
09:26:53,840 --> 09:26:56,596
here truck literally uses unkeyed Fields
13066
09:26:56,596 --> 09:26:58,436
oh yeah let's not do
13067
09:26:58,436 --> 09:27:01,480
that we want an
13068
09:27:01,480 --> 09:27:05,480
ID and I think it's a
13069
09:27:06,320 --> 09:27:10,720
limit right what am I messing up user
13070
09:27:10,720 --> 09:27:12,680
ID
13071
09:27:12,680 --> 09:27:15,240
perfect okay let's build and run the
13072
09:27:15,240 --> 09:27:17,720
server
13073
09:27:18,916 --> 09:27:21,436
again oh I realize I made a mistake I
13074
09:27:21,436 --> 09:27:22,756
need to actually hook this up to
13075
09:27:22,756 --> 09:27:26,320
something so let's go back into main.go
13076
09:27:26,320 --> 09:27:28,640
we need a new
13077
09:27:28,640 --> 09:27:32,200
endpoint we'll do
13078
09:27:32,200 --> 09:27:36,080
get um I don't know user
13079
09:27:36,080 --> 09:27:38,916
feed now feed's probably a loaded term
13080
09:27:38,916 --> 09:27:40,960
in this uh in this application we should
13081
09:27:40,960 --> 09:27:43,400
say uh let's just do
13082
09:27:43,400 --> 09:27:45,960
posts and it's going to require
13083
09:27:45,960 --> 09:27:50,640
middleware so middleware off and API CFG
13084
09:27:50,640 --> 09:27:52,756
Dot
13085
09:27:52,756 --> 09:27:56,000
Handler get posts for user okay so get
13086
09:27:56,000 --> 09:27:58,436
SL posts it's an authenticated endpoint
13087
09:27:58,436 --> 09:28:02,276
Perfect all right let's rebuild and run
13088
09:28:02,680 --> 09:28:05,120
that
13089
09:28:05,120 --> 09:28:09,000
okay opening up thunder
13090
09:28:09,520 --> 09:28:13,520
client first we need to check well
13091
09:28:13,520 --> 09:28:16,436
actually let's just grab some off
13092
09:28:16,436 --> 09:28:19,320
information so
13093
09:28:19,320 --> 09:28:23,916
um this clearly has some
13094
09:28:23,916 --> 09:28:26,960
moth let's grab that API key create a
13095
09:28:26,960 --> 09:28:27,960
new
13096
09:28:27,960 --> 09:28:33,880
request HTTP col Local
13097
09:28:33,880 --> 09:28:37,360
Host V1
13098
09:28:37,360 --> 09:28:40,756
posts headers close
13099
09:28:40,756 --> 09:28:43,000
that
13100
09:28:43,000 --> 09:28:47,800
authorization API key okay so if I make
13101
09:28:47,800 --> 09:28:49,800
that request I'm getting back no posts
13102
09:28:49,800 --> 09:28:51,040
now we know we have posts in the
13103
09:28:51,040 --> 09:28:53,680
database but my my user that I'm
13104
09:28:53,680 --> 09:28:57,720
currently logged in as is not following
13105
09:28:57,720 --> 09:28:59,560
anything right I'm getting back the
13106
09:28:59,560 --> 09:29:03,436
empty array when I when I check my feed
13107
09:29:03,436 --> 09:29:06,480
follows um but I can check which feeds
13108
09:29:06,480 --> 09:29:09,720
Exist by running this API
13109
09:29:09,720 --> 09:29:12,880
request so let's grab this feed let's
13110
09:29:12,880 --> 09:29:16,080
grab the Wags Lane feed and let's go
13111
09:29:16,080 --> 09:29:18,916
follow that one so we'll post to feed
13112
09:29:18,916 --> 09:29:23,880
follows here this feed ID
13113
09:29:23,880 --> 09:29:25,840
okay so now I should be following let's
13114
09:29:25,840 --> 09:29:27,720
check my feed
13115
09:29:27,720 --> 09:29:30,720
follows great I'm following them so now
13116
09:29:30,720 --> 09:29:33,560
if I go get my
13117
09:29:35,596 --> 09:29:39,360
posts there we go I should just be
13118
09:29:39,360 --> 09:29:40,800
getting
13119
09:29:40,800 --> 09:29:45,276
posts from the Wags lane. Dead
13120
09:29:45,276 --> 09:29:49,400
Block perfect let's try following let's
13121
09:29:49,400 --> 09:29:52,320
try following um
13122
09:29:52,320 --> 09:29:55,240
the other one
13123
09:29:55,240 --> 09:29:59,080
so where is it feed follows no
13124
09:29:59,080 --> 09:30:01,596
feeds let's try following the boot Dev
13125
09:30:01,596 --> 09:30:02,596
blog as
13126
09:30:02,596 --> 09:30:07,560
well so post to feed
13127
09:30:08,400 --> 09:30:12,240
follows send that check my feed follows
13128
09:30:12,240 --> 09:30:15,120
now I'm following both now if I go get
13129
09:30:15,120 --> 09:30:16,160
my
13130
09:30:16,160 --> 09:30:18,480
posts perfect we're seeing stuff from
13131
09:30:18,480 --> 09:30:22,080
the boot Dev blog that's it thank than
13132
09:30:22,080 --> 09:30:24,840
you for sticking with me through all of
13133
09:30:24,840 --> 09:30:27,960
this mess we've created an amazing blog
13134
09:30:27,960 --> 09:30:30,276
aggregator that will actually work
13135
09:30:30,276 --> 09:30:32,800
pretty darn well at scale you could run
13136
09:30:32,800 --> 09:30:35,160
this thing uh you know over a long
13137
09:30:35,160 --> 09:30:37,680
period of time collect millions of blog
13138
09:30:37,680 --> 09:30:41,520
posts and it would do pretty well I hope
13139
09:30:41,520 --> 09:30:43,880
you had a ton of fun with this project I
13140
09:30:43,880 --> 09:30:46,520
do want to remind you that this is a
13141
09:30:46,520 --> 09:30:48,800
server right we've kind of been running
13142
09:30:48,800 --> 09:30:51,000
it stopping it restarting it but at the
13143
09:30:51,000 --> 09:30:53,640
end of the day you can just turn it on
13144
09:30:53,640 --> 09:30:56,560
ADD new feeds and follows and interact
13145
09:30:56,560 --> 09:30:58,720
with it directly and it will once a
13146
09:30:58,720 --> 09:31:01,436
minute go out and collect all of those
13147
09:31:01,436 --> 09:31:03,360
blog posts so you could just keep this
13148
09:31:03,360 --> 09:31:05,720
running on a Raspberry Pi in your house
13149
09:31:05,720 --> 09:31:08,960
um to aggregate you know blog posts
13150
09:31:08,960 --> 09:31:11,640
podcasts all that kind of stuff um I
13151
09:31:11,640 --> 09:31:13,160
will point out that we have done a bit
13152
09:31:13,160 --> 09:31:16,120
of happy path programming so happy path
13153
09:31:16,120 --> 09:31:17,520
programming is when you're not
13154
09:31:17,520 --> 09:31:19,880
necessarily handling every Edge case out
13155
09:31:19,880 --> 09:31:22,120
there you're you're handling kind of you
13156
09:31:22,120 --> 09:31:23,916
the thing that you expect to happen most
13157
09:31:23,916 --> 09:31:26,640
of the time so for example um we only
13158
09:31:26,640 --> 09:31:29,200
had one type of date parsing for the
13159
09:31:29,200 --> 09:31:32,400
published at dates in our RSS feeds but
13160
09:31:32,400 --> 09:31:34,160
maybe there are RSS feeds out there that
13161
09:31:34,160 --> 09:31:36,360
use a different date format and we'll
13162
09:31:36,360 --> 09:31:38,800
fail to parse them um so one way that
13163
09:31:38,800 --> 09:31:40,436
you could extend this project would be
13164
09:31:40,436 --> 09:31:43,520
to just add a ton of new RSS feeds and
13165
09:31:43,520 --> 09:31:45,596
make sure that you deal with the issues
13166
09:31:45,596 --> 09:31:47,560
as they come up make sure you improve
13167
09:31:47,560 --> 09:31:49,360
the logging so that you can see the
13168
09:31:49,360 --> 09:31:51,680
issues when they come up anyways I hope
13169
09:31:51,680 --> 09:31:53,720
you had a ton of fun with this project
13170
09:31:53,720 --> 09:31:55,840
and that you learned something I just
13171
09:31:55,840 --> 09:31:57,596
want to remind you that we do have an
13172
09:31:57,596 --> 09:32:00,436
entire backend learning path over on
13173
09:32:00,436 --> 09:32:03,276
boot. in Goan so if you liked this
13174
09:32:03,276 --> 09:32:04,880
project if you liked this course and are
13175
09:32:04,880 --> 09:32:07,276
looking for some more content definitely
13176
09:32:07,276 --> 09:32:10,080
go check out boot. we also have
13177
09:32:10,080 --> 09:32:11,276
published a lot of different ways that
13178
09:32:11,276 --> 09:32:13,276
you could potentially extend this
13179
09:32:13,276 --> 09:32:15,560
project to make it cooler for example
13180
09:32:15,560 --> 09:32:17,800
maybe you add a front end or a command
13181
09:32:17,800 --> 09:32:19,520
line application that interacts directly
13182
09:32:19,520 --> 09:32:20,880
with the API so that you don't need to
13183
09:32:20,880 --> 09:32:23,520
use manual client like thunder client
13184
09:32:23,520 --> 09:32:25,480
every time that you want to interact
13185
09:32:25,480 --> 09:32:27,916
with your posts and then I also just
13186
09:32:27,916 --> 09:32:29,916
want to remind you before I go that you
13187
09:32:29,916 --> 09:32:33,520
can find me on Twitter at Wags lane or
13188
09:32:33,520 --> 09:32:36,520
on YouTube at boot. definitely go
13189
09:32:36,520 --> 09:32:38,840
subscribe to our YouTube channel as well
13190
09:32:38,840 --> 09:32:40,520
thank you again to free code camp for
13191
09:32:40,520 --> 09:32:42,880
allowing us to publish this course and
13192
09:32:42,880 --> 09:32:45,040
this project walk through I hope you
13193
09:32:45,040 --> 09:32:46,520
enjoyed it and I'll see you in the next
13194
09:32:46,520 --> 09:32:48,960
one947227
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.