 Something that comes up quite often is we need to represent a set of discreet values like for example the days of the week There's only seven discreet days of the week that never changes. It's always gonna be the same There's Sunday Monday Tuesday Wednesday Thursday Friday Saturday In some languages, they have data types. You can define called some types or sometimes called enum types as an enumeration types We can define data types that are discreetly made up of these defined values. You just give names There is no such facility though in go So instead what we might do is represent these discreet values as say like strings as we do here Here we're representing the days of the week is just the string Sunday for Sunday Monday for Monday It's a Tuesday Wednesday Thursday Friday Saturday, etc. That's pretty obvious What we might do alternatively is just use arbitrary number values integer values to represent These respective days and so like say zero would be Sunday Monday would be one Tuesday would be two, etc And it wouldn't necessarily really matter what the actual number value is as long as we're consistent when reading and writing our data If we when we use integers to represent days of the week We always make sure that zero represents Sunday as long as we're consistent about that The choice is totally arbitrary just like it's totally arbitrary what? Numbers are used to represent characters in a character set and the advantage here of using in values is that integers are smaller generally than strings even very small strings like these here are well Let's see you have the the address of where the actual string data is stored And then there's an array of bytes that make up the actual character data. So so even fairly small strings Maybe larger than you want if say you're representing a whole bunch of values Like you imagine you have like thousands and millions of these things in which case storing all of these string values Could be inefficient most of the time it probably wouldn't matter So integers are another option and what you'll probably want to do Is define named things that you can use instead of the actual string value or int value because With strings the issue would be you'd probably very often create typos And the thing is the compiler when you have a typo in your string the compiler has no idea The compiler will accept any any string as long as it's a valid string And so you're gonna have a really annoying bug Where you've typed sundae a million times and like a thousand different strings and then there's one that's different Whereas if I define a variable called sundae Which is perhaps just a string value sundae. It seems a little strange a little silly But the thing is because this is a variable if I have a typo in it like if I accidentally type sundae Well, the compiler is probably going to catch that because I probably don't have a variable called sundae, right? I could but most likely I wouldn't So it's generally better to create these variables And then instead of using the values directly in your code to use these variables And this is doubly true if I'm representing these discrete values as int values because The association of one int to the the day of the week is basically arbitrary I mean there's some logic here starting from zero and counting from there But it'd be very very easy to make a mistake if if I had to remember every time I look at my code When I see a number three after remember, oh, that's supposed to represent Wednesday That's something I'm going to get wrong It makes the code harder to read and it's going to be something I can mess up very very easily Whereas if I have an actual defined name Wednesday that I can use in my code And the compiler will probably catch any typo. That's much much better One thing we want to avoid is ever changing these variables We define these variables and they're supposed to have the same value throughout the whole life of the program And it's never supposed to change. It's always supposed to be the same thing So there's actually a language feature that helps us out in that regard Instead of creating variables, we can create what go calls constants Denoted with the word const and so here this is defining a constant sundae of type int Which is the value zero and a constant mondae of type int, which is the value one And unlike variables constants can't be reassigned And in fact you're required to when creating them initialize them with a value And the value you give them has to be a compile time expression That's to be something which the compiler can compute a compile time Like say I can't have a call to foo here to get the value for mondae because it's a const And you at compile time the compiler can't call functions Functions only get called at one time But I can't have something like one plus five. That's a or 56. That is a compile time expression and that would be valid Though there would be no reason to do that in this case So constants are as the name implies constant. They can't be reassigned And as a further convenience because it is quite common to create a bunch of constants like this in succession And sometimes also to create a bunch of variables in succession like here There is a convenience syntax for it where you use var and const But then you put parens and inside you here we're creating a bunch of discrete variables on each line And here with const same thing a bunch of constants on each line So that's just a little syntactical allowance And in fact we can do the same with imports instead of having a bunch of separate import statements You can combine them into one import statement with parens and then putting the things you import on each successive line And the constants which we define actually don't have to have a type Just like number constants like these number little zero one two three four five six as we discussed They don't really have a particular type as far as the compile is concerned They could equally be a uint value or an int value or float 32 value because the The the number little itself doesn't have any type. Well here We're defining a bunch of constants sunday monday tuesday wednesday thursday friday saturday And I didn't specify any type. I didn't say it's an int I didn't say it's a uint or any other kind of integer or float or anything It's just a constant and so here in main Where I have a verbal a which is an int b which is a float 64 and c is a uint 32 I can assign to any one of them I can assign the value sunday because sunday is the constant value zero and zero is a valid int value It's also a valid float 64 value and it's a valid uint 32 values. So the compiler is okay with each one of these As a further convenience because it's really common to follow this pattern where where we declare a bunch of constants And there's from some starting value. You have a bunch of constants with all of the successive values We have a special syntax for that. There's what's called iota And so this is defining a bunch of constants sunday monday tuesday wednesday thursday friday saturday We're defining these constants in this order And notice there's only an equal sign on the first one and then we have a special word iota And what happens here is that uh monday tuesday wednesday thursday friday saturday It's as if there's this equal sign here with iota on each one And what happens here is that iota for the first constant has the value zero For the next one it'll have the value one And then next it'll have the value two and then for wednesday it'll be three for thursday iota 4 etc So if we just write sunday equals iota What's happening is that sunday gets the value zero monday will be one tuesday will be two Wednesday will be three Thursday will be four etc just like we defined up here And when we use iota we can actually use it in a more complicated uh compile time expression So like here we'll need to find sunday. We're saying the expression is two times iota And again iota in each successive constant increases by one its value But it's the same expression for each one. It's two times iota So sunday will be two times zero which is zero monday will be two times one which is two Tuesday will be two times two which is four wednesday will be six Thursday will be eight friday will be ten and saturday will be 12 And in this particular case it doesn't really make sense to define the constants this way There's really no reason not to give them just the successive values zero one two three four five six But there are cases where this comes up and you want to do something a bit more sophisticated than just Having a success of integers and and so you can effectively arrange it With a complex expression like say for whatever reason imagine they instead of having the constants start at zero You want to start counting from five? So if we just take five and add iota then effectively then that would be Five plus zero which is five monday would be five plus one which is six Tuesday would be five plus Two which is seven etc. And so we would effectively have the the constants to find in order starting from five And understand that when we use iota We can actually give the constants a type and when we do so we only specify the type for the first constant and then the The successive constants all implicitly are the same type So here sunday monday tuesday wednesday thursday friday saturday they're actually all are ins Rather than just untyped constants And so here oops, this is not correct So the first assignment will be okay, but then this is going to be compile error And same thing down here. This is going to be compile error because sunday is not an untyped constant. It's actually an int Now we would have to cast in this case. We'd have to say float 64 From sunday and Same here uint 32 from sunday and then it would be okay to the compiler But otherwise if we just leave it like that that's a compilation error Lastly with constants, I mentioned in passing that String literals are actually also untyped constants like number literals are not necessarily any particular number type Strings are actually not necessarily strings If we define some other type, which is a name type that's defined to be a string Then a string literal would validly both be a string and a my string So say here if I create a variable s, which is a my string. I can assign to it um A string literal and because the string literal isn't strictly a string. It's an untyped constant It's valid to assign to s. So that's what's going on there And so here we're defining two constants One of which is a string constant this one called typed and it has this value I'm a typed constant, but then we also define this untyped constant called untyped Where it's the string value, but it's considered to be untyped and so So having to find the variable s of type my string We get a compilation error if we try to assign typed to it because as far as the compiler is concerned typed here Is not just any kind of string. It's specifically the built-in string type It's not an unnamed constant. Whereas if I assign untyped to s that's okay because This constant doesn't have any particular type and so it's equally a built-in string and it's also a my string Whereas if I want to take the type string and assign it to s I would have to cast it As I do here and and now it's acceptable the compiler will accept that okay. This is a valid string Again be clear. There's no actual data conversion being done here It's just the same data is just we're satisfying the compiler that in this case What's defined here to be specifically a built-in string type We want to use it as a my string and so that's why we have to have the cast here