{"componentChunkName":"component---src-templates-lesson-post-js","path":"/lesson/const-and-final-variables","result":{"data":{"strapiLesson":{"id":"Lesson_21","author":{"email":"eric@ericwindmill.com","username":"Eric Windmill","twitter":"ericwindmill"},"content":"<div class='post-toc'>\n\nOn this page:\n\n* [const](#const)\n* [final](#final)\n\n</div>\n\n\nIn the previous lesson, we saw how to use `var` to define variables. In place of `var`, you can also use the const and \n final keywords. The two are similar in the fact that they can never be reassigned. When they have their value, that's the value forever. \n \n### const \n\nA `const` variable must be _compile-time constant_. (const is shorthand for \"constant\".) Once const is assigned a value, it can never change. \n\n```dart\nconst name = \"Greg\";\n\n// doesn't work!\nname = \"Sarah\";\n```\n\nThe phrase \"compile-time constant\" is important. It means that there can't be any ambiguity in the value, even before it's used in your code. For example, you cannot assign a `const` variable a value from the return value of a function. It can only be set to values that _always_ resolve to the same value, such as Strings, numbers, arithmetic operation.\n\n```dart\nconst name = \"Greg\"; \nconst age = 25; \nconst screenHeight = 15 + 15; \n\nconst double cost = 5.55;\nconst collectionOfDoubles = [14.55, cost]; // okay because \"cost\" is also a constant double\n\n// not allowed!\n// the compiler can't know this width until the function is called.\n const screenWidth = getScreenWidth();\n``` \n\n### final\n\n`final` is similar to `const`, but it doesn't have to be constant at compile time. It can be assigned to any value, including non-const values, but it cannot change once it has been set.\n\n```dart\nfinal name = \"Greg\";\n\n// doesn't work!\nname = \"Sarah\";\n```\n\n`final` also must be set when the variable is created, unlike `var`. For example:\n\n```dart\n// okay\nvar name;\nname = \"Wallace\";\n\n// doesn't work!\nfinal name;\nname = \"Wallace\";\n```\n\nThe only place that you'd define a final variable and not give it a value straight away is on class properties, which we'll explore later.","updated_at":"Saturday, 18th of July, 2020","slug":"const-and-final-variables","strapiId":21,"title":"const and final variables","tutorial":{"category":"Dart","title":"Dart Fundamentals"}},"strapiTutorial":{"lessons":[{"author":1,"content":"Assigning a value to a variable in Dart is done by using the `=` operator.\n\n```dart\nvar name = \"PJ\"; \n```\n\nDart also supports _compound operators_, which are the equivalent of performing an operation and assignment.\n\n|  Operator | Meaning  |\n|---|---|\n| -= | subtraction assignment  |\n| /= | divisions assigment |\t\n| %= | modulo assignment |\t\n| += | addition assignment |\n| *= | multiplication |\t\n| ~/= | integer division assignment |\n| >>= | bitwise shift right assignment  |\t\n| ^= | bitwise XOR assignment |\n| <<= | bitwise shift left assignment |\t\n| &= | bitwise and assignment |\t\n| &#124;= | bitwise or assignment |\n\nexample:\n```dart\na -= b;\n// above is shorthand for\na = a - b;\n\n// *= example\nvar a = 2; // Assign using =\na *= 3; // Assign and multiply: a = a * 3\nassert(a == 6);\n```\n","created_at":"2020-07-18T17:33:57.739Z","id":23,"slug":"assignment-operators","title":"Assignment Operators","tutorial":2,"updated_at":"2020-07-18T17:34:09.879Z"},{"author":1,"content":"Dart supports three kinds of comments:\n\n```dart\n// Inline comments\n\n/*\nBlocks of comments. It's not convention to use block comments in Dart.\n*/\n\n/// Documentation\n///\n/// This is what you should use to document your classes.\n```\n\nGenerally, documentation comments with three slashes are used for documenting your code. Anything you think will stay in the code forever should use this style of comments. Inline comments are used for brief insights into something on a specific line.\n","created_at":"2020-07-12T16:36:15.220Z","id":12,"slug":"comments","title":"Comments","tutorial":2,"updated_at":"2020-07-18T17:34:09.879Z"},{"author":1,"content":"<div class=\"aside\">\nThe following is an excerpt from the book <a href=\"https://www.manning.com/books/flutter-in-action\">Flutter in Action</a>.\n</div>\n\nDart supports `if`, `else if`, and `else`, as you'd expect. Here's a standard `if` statement:\n\n```dart\n// this checks a single condition, \n// and the \"else\" block provides a fallback\nif (inPortland) {\n  print('Bring an umbrella!');\n} else {\n  print('Check the weather first!');\n}\n\n// using \"else if\" allows you to check for multiple conditions\n// and if they all evaluate to false, fall back\nif (inPortland && isSummer) {\n  print('The weather is amazing!');\n} else if(inPortland && isAnyOtherSeason) {\n  print('Torrential downpour.');\n} else {\n  print ('Check the weather!');\n}\n\n// you can use as many \"else if\" statements as you need to\nif (inPortland && isSummer) {\n  print('The weather is amazing!');\n} else if(inPortland && isSpring) {\n  print('Torrential downpour.');\n} else if(inPortland && isAutumn) {\n  print('Torrential downpour.');\n} else if(inPortland && isWinter) {\n  print('Torrential downpour.');\n} else {\n  print ('Check the weather!');\n}\n```\n\n<div class=\"aside\">\nNote that the `else if` statements execute in the order that they're written. The first one that evaluates to \"true\" is the only code block that is executed.\n</div>\n\nFinally, Dart is sane, and a condition must evaluate to a boolean. There is only one way to say \"true\" (`true`) and one way to say \"false\" (`false`). In some languages, there is a concept of \"truthiness,\" and all values coerce to true or false. In such languages, you can write `if (3) {`, and it works. That is not the case in Dart.","created_at":"2020-07-18T17:37:58.387Z","id":29,"slug":"control-flow-if-else-else-if","title":"Control Flow: if, else, else if","tutorial":2,"updated_at":"2020-07-25T15:20:27.986Z"},{"author":1,"content":"You can repeat expressions in loops using the same keywords as in many languages. There are several kinds of loops in Dart:\n\n* Standard `for`\n* `for-in`\n* `while`\n* `do while`\n\n### for loops\n\nIf you need to know the index, your best bet is the standard `for` loop:\n\n````dart\nfor (var i = 0; i < 5; i++) {\n  print(i);\n}\n\n// prints\n0\n1\n2\n3\n4\n````\n\nIf you don't care about the index, the `for-in` loop is great option. It's easier to read and more concise to write.\n\n````dart\nList<String> pets = ['Nora', 'Wallace', 'Phoebe'];\nfor (var pet in pets) {\n  print(pet);\n}\n\n// prints\n'Nora'\n'Wallace'\n'Phoebe'\n````\n\n### while loops\n\n`while` loops behave as you'd expect. They evaluate the condition _before_ the loop runs -- meaning it may never run at all:\n\n````dart\nwhile(someConditionIsTrue) {\n  // do some things\n}\n````\n\n`do-while` loops, on the other hand, evaluate the condition _after_ the loop runs. So they _always_ execute the code in the block at least once:\n\n```dart\ndo {\n  // do somethings at least once\n} while(someConditionIsTrue);\n```\n\n### break and continue\n\nThese two keywords help you manipulate the flow of the loop. Use `continue` in a loop to immediately jump to the next iteration, and use `break` to break out of the loop completely:\n\n```dart\nfor (var i = 0; i < 55; i++) {\n  if (i == 5) {\n    continue; // jump to next iteration\n  }\n  if (i == 10) {\n    break; // stop loop immediately\n  }\n  print(i);\n}\n\n// prints to the console\n0\n1\n2\n3\n4\n6\n7\n8\n9\n```","created_at":"2020-07-18T17:41:02.235Z","id":32,"slug":"loops-for-and-while","title":"Loops: for and while","tutorial":2,"updated_at":"2020-07-18T17:41:02.244Z"},{"author":1,"content":"The basic building block of information in your Dart program will be variables. Anytime you're\n working with data in an app, you can store that data in variables.  For example, if you're\n  building a chat application, you can use variables to refer to chat messages or a user.\n  \nVariables store references to these _values_.\n  \n## Defining Variables\n\nOne of many ways, and the simplest way, to define a variable in Dart is using the `var` key word. \n\n```dart\nvar message = 'Hello, World';\n```\n\nThis example creates a variable called `message`, and also _initializes_ the variable with a\n String value of `Hello, World`. Now, you can access that value by referring to the `message\n ` variable.\n \n```dart\nvar message = 'Hello, World';\nprint(message);\n\n// => Hello, World\n```\n\n## Inferring the type\n\nDart is a _typed language_. The type of the variable `message` is String. Dart can infer this\n type, so you did't have to explicitly define it as a String. Importantly, this variable must be\n  a String forever. You cannot re-assign the variable as an integer. If you did want to create a\n   variable that's more dynamic, you'd use the `dynamic` keyword. We'll see examples of that in a later lesson.\n   \n```dart\ndynamic message = 'Hello World';\n```\n\nYou can safely re-assign this variable to an integer. \n\n```dart\ndynamic message = 'Hello, World';\nmessage = 8; \n```\n\n*NB*: It's rarely advisable to use `dynamic`. Your code will benefit from being type safe.  \n\n\n\n","created_at":"2020-07-12T16:35:51.910Z","id":11,"slug":"values-and-variables","title":"Values and variables","tutorial":2,"updated_at":"2020-07-18T17:34:09.879Z"},{"author":1,"content":"Functions look familiar in Dart if you're coming from any C-like language. The anatomy of a function is pretty straightforward:\n\n```dart\nString makeGreeting(String name) { \n  return 'Hello, $name';\n}\n```\n\nThe first line in the function is the _signature_. It defines the return type of the function, the function name, and lists all arguments the function requires or accepts. \n\nThe function sig","created_at":"2020-07-18T17:41:34.320Z","id":33,"slug":"anatomy-of-dart-functions","title":"Anatomy of Dart Functions","tutorial":2,"updated_at":"2020-07-18T17:41:34.328Z"},{"author":1,"content":"<div class='aside'>\nThe following is an excerpt from the book <a href=\"https://www.manning.com/books/flutter-in-action\">Flutter in Action</a>.\n</div>\n\n`switch` statements are great when there are many possible conditions for a single value. These statements compare `int`s, `String`s, and compile-time constants using `==`. In other words, you must compare a value to a value of the same type that cannot change at runtime. If that sounds like jargon, here's a simple example:\n\n```dart\nint number = 1;\nswitch(number) {\n  case 0:\n    print('zero!');\n    break; // The switch statement must be told to exit, or it will execute every case.\n  case 1:\n    print('one!');\n    break;\n  case 2:\n    print('two!');\n    break;\n  default:\n    print('choose a different number!');\n}\n```\n\nThat's perfectly valid. The variable `number` could have any number of values: it could be 1, 2, 3, 4, 66, 975, -12, or 55. As long as it's an `int`, its a possible value for `number`. This `switch` statement is simply a more concise way of writing an `if/else` statement.\nHere's an overly complex `if`/`else` block, for which you should prefer a `switch` statement:\n\n```dart\nint number = 1;\nif (number == 0) {\n    print('zero!');\n} else if (number == 1) {\n    print('one!');\n} else if (number == 2) {\n    print('two!');\n} else {\n    print('choose a different number!');\n}\n```\n\nThat's what a `switch` statement does, in a nutshell. It provides a concise way to check for any number of values. It's important, though, to remember that it only works with runtime constants. This is not valid:\n\n```dart \n  int five = 5;\n  switch(five) {\n      case(five < 10):\n      // do things...\n  }\n```\n\n`five < 10` isn't constant at compile time and therefore cannot be used. It could be true or false. You cannot do computation within the case line of a switch statement.\n\n### Exiting a Switch statement\n\nEach case in a `switch` statement should end with a keyword that exits the switch. If you don't, the switch statement will execute multiple blocks of code.\n\n```dart\nswitch(number) {\n  case 1:\n    print(number);\n    break; // without this, the switch statement would execute case 2 also!\n  case 2:\n    print(number + 1)\n    break;\n}\n```\n\nSometimes, it is desirable to execute multiple blocks of code. to In `switch` statements, you can fall through multiple cases by not adding a `break` or `return` statement at the end of a case:\n\n```dart\nintnumber = 1;\nswitch(number) {\n  case -1:\n  case -2:\n  case -3:\n  case -4:\n  case -5:\n    print('negative!');\n    break;\n  case 1:\n  case 2:\n  case 3:\n  case 4:\n  case 5:\n    print('positive!');\n    break;\n  case 0:\n  default:\n    print('zero!');\n    break;\n}\n```\n\nIn this example, if the number is between -5 and -1, the code will print `negative!`.\n\nMost commonly, you'll use `break` or `return`. `break` simply exits out of the switch; it doesn't have any other effect. It doesn't return a value. In Dart, a `return` statement immediately ends the function's execution, and therefore it will break out of a `switch` statement. In addition to those, you can use the `throw` keyword, which throws an error.\n\n### Execute multiple cases with \"continue\"\n\nFinally, you can use a `continue` statement and a label if you want to fall through but still have logic in every case:\n\n```dart \nString animal = 'tiger';\nswitch(animal) {\n  case 'tiger':\n    print(\"it's a tiger\");\n    continue alsoCat;\n  case 'lion':\n    print(\"it's a lion\");\n    continue alsoCat;\n  alsoCat:\n  case 'cat':\n    print(\"it's a cat\");\n    break;\n  // ...\n}\n```\n\nThis `switch` statement will print `it's a tiger` and `it's a cat` to the console.","created_at":"2020-07-18T17:38:28.603Z","id":30,"slug":"switch-statements-and-case","title":"Switch statements and case","tutorial":2,"updated_at":"2020-07-18T17:38:28.611Z"},{"author":1,"content":"Dart also supports a nice shorthand syntax for any function that has only one expression. In other words, is the code inside the function block only one line? Then it's probably a single expression, and you can use this syntax to be concise:\n\n```run-dartpad:theme-dark:run-false\nString makeGreeting(String name) => 'Hello, $name!';\n\nmain() {\n    print(makeGreeting('Wallace'));\n}\n```\n\nFor lack of better term, we'll call this an _arrow function_. Arrow functions implicitly return the result of the expression. `=> expression;` is essentially the same as `{ return expression; }`. There's no need to (and you can't) include the `return` keyword.","created_at":"2020-07-18T17:42:16.738Z","id":34,"slug":"arrow-functions","title":"Arrow functions","tutorial":2,"updated_at":"2020-07-25T15:20:41.491Z"},{"author":1,"content":"Cascade notation is syntactic sugar in Dart that allows you to make a sequence of operations on the same object. You can use the \"double dot\" to call functions on objects and access properties. This \"operator\" is simply used to make your code cleaner and concise. It often saves you from having to create temporary variables.\n\nexample use from the [Dart documentation](https://dart.dev/guides/language/language-tour#cascade-notation-): \n```dart\n// with cascade notation:\nquerySelector('#confirm') // Get an object.\n  ..text = 'Confirm' // Use its members.\n  ..classes.add('important')\n  ..onClick.listen((e) => window.alert('Confirmed!'))\n\n// without cascade notation\nvar button = querySelector('#confirm');\nbutton.text = 'Confirm';\nbutton.classes.add('important');\nbutton.onClick.listen((e) => window.alert('Confirmed!'));\n``` ","created_at":"2020-07-18T17:44:57.393Z","id":37,"slug":"cascade-notation","title":"Cascade notation","tutorial":2,"updated_at":"2020-07-18T17:44:57.401Z"},{"author":1,"content":"Dart functions allow positional parameters, named parameters, and optional positional and named parameters, or a combination of all of them. Positional parameters are the basic parameters, and they're required.\n\n```dart\nvoid debugger(String message, int lineNum) {\n  // ...\n}\n```\n\nTo call that function, you _must_ pass in a `String` and an `int`, in that order:\n\n```dart\ndebugger('A bug!', 55);\n```\n\n### Named parameters\n\nDart supports named parameters. _Named_ means that when you call a function, you attach the argument to a label.\n\nNamed parameters are written a bit differently. When defining the function, wrap any named parameters in curly braces (`{ }`). This line defines a function with named parameters:\n\n```dart\nvoid debugger({String message, int lineNum}) {}\n``` \n\nCalling that function would look like this:\n\n```dart\ndebugger(message: 'A bug!', lineNum: 44);\n```\n\nNamed parameters, by default, are optional. But, using the [meta](https://pub.dev/packages/meta) package, you can annotate them and make them required:\n\n```dart\nimport 'package:meta/meta.dart'\n\nWidget build({@required Widget child}) {\n  //...\n}\n```\n\nThe pattern you see here will become familiar when we start writing Flutter apps. For now, don't worry too much about annotations.\n\n### Positional optional parameters\n\nFinally, you can pass positional parameters that are optional, using `[ ]`:\n\n```dart\nint addSomeNums(int x, int y, [int z]) {\n  int sum = x + y;\n  if (z != null) {\n    sum += z;\n  }\n  return sum;\n}\n```\n\nYou call that function like this:\n\n```dart\naddSomeNums(5, 4); // okay, because the third parameter is optional \naddSomeNums(5, 4, 3); // also okay\n```\n\n### Default parameter values\n\nYou can define default values for parameters with the `=` operator in the function signature. Default parameter values tell the function to use the defined default _only if_ nothing is passed in.\n\n```dart\n// function signature \nint addSomeNums(int x, int y, [int z = 5]) => x + y + z;\n\n// calling that function without passing in the third argument\nint sum = addSomeNums(5, 6);\nassert(sum == 16); // 5 + 6 + 5\n\n// calling that function with passing in the third argument\nint sum2 = addSomeNums(5, 6, 10);\nassert(sum2 == 21); // 5 + 6 + 10\n```\n\nDefault parameter values only work with optional parameters. ","created_at":"2020-07-18T17:43:22.856Z","id":35,"slug":"function-arguments-default-optional-named","title":"Function arguments: default, optional, named","tutorial":2,"updated_at":"2020-07-18T17:43:22.864Z"},{"author":1,"content":"<div class='aside'>\nThe following is an excerpt from the book <a href=\"https://www.manning.com/books/flutter-in-action\">Flutter in Action</a>.\n</div>\n\nNull-aware operators are one of my favorite features in Dart. In any language, having variables and values fly around that are `null` can be problematic. It can crash your program. Programmers often have to write `if (response == null) return` at the top of a function to make asynchronous calls. That's not the worst thing ever, but it's not concise.\n\nNull-aware operators in Dart help resolve this issue. They're operators to say, \"If this object or value is `null`, then forget about it: stop trying to execute this code.\"\n\nThe number-one rule of writing Dart code is to be concise but not pithy. Anytime you can write less code without sacrificing readability, you probably should. The three null-aware operators that Dart provides are `?.`, `??`, and `??=`.\n\n### The ?. operator\n\nSuppose you want to call an API and get some information about a `User`. And maybe you're not sure whether the user information you want to fetch even exists. You can do a standard null check like this:\n\n```dart\nvoid getUserAge(String username) async {\n  final request = new UserRequest(username);\n  final response = await request.get();\n  User user = new User.fromResponse(response);\n  // null check\n  if (user != null) {\n    this.userAge = user.age;\n  }\n  // etc.\n}\n```\n\nThat's fine. It works. But the null-aware operators make it much easier. The following operator basically says, \"Hey, assign `userAge` to `user.age`. But if the `user` object is `null`, that's okay. Just assign `userAge` to `null`, rather than throwing an error\":\n\n```dart\nvoid getUserAge(String username) async {\n  final request = UserRequest(username);\n  final response = await request.get();\n  User user = new User.fromResponse(response);\n\n  // delightfully shorter null check\n  this.userAge = user?.age; \n  // etc.\n}\n```\n\nIf `user` is indeed `null`, then your program will assign `userAge` to `null`, but it won't throw an error, and everything will be fine. If you removed the `?.` operator, it would be an error to call `age` on a `null User` object. Plus, your code is more concise and still readable.\n\n<div class=\"aside\">\nIt's worth pointing out that if any code below the line `this.userAge = user?.age;` relied on `useAge` not being `null`, the result would be an error.\n</div>\n\n### The ?? operator\n\nThe second null-aware operator is perhaps even more useful. Suppose you want the same `User` information, but many fields for the user aren't required in your database. There's no guarantee that there will be an age for that user. Then you can use the double question mark (`??`) to assign a \"fallback\" or default value.\n\nThis operator says, \"Hey program, do this operation with this value or variable. But if that value or variable is `null`, then use this backup value.\" It allows you to assign a default value at any given point in your process, and it's super handy:\n\n```dart\nvoid getUserAge(String username) async {\n  final request = new UserRequest(username);\n  final response = request.get();\n  User user = new User.fromResponse(response);\n  \n  // If user.age is null, defaults to 18\n  this.userAge = user.age ?? 18;  <1>\n  // etc.\n}\n```\n\n\n### The ??= operator\n\nThis last null-safe operator accomplishes a goal pretty similar to the previous one, but the opposite. While writing this, I was thinking about how I rarely use this operator in real life. So I decided to do a little research. And wouldn't you know it? I should be using it. It's great.\n\nThis operator basically says, \"Hey, if this object is `null`, then assign it to this value. If it's not, just return the object as is\":\n\n```dart\nint x = 5\nx ??= 3;\n```\n\nIn the second line, `x` will not be assigned 3, because it already has a value. But like the other null-aware operators, this one seeks to make your code more concise.","created_at":"2020-07-18T17:35:16.943Z","id":25,"slug":"null-aware-operators","title":"Null Aware Operators","tutorial":2,"updated_at":"2020-07-18T17:35:16.953Z"},{"author":1,"content":"The ternary operator is technically that: an operator. But, it's also kind of an `if`/`else` substitute. It's also kind of a `??` alternative, depending on the situation. The ternary expression is used to conditionally assign a value. It's called _ternary_ because it has three portions: the condition, the value if the condition is true, and the value if the condition is false.\n\n```dart\nString alert = isReturningCustomer ? 'Welcome back to our site!' : 'Welcome, please sign up.';\n```\n\nIn the above example `isReturningCustomer` is a boolean. If it is true, the variable called `alert` will be assigned the value \"Welcome back to our site!\". Otherwise, `alert` will be assigned the value \"Welcome, please sign up.\". ","created_at":"2020-07-18T17:40:15.849Z","id":31,"slug":"ternary-conditional-operator","title":"Ternary Conditional operator","tutorial":2,"updated_at":"2020-07-18T17:40:15.858Z"},{"author":1,"content":"Logical operators in Dart as similar to most languages. They can be used to combine or invert boolean expressions.\n\n|  Operator | Meaning  |\n|---|---|\n| &&  | logical AND |\n|  &#124;&#124; | logical OR |\n| !expr  | invert boolean |\n\nexample use:\n\n```dart\nbool isSnowing = true;\nbool isRaining = false;\n\nassert(!isRaining); // true\nassert(isSnowing || isRaining); // true because at least one is true\nassert(isSnowing && !isRaining); // true because both are true\n```","created_at":"2020-07-18T17:34:37.044Z","id":24,"slug":"logical-operators","title":"Logical Operators","tutorial":2,"updated_at":"2020-07-25T15:19:37.735Z"},{"author":1,"content":"You can manipulate the individual bits of numbers in Dart. Usually, you'd use these bitwise and shift operators with integers.\n\n| Operator |\tMeaning |\n|---|---|\n| & |\tAND |\n|  &#124; |\tOR |\n| ^ |\tXOR | \n| ~expr\t| Unary bitwise complement (0s become 1s; 1s become 0s) |\n| <<\t| Shift left | \n| \\>>\t| Shift right|\n\nHere's an example of using bitwise and shift operators:\n\n```dart\nfinal value = 0x22;\nfinal bitmask = 0x0f;\n\nassert((value & bitmask) == 0x02); // AND\nassert((value & ~bitmask) == 0x20); // AND NOT\nassert((value | bitmask) == 0x2f); // OR\nassert((value ^ bitmask) == 0x2d); // XOR\nassert((value << 4) == 0x220); // Shift left\nassert((value >> 4) == 0x02); // Shift right\n```","created_at":"2020-07-18T17:37:15.233Z","id":28,"slug":"bitwise-and-shift-operators","title":"Bitwise and Shift Operators","tutorial":2,"updated_at":"2020-07-18T17:37:15.242Z"},{"author":1,"content":"<div class='post-toc'>\n\nOn this page:\n\n* [const](#const)\n* [final](#final)\n\n</div>\n\n\nIn the previous lesson, we saw how to use `var` to define variables. In place of `var`, you can also use the const and \n final keywords. The two are similar in the fact that they can never be reassigned. When they have their value, that's the value forever. \n \n### const \n\nA `const` variable must be _compile-time constant_. (const is shorthand for \"constant\".) Once const is assigned a value, it can never change. \n\n```dart\nconst name = \"Greg\";\n\n// doesn't work!\nname = \"Sarah\";\n```\n\nThe phrase \"compile-time constant\" is important. It means that there can't be any ambiguity in the value, even before it's used in your code. For example, you cannot assign a `const` variable a value from the return value of a function. It can only be set to values that _always_ resolve to the same value, such as Strings, numbers, arithmetic operation.\n\n```dart\nconst name = \"Greg\"; \nconst age = 25; \nconst screenHeight = 15 + 15; \n\nconst double cost = 5.55;\nconst collectionOfDoubles = [14.55, cost]; // okay because \"cost\" is also a constant double\n\n// not allowed!\n// the compiler can't know this width until the function is called.\n const screenWidth = getScreenWidth();\n``` \n\n### final\n\n`final` is similar to `const`, but it doesn't have to be constant at compile time. It can be assigned to any value, including non-const values, but it cannot change once it has been set.\n\n```dart\nfinal name = \"Greg\";\n\n// doesn't work!\nname = \"Sarah\";\n```\n\n`final` also must be set when the variable is created, unlike `var`. For example:\n\n```dart\n// okay\nvar name;\nname = \"Wallace\";\n\n// doesn't work!\nfinal name;\nname = \"Wallace\";\n```\n\nThe only place that you'd define a final variable and not give it a value straight away is on class properties, which we'll explore later.","created_at":"2020-07-18T17:32:20.744Z","id":21,"slug":"const-and-final-variables","title":"const and final variables","tutorial":2,"updated_at":"2020-07-18T17:34:09.879Z"},{"author":1,"content":"Dart supports all the operators you'd expect from a modern programming language. \n\n### Arithmetic\n\n|  Operator | Meaning  |\n|---|---|\n| + | \tAdd |\n| - | \tSubtract |\n| -expr | \tUnary minus, also known as negation (reverse the sign of the expression) |\n| * | \tMultiply |\n| / | \tDivide |\n| ~/ | \tDivide, returning an integer result |\n| % | \tGet the remainder of an integer division (modulo) |\n| ++var |\tvar = var + 1 (expression value is var + 1) |\n| var++ |\tvar = var + 1 (expression value is var) |\n| --var |\tvar = var – 1 (expression value is var – 1) |\n| var-- |\tvar = var – 1 (expression value is var) |\n\n\nexample use:\n```dart\nassert(2 + 3 == 5);\nassert(2 - 3 == -1);\nassert(2 * 3 == 6);\nassert(5 / 2 == 2.5); // Result is a double\nassert(5 ~/ 2 == 2); // Result is an int\nassert(5 % 2 == 1); // Remainder\n\nassert('5/2 = ${5 ~/ 2} r ${5 % 2}' == '5/2 = 2 r 1');\n\nvar a, b;\n\na = 0;\nb = ++a; // Increment a before b gets its value.\nassert(a == b); // 1 == 1\n\na = 0;\nb = a++; // Increment a AFTER b gets its value.\nassert(a != b); // 1 != 0\n\na = 0;\nb = --a; // Decrement a before b gets its value.\nassert(a == b); // -1 == -1\n\na = 0;\nb = a--; // Decrement a AFTER b gets its value.\nassert(a != b); // -1 != 0\n```\n\n### Comparison\n\n| Operator  | Meaning  |\n|---|---|\n| == |\tEqual |\n| != |\tNot equal |\n| > |\tGreater than |\n| < |\tLess than |\n| >= |\tGreater than or equal to |\n| <= |\tLess than or equal to |\n\n\nexample usage:\n```dart\nassert(2 == 2);\nassert(2 != 3);\nassert(3 > 2);\nassert(2 < 3);\nassert(3 >= 3);\nassert(2 <= 3);\n```","created_at":"2020-07-18T17:33:13.668Z","id":22,"slug":"arithmetic-and-comparison-operators","title":"Arithmetic and Comparison Operators","tutorial":2,"updated_at":"2020-07-18T17:34:09.879Z"},{"author":1,"content":"<div class='aside'>\nThe following is an excerpt from the book <a href=\"https://www.manning.com/books/flutter-in-action\">Flutter in Action</a>.\n</div>\n\nDart is _lexically scoped_. Every code block has access to variables \"above\" it. The scope is defined by the structure of the code, and you can see what variables are in the current scope by following the curly braces outward to the top level:\n\n<!-- TODO: add diagram -->\n\n```dart\nString topLevel = 'Hello';\n\nvoid firstFunction() {\n  String secondLevel = 'Hi';\n  print(topLevel);\n  nestedFunction() {\n    String thirdLevel = 'Howdy';\n    print(topLevel);\n    print(secondLevel);\n    innerNestedFunction() {\n      print(topLevel);\n      print(secondLevel);\n      print(thirdLevel);\n    }\n  }\n  print(thirdLeve);\n}\n\nvoid main() => firstFunction();\n```\n\nThis is a valid function, until the last `print` statement. The third-level variable is defined outside the scope of the nested function, because scope is limited to its own block or the blocks above it. (Again, a block is defined by curly braces.)","created_at":"2020-07-18T17:43:53.132Z","id":36,"slug":"lexical-scope","title":"Lexical Scope","tutorial":2,"updated_at":"2020-07-18T17:43:53.141Z"},{"author":1,"content":"Dart is a typed language, and it's often useful to assert that a value is of a correct type, or _change_ the type of a value to a related type. Typecasting is quite a bit topic, but here we'll discuss the basics. \n\n|  Operator |  Meaning |\n|---|---|\n|is\t | True if the object has the specified type |\n|is! | \tFalse if the object has the specified type |\n|as\t | Typecast (also used to specify library prefixes) |\n\nexample \"is\" use:\n```dart\n// suppose your program has these three subclasses of User\nclass Customer extends User {...}\nclass Employee extends User {...}\nclass Boss extends User {...}\n\n// And suppose there's a variable called 'user',\n// and it could be any of the subclasses of 'User' \n\n// handle a customer\nif (user is Customer) {\n  // do something\n}\n\n// assert that the user is an employee or boss \nif (user is! Customer) {\n  // do something\n}\n```\n\n### Intro to Typecasting\n\nTypecasting can be useful in many ways, but as an intro to using `as`, let's suppose you have a class called `User`, and several subclasses of `User`. Each of these subclasses will have different properties from each other. You can use `as` to access these sub-class specific properties in your code.\n\n```dart\nclass User {}\n\nclass Customer {\n  String address;\n}\n\nclass Employee {\n  DateTime shiftStartTime;\n}\n\n// suppose you have a User object here,\n// but you know in this function you'll always \n// be dealing with the \"employee\" sub-types\n\nclockIn(User user) {\n  // case the user object as it's subtype\n  (user as Employee).shiftStartTime = now;\n}\n\n\n// NB: this is important because if you didn't use 'as'\n// the Dart compiler doesn't know if the user is an Employee or Customer,\n// and can't guarantee that the the `startShiftTime` property exists.\n// example:\nuser.startShiftTime = now; // will this work? who knows! \n``` ","created_at":"2020-07-18T17:36:46.053Z","id":27,"slug":"type-test-operators","title":"Type Test Operators","tutorial":2,"updated_at":"2020-07-18T17:36:46.061Z"}]},"strapiTableOfContents":{"contents":"{\n  \"Dart\": {\n    \"Getting Started with Dart\": [\n      \"About Dart\",\n      \"Install Dart on your machine\",\n      \"Dartpad\",\n      \"Text Editors: Intellij and VSCode\",\n      \"Resources: Documentation and Pub.dev\",\n      \"Hello World\",\n      \"The main function\",\n      \"Print to the console\"\n    ],\n    \"Dart Fundamentals\": [\n      \"Values and variables\",\n      \"Comments\",\n      \"const and final variables\",\n      \"Arithmetic and Comparison Operators\",\n      \"Assignment Operators\",\n      \"Logical Operators\",\n      \"Null Aware Operators\",\n      \"Type Test Operators\",\n      \"Bitwise and Shift Operators\",\n      \"Control Flow: if, else, else if\",\n      \"Switch statements and case\",\n      \"Ternary Conditional operator\",\n      \"Loops: for and while\",\n      \"Anatomy of Dart Functions\",\n      \"Arrow functions\",\n      \"Function arguments: default, optional, named\",\n      \"Lexical Scope\",\n      \"Cascade notation\"\n    ],\n    \"Data Types\": [\n      \"Intro to Dart's Type System\",\n      \"Numbers\",\n      \"Strings\",\n      \"Booleans\",\n      \"dynamic\",\n      \"lists\",\n      \"sets\",\n      \"maps\"\n    ],\n    \"Object-Oriented Programming\": [\n      \"Intro to OOP\",\n      \"Classes\",\n      \"Constructors\",\n      \"Properties and methods\",\n      \"Methods: static, private, etc\",\n      \"Getters and setters\",\n      \"Extending classes (inheritance)\",\n      \"Initializer lists and final properties\",\n      \"Factory methods\",\n      \"Singletons\",\n      \"Abstract classes (and interfaces)\",\n      \"Mixins\",\n      \"Extension methods\"\n    ],\n    \"Iterables, Iterators, and Collections\": [\n      \"What are collections (and iterables)?\",\n      \"Looping: for-in and forEach\",\n      \"Reading elements pt 1: first, last\",\n      \"Adding elements: add and insert (all)\",\n      \"Checking for elements: contains, indexOf, any, every\",\n      \"Removing elements: remove, clear, removeWhere\",\n      \"Filtering elements: where, takeWhile, and skipWhile\",\n      \"Changing elements: map and expand\",\n      \"Deriving values from elements: fold, reduce, join\",\n      \"Type casting collections: cast, as, retype, toSet, toList\",\n      \"Iterators: understanding and creating your own\",\n      \"Iterable-like methods on maps (and putIfAbsent)\"\n    ]\n  },\n  \"Flutter\": {\n    \"Getting started with Flutter\": [\n      \"About Flutter\",\n      \"IDEs and resources\"\n    ],\n    \"Widgets\": [\n      \"Intro to Widgets\",\n      \"Widget types: Stateful and Stateless\",\n      \"StatefulWidget lifecycle\",\n      \"The Widget tree\",\n      \"BuildContext\",\n      \"Inherited Widgets\",\n      \"Thinking in widgets\"\n    ],\n    \"Intro Flutter App\": [\n      \"Intro and Setup\",\n      \"Data Model and HTTP\",\n      \"Build a custom widget\",\n      \"ListView and builder pattern\",\n      \"Gradient Backgrounds\",\n      \"Routing: Add a detail page\",\n      \"Routing 2: Add a form page\",\n      \"User Input\",\n      \"Sliders and Buttons\",\n      \"Snackbars and Dialogs\",\n      \"Built-in Animation: AnimatedCrossFade\",\n      \"Built-in Animation: Hero transition\"\n    ],\n    \"Custom Animation: Progress Indicator\": [\n      \"Intro and Overview\",\n      \"Build the example app boiler-plate\",\n      \"Custom Widget: Peg\",\n      \"Tween and AnimationController classes\",\n      \"Tween by example\",\n      \"Using Tweens and Intervals\",\n      \"Wrap the Pegs in AnimatedWidgets\",\n      \"Bring it all together\"\n    ],\n    \"State Management: Blocs without Libraries\": [\n      \"What are blocs?\",\n      \"Calendar App introduction\",\n      \"Create bloc one\",\n      \"Create a bloc provider\",\n      \"Using StreamBuilders with blocs\",\n      \"Create bloc two: Add/Edit Tasks\",\n      \"Consume the second bloc's streams\",\n      \"Complete source code\"\n    ],\n    \"State Management: Provider\": [\n      \"What is Provider?\",\n      \"The most basic example using Provider\",\n      \"ChangeNotifierProvider\",\n      \"Rebuilding widgets with Consumer\",\n      \"Finer build control with Selector\",\n      \"Future Provider\",\n      \"MultiProvider micro lesson\",\n      \"Stream Provider\",\n      \"Using context extensions for more control\",\n      \"ProxyProvider\",\n      \"Using .value constructors\",\n      \"The final example (A shopping cart app)\",\n      \"For the curious: How is provider implemented\"\n    ],\n    \"Handling Data with Brick: Offline First with Rest\": [\n      \"About Brick and setup\",\n      \"Adding a Repository\",\n      \"Adding a Model\",\n      \"Generating Code\",\n      \"Rendering Models\",\n      \"Adding an Association\"\n    ]\n  }\n}"}},"pageContext":{"slug":"const-and-final-variables","tutorialTitle":"Dart Fundamentals","previous":{"author":1,"content":"You can manipulate the individual bits of numbers in Dart. Usually, you'd use these bitwise and shift operators with integers.\n\n| Operator |\tMeaning |\n|---|---|\n| & |\tAND |\n|  &#124; |\tOR |\n| ^ |\tXOR | \n| ~expr\t| Unary bitwise complement (0s become 1s; 1s become 0s) |\n| <<\t| Shift left | \n| \\>>\t| Shift right|\n\nHere's an example of using bitwise and shift operators:\n\n```dart\nfinal value = 0x22;\nfinal bitmask = 0x0f;\n\nassert((value & bitmask) == 0x02); // AND\nassert((value & ~bitmask) == 0x20); // AND NOT\nassert((value | bitmask) == 0x2f); // OR\nassert((value ^ bitmask) == 0x2d); // XOR\nassert((value << 4) == 0x220); // Shift left\nassert((value >> 4) == 0x02); // Shift right\n```","created_at":"2020-07-18T17:37:15.233Z","id":28,"slug":"bitwise-and-shift-operators","title":"Bitwise and Shift Operators","tutorial":2,"updated_at":"2020-07-18T17:37:15.242Z"},"next":{"author":1,"content":"Dart supports all the operators you'd expect from a modern programming language. \n\n### Arithmetic\n\n|  Operator | Meaning  |\n|---|---|\n| + | \tAdd |\n| - | \tSubtract |\n| -expr | \tUnary minus, also known as negation (reverse the sign of the expression) |\n| * | \tMultiply |\n| / | \tDivide |\n| ~/ | \tDivide, returning an integer result |\n| % | \tGet the remainder of an integer division (modulo) |\n| ++var |\tvar = var + 1 (expression value is var + 1) |\n| var++ |\tvar = var + 1 (expression value is var) |\n| --var |\tvar = var – 1 (expression value is var – 1) |\n| var-- |\tvar = var – 1 (expression value is var) |\n\n\nexample use:\n```dart\nassert(2 + 3 == 5);\nassert(2 - 3 == -1);\nassert(2 * 3 == 6);\nassert(5 / 2 == 2.5); // Result is a double\nassert(5 ~/ 2 == 2); // Result is an int\nassert(5 % 2 == 1); // Remainder\n\nassert('5/2 = ${5 ~/ 2} r ${5 % 2}' == '5/2 = 2 r 1');\n\nvar a, b;\n\na = 0;\nb = ++a; // Increment a before b gets its value.\nassert(a == b); // 1 == 1\n\na = 0;\nb = a++; // Increment a AFTER b gets its value.\nassert(a != b); // 1 != 0\n\na = 0;\nb = --a; // Decrement a before b gets its value.\nassert(a == b); // -1 == -1\n\na = 0;\nb = a--; // Decrement a AFTER b gets its value.\nassert(a != b); // -1 != 0\n```\n\n### Comparison\n\n| Operator  | Meaning  |\n|---|---|\n| == |\tEqual |\n| != |\tNot equal |\n| > |\tGreater than |\n| < |\tLess than |\n| >= |\tGreater than or equal to |\n| <= |\tLess than or equal to |\n\n\nexample usage:\n```dart\nassert(2 == 2);\nassert(2 != 3);\nassert(3 > 2);\nassert(2 < 3);\nassert(3 >= 3);\nassert(2 <= 3);\n```","created_at":"2020-07-18T17:33:13.668Z","id":22,"slug":"arithmetic-and-comparison-operators","title":"Arithmetic and Comparison Operators","tutorial":2,"updated_at":"2020-07-18T17:34:09.879Z"}}},"staticQueryHashes":["2185715291","3564968493","63159454"]}