#10 - Dart Variables and the differences between Late, Var, Dynamic, Final & Const

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey what is going on everyone i'm wicked welcome back to my dart from novice to expert complete course in this tutorial we're going to start a long tour of dart language with all of its quirks and features we'll begin by having a quick recap of everything we learned so far then we'll move over to checking out everything about dart variables and the difference between var dynamic final and const keywords so without further ado let's get right into it beforehand though i want to send a token of appreciation to everyone supporting me as official youtube members especially to diana and michael aka aza on discord if you want to become a member all you have to do is to click the join button right next to my channel and pick your desired membership having that said let's continue with our tutorial as i said before diving into the tour of dart language we must do a quick recap of everything we learned so far in order to refresh our mind for the huge chapter that's going to come up next one thing to be noted is that this language tour will have its base on a no safety dart environment everything you're about to hear and see is based upon that so over the last nine tutorials we learned that dart is an object-oriented programming language meaning that mostly everything in dart is a class and objects are instances of these classes numbers functions and even null are objects as an example take a look and observe that each of these types are actually classes behind the scenes no matter what it is integer string list object null everything has its origins and implementations in a class as any other programming language dart comes with variables and everything you can place inside a variable is an object which is actually an instance of a class as an example if we take a look at this line of code you must know that 5 is actually an object instantiated from the integer class it's pretty much like writing int a equals int with a value of 5 dart is a strongly typed language meaning that everything has a type however explicitly annotating it is optional because dart can infer the type by using the var keyword at compile time and by using the dynamic keyword at runtime as an example if we write in var a equals 5 then variable a is going to be of type integer and we know that immediately after the assignment however if we type in dynamic b equals 5 then variable b is going to be of type dynamic and only at runtime the type of b will be set to integer as a result of this dynamic can be used to postpone type checking until runtime therefore it is really helpful to use it when you want to explicitly say that any type is allowed for a variable we'll talk about the differences between dynamic and var later on this tutorial dart is a sound type system meaning that it can never evaluate into an unknown state under the hood everything is clearly defined before the execution process and since we're in a no safety environment variables can't contain no unless you specifically say they can a variable can be nullable by placing a question mark symbol at the end of its type just like this if you strongly believe that an expression will never evaluate to no but the dart analyzer does not agree with you you can add the exclamation mark symbol to tell him that it won't be no and throw an exception if it is as an example a variable of type string question mark might be a string or it might be no however if you want to assign it to a non-nullable string you must postpend it with the exclamation mark just like this dart is an ecosystem based on packages every dart project is actually a package nevertheless every package can depend on any other packages and you can decide whether other packages can depend on yours or not packages use libraries in order to share their code one with another the code outside the lib folder of a package is not accessible to anyone and this is pretty much what you should remember that is necessary to know before diving ourselves into the complete tour of dart language either way you can go and rewatch specific tutorials if you forgot something about the things i covered inside of them now think of the road ahead as being a long train journey we're in the flatterly train and the first stop we're going to take on this tour of dart language is at the keyword station now i'm not going to spend a lot of time talking about all these keywords you'll even get to know some of them in great detail during this tutorial and the rest of them during the next tutorials however at the same time you need to know some minor but really important key facts about them ideally on a daily basis you should avoid using these words as identifiers yet you can notice that some of these keywords are marked with a superscript if really necessary you can use those as identifiers a variable identifier is actually the name you give to that variable words with the superscript one are called contextual keywords meaning that they have meaning only in specific places from inside the code take the on keyword for example it is normally used inside a throw catch statement specifying on which type of exception you should do something in response to however the own keyword can be used as an identifier to a variable signaling that a car is perhaps turned on words with a superscript 2 are valid identifiers in most places but they can't be used as a class type names or import prefixes for your quick knowledge import prefixes can be seen in this example we can import something and annotate it into a small prefix so that we can later access it by using that specific prefix words with the superscript 3 are really limited reserved words mostly related to the asynchronous huge advanced topic we'll cover that up later on this course the thing is that you can't use a weight or yield as an identifier in any function body marked with async async star or sync star since they have a ton of meaning in this case all other words in this list are reserved words meaning they can't be used as identifiers under any circumstances having this said it's finally time to talk about dart variables in dart you can mainly find four types of variables top level static instance and local variables and they're all split apart like this depending on where you declare them in your program so first and foremost in dart you can declare a variable that is not linked to any class or object and that can be accessed from anywhere else in your program this is called a top level variable you might also know it from other programming languages as being a global variable on the other hand since everything in dart is mainly an object you'll find yourself most of the time working with variables that are tied to objects and classes these are static and instance variables and you'll often find instance variables being referred to as fields or properties of a class you'll also find local variables which are variables that have a local scope meaning that they can only live and be accessed perhaps in a local context of a method or function having all of this in mind in dart a standard variable declaration looks like this string car equals bmw however it can easily become as complicated as static late final integer equals check temperature but we'll get to that later on so let's talk about the components of the standard one first car is the variable name that is also known as the identifier bmw is known as being the value of the variable and at the same time it must be an object instance of the same type as the variables type in our case bmw is a string object instance that was assigned to the car variable of type string the equal sign is an operator denoting the assignment process string is also called the type of the variable and it can be non-nullable just as it is right now or nullable if we post fix it with a question mark what you need to know is that variables in dart store references to an object therefore the above car variable is just a reference to a string object with a value of bmw that is located on dart's internal memory the assignment operation of a variable to an object denoted by the equal operator is optional however dart does not allow a variable to hold absolutely no value if no assignment operation was done then dart will assign a default value to that variable the default value dart will assign a variable to is null this will work fine with a nullable variable since it can be assigned to null by default however you know that a non-nullable variable cannot hold null therefore a really important rule you need to keep in mind is that non-nullable variables must be initialized before you access or use them notice that i said before you access them and not exactly right at declaration in order to study this subtle difference more in depth let's take a look at the rules on how you should declare a variable whether it's a top level static instance or a local one top level nullable variables can be left unassigned at declaration and will be assigned a value of node if so or you can assign them a declaration with a value of the right base type or with a value of node you can even assign them later on and it doesn't matter if you do it before or after using the variable however take in mind this can result in no exception errors non-nullable variables on the other hand must be declared at declaration with a value of the same type as they cannot hold a default null value if you won't assign it at declaration dart will show an error preventing you to compile the program however another approach here is that you can assign a value to the variable later on only if you're 100 sure it is going to be assigned before it will be accessed you can do that by using the late modifier what this modifier essentially does is permit the variable to hold no value until it gets initialized if you fail to initialize a late variable and you try to use it then a runtime error will occur if you don't know what a static variable is it is well a variable that can be accessed without having to instantiate an object from the class it was placed into so you can simply call them like this as a consequence you can't initialize a static variable in a constructor of a class so the question remains whether you need to assign it at declaration or perhaps later on by using late newable static variables can be left unassigned at declaration and will be assigned a value of null if so or you can assign them a declaration with a value of the right base type or with a value of no you can even assign them later on and it doesn't matter if you do it before or after using the variable however take in mind this can result in null exception errors non-nullable static variables on the other hand must be assigned a declaration with a value of the same type as they cannot hold a default null value if you want to assign it at declaration dart will show you an error preventing you to compile the program you can initialize the static variable later on but necessarily before it is used by using as before the late modifier instance variables compared to static variables exist only within an instance of a class so we must also take into consideration the constructor of the class in our initialization workflow nullable instance variables can be left unassigned at declaration and they will be assigned a value of no or you can assign them a declaration with a value of the right base type or with a value of not or you can assign them in the constructor whether it's formally adds an argument to the constructor into the initialization list or even right inside the constructor body you can even assign them after the constructor and it doesn't matter if you do it before or after using the variable however take in mind this can result as before in null exception errors non-new level instance variables can be assigned at declaration with a value of the same time as they cannot hold a default null value however it is not required to assign them here you can assign them to the constructor whether it's formally as an argument to the constructor or into the initialization list however you can't initialize it into the constructor body so you need to make sure you initialize it before it reaches the constructor body on the other hand you can also initialize the instance variable later on even inside the constructor body but necessarily before it is used by using as always the late modifier local variables are variables having a local scope you can for example declare a local variable into a function and it will only be available inside the scope of that function this makes it much more easier for the dart analyzer to scan if it will be assigned before use nullable local variables can be left unassigned at declaration and will be assigned a value of node or you can assign them at declaration with a value of the right base type or with a value of node you can even assign them later on and it doesn't matter if you do it before or after using the variable however take in mind this can as before result in null exception errors non-nullable local variables can be assigned a declaration with a value of the same type as they cannot hold a default null value however it is not obligatory to assign them here if you won't assign them at declaration it is required to assign them before you use them inside the scope they were declared in not doing so will result in an error and dart won't let you even compile the program as you can see in this scenario since dart can 100 take care of the state of the local variable you don't really need the late modifier for the expected behavior in order to visualize all of these scenarios even better i have created a table on how to correctly declare your variables you can pause the video and see if it makes sense for you for example you can see that nullable fields are optional all the way because they can contain the default null value issued by dart however null can cause null exceptions therefore it's like playing with fire with them in the case of non-nullable fields let's take the top level ones as an example add declaration if you don't plan on using the late modifier it's required to initialize it with a correct value if you want dart will show you an error if you use the late modifier then it's optional to initialize it where it was declared but as you can see it's required to initialize it before using it for instance fields however if you don't plan on using the late modifier it's optional to initialize them at declaration but it is required to do so before the constructor body and not doing so will result in an error if you use the late modifier then you can initialize it whenever you want but it is obligatory to do it before you'll access or use that variable hope it makes a little bit of sense it is not required to learn all of these the dart analyzer will help you and tell what's wrong if you're trying to break any of these rules but it's better to have a general idea on how you can declare a variable in different scenarios we currently saw the late modifier in action when we wanted to assign the value of a variable later on after the declaration however you can also use the late modifier onto a variable and assign it a value right where you declare it in this case the late modifier serves another purpose of lazily initializing a variable for example when you mark a variable as late but also initialize it at its declaration then the initializer runs right after the first time the variable is accessed and used and not when it's been declared this lazy initialization can be handy when the variable might not be needed and initializing it takes a lot of time and performance for example let's say we have a class with a static integer variable retrieving a time consuming calculation of the temperature from a weather sensor we're using this class instantiating it with other fields but we don't actually want to create this variable every time since it's not performance efficient we can fix this by marking it late moving on as i said before in dart type annotations are optional because types can be inferred at compile time by using the var keyword or at runtime by using the dynamic keyword so let's see the difference between them more in depth it's time for a showcase between var and dynamic therefore first and foremost let's create three var fields and assign them to an integer a string and a list of integers as you can see if we hover over the variables we already have the compile time types right after we typed in the declaration let's go ahead and print the runtime type of each variable to double check that they won't change at runtime if we run this file now you'll see that the runtime type is the same as the compile time type so what we can observe from this is that var vi equals 5 is absolutely equal to writing integer vi equals 5. so are the other ones in comparison with var dynamic is more like a standalone type telling the dart analyzer that the actual type will be set at runtime and not before compile time as we're used to with var creating and declaring the same three fields this time marking them as dynamic we can see that if we hover them their actual type is dynamic it's more like saying these variables can be of any type right now however the actual real type will be assigned to them at runtime so let's go ahead and print their runtime type if we run the program again you can notice that the runtime type is the same as with var and a quick note on dynamic is that even though this dynamic field is a list of integers if we try and access an instance method from inside the list class let's say the add method the dart static analyzer won't give you an autocomplete option for it since as far as he's concerned he doesn't know yet the type of the variable it will only be found at runtime so why would we want to use dynamic instead of var well let's see what happens when we try to set the var vi variable to a double value as you can see dart will pop up an error telling us that we can't assign a variable of type int to a double value therefore what we can deduce from this is that if we set a var variable to a value then the type of that variable can't be modified anymore after it has been set on the other hand if you tried the same scenario with dynamic type you can notice that it actually works and at runtime the first type is of type integer then after it got assigned to a double value the type will change right away to double and this is thanks to the runtime being able to switch types in real time but now you might wonder what is going to happen if we declare a var x variable and we won't assign it to anything what will be the type of x as you can see the compile type of the variable is actually set to dynamic by default in this case so this line is actually similar to saying dynamic x therefore an unassigned var variable has the same benefits of being a dynamic variable as a result since it's basically a dynamic variable we can set it to multiple types of values values that's going to denote its type at runtime the real question now is what happens if we just leave the var x unassigned and run the program just as it is we know that an unassigned var x is the same as writing an unassigned dynamic x variable so at runtime if there's been nothing assigned to it what's the type of variable x well the type will be of the default type and that type in dart is as expected the null type but wait that means dynamic type is actually nullable right and yeah that's completely true even though it doesn't have a question mark appended at the end dynamic type is a new level type so it's valid to be of type no so dynamic is really useful when for example you have a list of different kinds of values like integers strings and doubles all you have to do is to set it as being a list of dynamic type so that for each of the values the type is set accordingly that was the showdown between dynamic and var but let's extend this battle by adding another two competitors which are final and const the battle now resumes between dynamic vs var vs final versus const what i can tell you at first is that the order in which i told you these keywords is actually the order from the least restrictive to the most restrictive kind of variables you can declare in dart dynamic being the least restrictive and cost being the most restrictive so we currently know that dynamic can change the type of the variable and the variable can be reassigned later on inside the code with any other value whether it's of the same type or not var can't change the type of the variable unless it's not assigned to anything when declared which actually makes it dynamic but the variable can be reassigned later on inside the code with a value compatible with its declared type well a final variable similarly to var can't change the type of the variable however the variable can't be reassigned to another value later on a const variable can't change the type of the variable and the variable can't be reassigned to another value either so then what's the difference between final and const you might ask this is a really important question so please pay a little bit more attention to it first of all let me get one thing straight cost can not only be used for variables but also for values as well as constructors that will create a constant value or object and speaking about constant values you've been using them without knowing all of this tutorial what do you think happens when you type in integer a equals 5 well variable a isn't a constant variable but it is assigned to a constant integer value it's like writing integer a equals const integer with a value of 5. you notice that even though 5 is a constant value variable a is not so i can reassign it to another integer later on currently variable a is neither final or const even though it's been assigned to a constant value however constant variables are a little bit different what i can do is i can make the variable a constant so that not only the value will be constant but the entire line of code will practically become a constant i can now no longer modify the value of a since the entire variable is literally glued to its constant value a rule to be taking in mind is that denoting a variable to be constant makes the value of it to be constant too however the other way around is not true assigning a constant value to a variable doesn't make the variable become constant on the other hand compared to cast values there is no such thing as final values final variables similarly to constant variables can't be reassigned they only get assigned ones however the slight difference is that final variables don't make the value they're assigned to as being constant by default just like a constant variable will do for example if you have a final list containing 1 2 3 you can actually modify that list by adding removing other elements from it later on in the code and that's because it's not constant by default however since it's still a final variable you can't assign the list to another list for example the thing is that you can actually make the list value as being constant just by adding the cons keyword as we previously saw this way the final list equals constant one two three is actually equally the same as writing cost list equals one two three if you think a little bit dart even warns us that we should use const instead of final for this if we compare the hash codes of these two lists we can actually see they are the same since they point to the same compile time constant lists so from this we can conclude that final was created to mark variables non-reassignable while still being able to hold non-constant values and modify their content later on whereas constant variables must be assigned to constant values which are absolutely immutable by default and if they won't they'll automatically convert them to constant this also applies to an object if it is declared final as long as its fields are not final or cast themselves they can be reassigned however let's see another important fact concentrate on this final list variable here note that if we try to add a value to the list variable the static analyzer doesn't say anything even though we can clearly see it is assigned to a const value is it possible to mutate a cons value no it isn't but the thing is that dart only knows that the final list variable has been assigned to a constant value only at runtime so only if we run the program we'll see that it ends up throwing a runtime error so here's another important difference between final and const variables and that is that final variables will have a value known at runtime whereas constant variables must have a value known at compile time you can't assign a constant variable to a function calculating a sum of two numbers since the result of that function will only be retrieved at runtime instead you should use a final variable to store that another thing to be noted is that if you want to have a const instance variable inside a class you have to declare it as static cost rather than just const so that it can be accessed at compile time without having to instantiate the class at runtime therefore const can be used only for top level static or local variables instance variables are not supported a huge advantage of using both final and const for classes is coming in terms of performance let's say we have this class a containing a list of integer values field which is going to be instantiated into the constructor of the class if we create two classes with the exact same list and print their hash codes we'll notice that even though it seems like they both reference the same object from memory that's not true and two different objects are created and referenced however we previously said that the const keyword can be used as a constructor to generate const values in our case a const object right so what happens if we tell dark to create two constant instances of the a class well it obviously won't let us before the constructor of the a class is not marked const and if we make that const you'll see another error pops out and that is related to our list field not being final so why does our list need to be final well previously we learned that every const variable will make its value constant right well think that the constant variable is actually our class right now right we're actually trying to implement a constant constructor for our class variable right then that means all of its fields also need to be somehow constant and since class fields cannot be constant unless mark static the only choice we have left is to mark them final and let them hold constant values if we check the hash code of our variables now you'll see they match both referencing the same constant object in memory which obviously can bring huge performance increases in the long run i hope you really understood the difference between var dynamic final and cost so if we go back into the keywords table we can mark the ones we discussed today and surprisingly we can notice we actually covered some important ground right from the start it is finally time to end this long tutorial on dart variables i hope you really understood them in depth in the next tutorial we'll move over to the next station on this dart language tour and that is the dart built-in types station as always if you like this tutorial don't forget to smash that like button subscribe to my channel and share the video with all of your friends and colleagues in pursuit of top tier development until next time as always take care wicked is out bye bye
Info
Channel: Flutterly
Views: 2,532
Rating: undefined out of 5
Keywords: dart, dart tutorial, tutorial, dart variables, variables, late, var, dynamic, final, const, final vs const, dart final vs const, dart late, dart var, dart dynamic, dynamic vs var, dart var vs dynamic, dart final, dart const
Id: Efaq4LvS-es
Channel Id: undefined
Length: 32min 4sec (1924 seconds)
Published: Mon Jun 28 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.