{"id":4463,"date":"2025-01-03T01:19:33","date_gmt":"2025-01-03T01:19:33","guid":{"rendered":"https:\/\/www.qworqs.com\/blog\/?p=4463"},"modified":"2025-01-04T01:16:38","modified_gmt":"2025-01-04T01:16:38","slug":"my-dart-notes","status":"publish","type":"post","link":"https:\/\/www.voodoo.business\/blog\/2025\/01\/03\/my-dart-notes\/","title":{"rendered":"My Dart Notes"},"content":{"rendered":"\n<h3 class=\"wp-block-heading\">A quick revision of the Dart language syntax<\/h3>\n\n\n\n<p>this document is a reminder of everything Dart related ! There is a different one for flutter.<\/p>\n\n\n\n<p>Why ? Because I have a problem, I don&#8217;t limit myself to a few languages like normal human beings, I know A LOT of programming languages, and when you don&#8217;t use a language long enough, you start messing up which syntax works where, so I create those small &#8220;Reminder&#8221; pages that I can skim through in an hour before I start working with any language after leaving it for some time !<\/p>\n\n\n\n<p>Mind you, I eventually lose the page &#8220;in the (It is on some hard drive somewhere) and that is because after using it a couple of times, I no longer need it. but when i come across old ones, I will post them on this blog.<\/p>\n\n\n\n<p>I am posting this one online because I am composing it now, and I haven&#8217;t lost it yet \ud83d\ude09<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Classification<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>AOT <strong>Compiled<\/strong> for Production, or JIT compiled during development<\/li>\n\n\n\n<li>Can also transpile into <strong>Javascript<\/strong><\/li>\n\n\n\n<li>Uses <strong>Garbage Collector<\/strong> (When AOT, it is bundled with compiled app)<\/li>\n\n\n\n<li>Dart is statically typed (Fixed variable types)<\/li>\n\n\n\n<li>sound null safe (sound = No mixing of safe and unsafe)<\/li>\n<\/ul>\n\n\n\n<!--more-->\n\n\n\n<h2 class=\"wp-block-heading\">var, const, and final<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>var<\/strong><\/h3>\n\n\n\n<p>the var keyword simply allows dart to assign &#8220;Infer&#8221; a type once it is assigned a value for the first time, that type can never change after that, even though the value can change, var means you can&#8217;t explicitly declare the variable type, for that you replace the word var with the type (ex: int).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>final and const<\/strong><\/h3>\n\n\n\n<p>const and final work like var in this inferring mechanism if you want them to, but will also allow you to explicitly state a data type after them. you can postpone the initialization of final values with the <strong>late<\/strong> keyword<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">const int myConst = 15;<br>late final String temperature;<\/pre>\n\n\n\n<p>final and const make variables immutable, but there is a notable difference, anything in a <strong>collection<\/strong> (List or the like) can be changed even if the collection itself is final, this is not true for const.<\/p>\n\n\n\n<p>the compiler must be able to resolve the value of a const at compile time, final can either be at compile time or at runtime<\/p>\n\n\n\n<p>const is more efficient, and from an efficiency perspective, wiser than using final when you can use it, final is no different than any other variable in terms of efficiency, it just makes the variable immutable.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">dynamic<\/h3>\n\n\n\n<p>dynamic data type allows the variable to change type during execution<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">null<\/h2>\n\n\n\n<p>A question mark in front of a variable type means it is nullable (can be null)<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">int? age;<\/pre>\n\n\n\n<p>if there is no question mark, you can still postpone the initialization instead with the <strong>late<\/strong> keyword as seen before<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Data Types<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Numeric types<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>int = Integer Values<\/li>\n\n\n\n<li>double = Floating point<\/li>\n\n\n\n<li>num: can be either integer or double<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Strings<\/h3>\n\n\n\n<p>Notice: this type starts with a capital letter (S), int and double for example don&#8217;t, In any other language, primitive types would be lowercase, while non primitive would start with capital letter, and even though all types in dart are non primitive, it tries to maintain familiarity with languages that do have that distinction !<\/p>\n\n\n\n<p>you can either use the + to concatenate, or interpolate with the dollar sign syntax for simple variables, or dollar sign and curly brackets for complex values (or any expression or even a ternary operator), if you want the escape characters to not escape but rather be considered characters, put a lowercase letter &#8220;r&#8221; in front of the string,<\/p>\n\n\n\n<p>up to now, i see no difference between double quotes and single quotes besides what quotes need to be escaped<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">example: howOld = 'I am $age ${age == 1 ? 'year' : 'years'} old.';<\/pre>\n\n\n\n<p><strong>StringBuffer<\/strong><\/p>\n\n\n\n<p>for very long strings, it is recommended to use<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">StringBuffer buffer = StringBuffer(); <\/pre>\n\n\n\n<p>then use its <strong>write<\/strong> method to concatenate to it, and its <strong>toString<\/strong> method to bring the contents back out<\/p>\n\n\n\n<p><strong>Detecting variable types<\/strong><\/p>\n\n\n\n<p>Any variable is an object, and all objects have a method called <strong>.runtimeType<\/strong>, so myVariable.runtimeType will return the type of the variable.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Functions<\/h2>\n\n\n\n<p>I usually use the words arguments and parameters interchangeably, while I have always known that arguments are the variables you pass to a function when you call it, and parameters are part of the function&#8217;s definition\/declaration, in practice, if you mix them up, everyone will still know what you are talking about.<\/p>\n\n\n\n<p>all <strong>functions are objects<\/strong> of class Function, everything in dart is an object.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">1- Positional mandatory <strong>parameters<\/strong><\/h3>\n\n\n\n<p>you can write the same function in 3 ways, the following are equivalent<\/p>\n\n\n\n<p><strong>1.1-<\/strong> The C++ way ! <strong>Positional, Mandatory<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">int addNums(int numOne, int numTwo) {<br>&nbsp;&nbsp;&nbsp; return numOne + numTwo;<br>}<\/pre>\n\n\n\n<p>OR<\/p>\n\n\n\n<p><strong>1.2-<\/strong> The object variable assignment (Object of &#8220;Function class&#8221; type) <strong>Positional, Mandatory<\/strong>, notice, whatever is after the = sign is simply a closure (Can&#8217;t seem to be able to figure out what the official name of an anonymous function is in dart, A closure, Lambda function, or anonymous function)<\/p>\n\n\n\n<p>what we are doing here is assigning this lambda function to a variable of type Function ! <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">Function addNums = (int numOne, int numTwo) {<br>&nbsp;&nbsp;&nbsp; return numOne + numTwo;<br>}<\/pre>\n\n\n\n<p><strong>1.3-<\/strong> <strong>Arrow Syntax<\/strong><\/p>\n\n\n\n<p>If we have <strong>one expression<\/strong>, whatever value that expression resolves to will be the return value.. you can call this exactly like you call the previous two<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>int addNums(int numOne, <\/code><code>int numTwo) =&gt; numOne + numTwo;<\/code><\/pre>\n\n\n\n<p><strong>NOTE<\/strong> 1: The data types &#8220;<strong>int<\/strong>&#8221; on the parameters in all three of the above are OPTIONAL as they can be inferred at runtime from the values passed ! (Not to be confused with Generic Data Types (<strong>T<\/strong>))<\/p>\n\n\n\n<p><strong>NOTE 2:<\/strong> A function can have any number of <em>required positional<\/em> parameters. These can be followed either by <em>named<\/em> parameters or by <em>optional positional<\/em> parameters (but not both).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">1- <strong>optional positional parameters<\/strong>&#8230;<\/h3>\n\n\n\n<p>Just put them in <strong>square brackets<\/strong> to make them <strong>optional<\/strong> ! When in square brackets, you must either have a question mark to allow them to be null or a default value !<\/p>\n\n\n\n<p>If you allow them to be null and don&#8217;t use a default value in the function declaration&#8230; you can use the double question mark (<strong>??<\/strong>) called the <strong>null-aware coalescing operator<\/strong>. It is a quick way to check if a value is null and provide a default value if it is.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">final actualName = name ?? 'Unknown'; <\/pre>\n\n\n\n<p>(will end up being either name or unknown depending on whether name is null)<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">2- <strong>Named parameters<\/strong><\/h3>\n\n\n\n<p>done by putting the parameters in<strong> curly brackets<\/strong>. the question mark is still required, unless it is named and mandatory, to make it mandatory, put the <strong>required<\/strong> keyword in front of it, you can then, if you like, remove the question mark, you can keep it if you want the user to be able to pass null !<\/p>\n\n\n\n<p>you can add default values in the definition (used when argument not passed) in the C style way !<\/p>\n\n\n\n<p><strong>If you want them named, you wrap them in { and }<\/strong>, once you do that, every parameter needs to be either optional (?) or required, and you can <strong>make them optional<\/strong> with a question mark right after the type annotation, or required with the required keyword<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong>String<\/strong> greeting({<strong>String<\/strong>? name, <strong>required int<\/strong> age}) {<br>\u00a0\u00a0\u00a0 return \"Hi, my name is $name and I am $age years old\";<br>}<\/pre>\n\n\n\n<p>calling<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">String myVariable = greeting(name: \"mario\", age: 55);<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">3- <strong>Callback functions<\/strong><\/h3>\n\n\n\n<p>Callback functions, is when you pass a function to another, where the other knows how to execute the function (You only pass the function name, the parameters are stored in the receiving function)<\/p>\n\n\n\n<p>INTERESTING: When calling a function, adding an exclamation mark at the end of parameter forces the compiler to send that value to the function and not look at null safety or type !<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Switch<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Switch statements and switch expressions<\/h3>\n\n\n\n<p><strong>1- Switch statements<\/strong> (Example does not use break because it uses return instead which exits anyway)<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">switch(day) {<br>&nbsp;&nbsp;&nbsp; case 1:<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 'Monday';<br>&nbsp;&nbsp;&nbsp; case 2:<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 'Tuesday';<br>&nbsp;&nbsp;&nbsp; default:<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 'Some other day';<br>}<\/pre>\n\n\n\n<p><strong>2- Switch expression<\/strong> (Semicolon at the end)<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">var theDay = switch(day) {<br>&nbsp;&nbsp;&nbsp; 1 =&gt; 'Monday';<br>&nbsp;&nbsp;&nbsp; 2 =&gt; 'Tuesday';<br>&nbsp;&nbsp;&nbsp; _ =&gt; 'Some other day';<br>};<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Records<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">&nbsp;(Like Tuples in rust) !<\/h3>\n\n\n\n<p>Records, if you come from rust or python or many other similar languages, Records are basically darts answer to <strong>tuples<\/strong> ! think of them as tuples that can either have <strong>positional data, or named data<\/strong><\/p>\n\n\n\n<p>records are fixed-sized, heterogeneous, and typed<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>\/\/ Record type annotation\n(String, int) record = ('A string', 123);<\/code><\/pre>\n\n\n\n<p>OR<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>(String myString, int myInt) record = ('A string', 123);\/\/ (Still unnamed because there are no curly brackets)<\/code><\/pre>\n\n\n\n<p>1- <strong>named fields<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">({String name, int age})<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">var person = (name: 'Clark', age: 42);<\/pre>\n\n\n\n<p>You can annotate the type of the variable person by preceding the variable names with their types, when in curly brackets within the brackets, <strong>the curly brackets as usual mean &#8220;named&#8221;, <\/strong>if not in curly brackets, the field names are just for the developers convenience and mean nothing.<\/p>\n\n\n\n<p>In the same way above, this could be a return type for a function for example<\/p>\n\n\n\n<p>to access fields in the record, you can use <strong>person.name<\/strong> since it is a named record,<\/p>\n\n\n\n<p>a returned record from a function can be split into a pattern, resulting in two variables for example<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Classes<\/h2>\n\n\n\n<p>Classes in dart use the keyword <strong>this<\/strong> like C++ (not self like python for example)<\/p>\n\n\n\n<p>the constructor is a method with the same name as the class<\/p>\n\n\n\n<p>We can have <strong>default values<\/strong> by simply assigning the values to the property names<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">class MenuItem {<br>&nbsp;&nbsp;&nbsp; String title = \"N\/A\";<br>&nbsp;&nbsp;&nbsp; double price = 0.00;<br>}<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">var noodles = menuItem();<\/pre>\n\n\n\n<p><strong>named constructor<\/strong> methods exist, they are alternative constructors, they use the name of the class and an additional subname.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">class Player {\n  Player(String name, int color) {\n    this._color = color;\n    this._name = name;\n  }\n\n  Player.fromPlayer(Player another) {\n    this._color = another.getColor();\n    this._name = another.getName();\n  }  \n}\n\nnew Player.fromPlayer(playerOne);\n<\/pre>\n\n\n\n<p>Named constructors can also be private by starting the name with <code>_<\/code><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>class Player {\n  Player._(this._name, this._color);\n\n  Player._foo();\n}<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">-----<br>Shorthand constructor, with additional named constructor<br><code>class Player {\n  final String name;\n  final String color;\n\n  Player(this.name, this.color);\n\n  Player.fromPlayer(Player another) :\n    color = another.color,\n    name = another.name;\n}\n<\/code><\/pre>\n\n\n\n<p>&#8212;&#8212;&#8212;<\/p>\n\n\n\n<p><strong>inheritance<\/strong> is done as follows<\/p>\n\n\n\n<p>class OfficialName <strong>extends<\/strong> Name<\/p>\n\n\n\n<p>and the constructor can either be<\/p>\n\n\n\n<p>OfficialName(this._title, String first, String last) : super(first, last);<\/p>\n\n\n\n<p>OR<\/p>\n\n\n\n<p>OfficialName(this._title, super.first, super.last);<\/p>\n\n\n\n<p><strong>inter faces and abstract classes<\/strong><\/p>\n\n\n\n<p>we have <strong>extends<\/strong>, which can only extend one class, but we also have<\/p>\n\n\n\n<p><strong>implements<\/strong>: all classes are implicit interfaces, when you implement a class, all classes in super must be re-implemented in new class, you can implement any number of classes<\/p>\n\n\n\n<p><strong>with<\/strong>: Apply mixin, which allows you to reuse a class&#8217;s code in multiple class hierarchies, without creating a subclass ! just borrowing the code<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Collections<\/h2>\n\n\n\n<p><strong>List<\/strong>: order is maintained (Array)<br><strong>Map<\/strong>: associative key value pairs accessed by key (hashmap or dictionary or associative array)<br><strong>Sets<\/strong>: No order, but only unique values, returns null if value is not there (Set or Hashset)<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>List<\/strong><\/h3>\n\n\n\n<p><strong>Dynamic list (Inferred Dynamically)<\/strong><\/p>\n\n\n\n<p><strong>List <\/strong>scores = [10, 11, 12, 13, 14]; \/\/ (List&lt;dynamic&gt;) This one<strong> accepts ANYTHING<\/strong> after this, it is a list of type DYNAMIC<\/p>\n\n\n\n<p><strong>var<\/strong> scores = [50, 60, 80, 451]; \/\/ (List&lt;int>) This becomes a list of integers, will <strong>only accept integers<\/strong> past this point !!!<\/p>\n\n\n\n<p><strong>var<\/strong> scores = [50, 60, 80, 451, &#8220;Disqualified&#8221;]; \/\/ (List&lt;Object&gt;) Any object will do, including an int<\/p>\n\n\n\n<p>List&lt;int> = [50, 60, 70];\/\/ Will only accept integers<\/p>\n\n\n\n<p><strong>Explicitly setting types:<\/strong><\/p>\n\n\n\n<p>List&lt;int&gt; scores = [50, 75, 20, 99];<\/p>\n\n\n\n<p>scores[2] = 25;\/\/ Update is okay !<\/p>\n\n\n\n<p>scores.add(150); \/\/ Add a new value to the end, you can&#8217;t add by assigning directly to a new index<\/p>\n\n\n\n<p>scores.remove(75); \/\/ Will remove scores[1], will only remove the <strong>first matching instance<\/strong><\/p>\n\n\n\n<p>scores.removeLast();\/\/ Removes the last element<\/p>\n\n\n\n<p>scores.length \/\/ the number of items in the list<\/p>\n\n\n\n<p>scores.shuffle();\/\/ Shuffles in place <\/p>\n\n\n\n<p>scores.indexOf(75); \/\/ Should rturn 1 !<\/p>\n\n\n\n<p>variableName.add \/\/ Concatenates one element<br>variableName.addAll \/\/ Takes another list and concatenates them<\/p>\n\n\n\n<p>numbers[1] = 15;<\/p>\n\n\n\n<p>going more than last element will throw an out-of-bounds exception<\/p>\n\n\n\n<p>&nbsp;the following should protect you, unless the list is empty, in that case they themselves will throw the No element error<\/p>\n\n\n\n<p>final firstElement = numbers.first;<br>final lastElement = numbers.last;<\/p>\n\n\n\n<p><strong>Map<\/strong><\/p>\n\n\n\n<p>Curly braces are used to create <strong>both sets and maps<\/strong><\/p>\n\n\n\n<p>but an <strong>empty couple of curley braces create a map<\/strong> not a set !<\/p>\n\n\n\n<p>var emptMap = {}; \/\/ This creates a map not a set<\/p>\n\n\n\n<p>A map has key value pairs, they keys have a type, and the values have a type<\/p>\n\n\n\n<p>var planets= {<br>&nbsp;&nbsp;&nbsp; &#8220;first&#8221;: &#8220;Mercury&#8221;,<br>&nbsp;&nbsp;&nbsp; &#8220;second&#8221;: &#8220;Venus&#8221;,<br>&nbsp;&nbsp;&nbsp; &#8220;third&#8221;: &#8220;earth&#8221;,<br>&nbsp;&nbsp;&nbsp; &#8220;fourth&#8221;: &#8220;mars&#8221;,<br>&nbsp;&nbsp;&nbsp; &#8220;fifth&#8221;: &#8220;Jupiter&#8221;<br>}<\/p>\n\n\n\n<p>OR<\/p>\n\n\n\n<p>Map&lt;int, String&gt; planets = {<br>&nbsp;&nbsp;&nbsp; 1: &#8220;Mercury&#8221;,<br>&nbsp;&nbsp;&nbsp; 2: &#8220;Venus&#8221;,<br>&nbsp;&nbsp;&nbsp; 3: &#8220;earth&#8221;,<br>&nbsp;&nbsp;&nbsp; 4: &#8220;mars&#8221;<br>}<\/p>\n\n\n\n<p>So, to access from the first map &lt;String, String><\/p>\n\n\n\n<p>print(planets[&#8220;fifth&#8221;]); \/\/ There you have it, provide the key and that is it<\/p>\n\n\n\n<p>planets[&#8220;fifth&#8221;] = &#8220;new planet&#8221;;<\/p>\n\n\n\n<p>Adding a new one<\/p>\n\n\n\n<p>planets[&#8220;sixth&#8221;] = &#8220;Uranus&#8221;; \/\/ yup,. <strong>unlike lists<\/strong>, you can add by assigning a new key a new value<\/p>\n\n\n\n<p>methods<\/p>\n\n\n\n<p>planets.containsKey(&#8220;third&#8221;); \/\/ Does the key exist ?<br>planets.containsValue(&#8220;earth&#8221;); \/\/ Does the value exist ?<br>planets.remove(&#8220;third); \/\/REemove the third key from the map, but returns it&#8217;s value &#8220;earth&#8221; one last time before it gets deleted<br>planets.keys; \/\/ Returns all the keys<br>planets.values(); \/\/ Returns all the values<\/p>\n\n\n\n<p>Map&lt;String, int&gt; variableName = {&#8216;Clark&#8217;: 25, &#8216;Pete&#8217;: 30};<\/p>\n\n\n\n<p>variableName[&#8216;Pete] = 33;<\/p>\n\n\n\n<p>ages[&#8216;newguy&#8217;] = 22;<br><\/p>\n\n\n\n<p>variableName.remove(&#8216;Pete&#8217;);<\/p>\n\n\n\n<p>ages.forEach((String name, int age) {<br>&nbsp;&nbsp;&nbsp; print(&#8216;$name is $age years old&#8217;);<br>}<br>);<br>\/\/the above uses an anonymous function that receives the values from the map as parameters, and prints them<\/p>\n\n\n\n<p>trying to access with a non existent key will simply return null, no errors or anything<\/p>\n\n\n\n<p><strong>Sets<\/strong><\/p>\n\n\n\n<p><strong>Very efficient<\/strong><\/p>\n\n\n\n<p>Can&#8217;t hold duplicates, and are <strong>unordered<\/strong><\/p>\n\n\n\n<p>final set people = {&#8216;Mark&#8217;, &#8216;moe&#8217;, &#8216;john&#8217;};\/\/ Implicit type string<\/p>\n\n\n\n<p>final Set&lt;String&gt; ministers = {&#8216;Justin&#8217;, &#8216;Stephen&#8217;, &#8216;Paul&#8217;, &#8216;Jean&#8217;, &#8216;Kim&#8217;, &#8216;Brian&#8217;}; \/\/Explicit type, string<br>ministers.addAll({&#8216;John&#8217;, &#8216;Pierre&#8217;, &#8216;Joe&#8217;, &#8216;Pierre&#8217;}); \/\/ Duplicates are ignored<\/p>\n\n\n\n<p>final isJustinAMinister = ministers.contains(&#8216;Justin&#8217;);<\/p>\n\n\n\n<p>for (String primeMinister in ministers) {<br>&nbsp;&nbsp;&nbsp; print(&#8216;$primeMinister is a Prime Minister.&#8217;);<br>}<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Control flow<\/strong><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">for loops<\/h3>\n\n\n\n<p>for header is same as C++<\/p>\n\n\n\n<p>for(int i = 0; i &lt; 5; i++)<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">loop through a list<\/h3>\n\n\n\n<p>for(int score in scores)<\/p>\n\n\n\n<p>in the loop above, you can use a <strong>where filter<\/strong> on the list to limit what scores are passed into the loop<br>the where filter takes a lambda expression AKA anonymous function AKA closures<\/p>\n\n\n\n<p>for(int score in scores.where((s) =&gt; s &gt; 50))<\/p>\n\n\n\n<p>Explanation:<\/p>\n\n\n\n<p>In the lambda expression, variables inside the () are parameters\/arguments, so the where will pass the S as parameter to the function, the body uses the S to return true or false to the where expression, when true, it passed it to the for loop, when false, it ignores it and moves on<\/p>\n\n\n\n<p><strong>Spread Operator<\/strong><\/p>\n\n\n\n<p>Notice how the if statement and the added set are all between two commas, as if they are one element of the big set ! the three dots are called the spread operator, <strong>Spread operators can also be used anywhere you wish to merge lists;<\/strong><\/p>\n\n\n\n<p>final randomNumbers = [<br>&nbsp;&nbsp;&nbsp; 34, 232, 54, 32, <strong>if<\/strong> (testCond) &#8230;[ 123, 258, 512, ],<br>];<\/p>\n\n\n\n<p>the following anon function returns values that are inserted into the list doubled, very interesting way of using a loop to fill in a List<\/p>\n\n\n\n<p>final doubled = [ for (int number in randomNumbers) number * 2, ];<\/p>\n\n\n\n<p>no return statement above, they will be added to the new list by magic ! but because this can be restrictive, you may want to use something like the randomNumbers example (collection-if or collection-for are valid)<\/p>\n\n\n\n<p><strong>Higher order functions<\/strong><\/p>\n\n\n\n<p>Where things get interesting,<\/p>\n\n\n\n<p>reading and writing data is all about Create, Read, Update, and Delete (CRUD), in the case of higher order functions, in contrast, higher order means they either take another function or return another function, not the data, the actual functions are the things passed around&#8230;<\/p>\n\n\n\n<p>1- map<\/p>\n\n\n\n<p>To avoid confusion, Map with a capital letter is a data type described above (HashMap), the method map (Small letter) is a method that returns an Iterable and is part of the Iterable abstract class !<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>\/\/ Without the map function, we would usually \/\/ write this code like this<\/td><td>\/\/ But instead it can be simplified and it can \/\/ actually be more performant on complex data<\/td><\/tr><tr><td>final names = []; <br>for (Map rawName in data) { <br>final first = rawName[&#8216;first&#8217;]; <br>final last = rawName[&#8216;last&#8217;]; <br>final name = Name(first, last); names.add(name); <br>}<\/td><td>List mapping() {<br>final names = data.map&lt;Name>((Map rawName) {<br>final first = rawName[&#8216;first&#8217;]; <br>final last = rawName[&#8216;last&#8217;]; <br>return Name(first, last); }).toList(); <br>return names; <br>} <br><br>\/\/OR even simpler skipping the intermediate variables <br><br>final names = data.map&lt;Name>( (Map raw) => Name(raw[&#8216;first&#8217;], raw[&#8216;last&#8217;]), ).toList();<\/td><\/tr><tr><td>The code above iterates in a for loop over the elements of type map inside the variable &#8220;data&#8221; of type list, storing the extracted map data in a list called names<\/td><td>mapping is a function that returns a List using the Iterable.map method<br><br>names = data.map(ANON_FUNCT).toList();<br><br>map returns an iterable, which can be then passed to anything else that is chained..<br><br>map is a method in Iterables class<br><br>map is also a generic function. Consequently, you can add some typing information\u2014in this case, \u2014to tell Dart that you want to save a list of Name, not a list of dynamics<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>The above function returns strongly typed data (A list of objects of type name)<\/p>\n\n\n\n<p><strong>Sorting<\/strong><\/p>\n\n\n\n<p>Now, we would like to sort the list by last name !<\/p>\n\n\n\n<p>sorts accepts an optional function (int sortPredicate(T elementA, T elementB);) that accepts two things to be compared, and returns 1, 0 or -1&#8230;(Anonymous in this case), the form would be <strong>data.sort(saidFunction);<\/strong><\/p>\n\n\n\n<p>final names = mapping();<\/p>\n\n\n\n<p><strong>names.sort(<\/strong>(a, b) =&gt; a.last.compareTo(b.last)<strong>)<\/strong>;<\/p>\n\n\n\n<p>Sort is a mutable function (Sorts in place)<\/p>\n\n\n\n<p><strong>Filtering<\/strong><\/p>\n\n\n\n<p>Takes a function that returns true or false, upon which we decide if this is to copy to new list or not<\/p>\n\n\n\n<p>Starts With is a method on the strings class<br><\/p>\n\n\n\n<p>final onlyMs = <strong>names.where(<\/strong>(name) =&gt; name.last.startsWith(&#8216;M&#8217;)<strong>);<\/strong><\/p>\n\n\n\n<p>Predicates (AKA tests): takes an input value and returns a Boolean value<\/p>\n\n\n\n<p>other forms of where that accept predicate functions as param are for example<\/p>\n\n\n\n<p>firstWhere(), lastWhere(), singleWhere(), indexWhere(), and removeWhere()<\/p>\n\n\n\n<p><strong>Reducing a list<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>void reducing() { <br>\/\/ Merge an element of the data together final <br>allAges = data.map&lt;int>((person) => person[&#8216;age&#8217;]);<br>int sum = 0; <br>for (int age in allAges) {<br>sum += age; <br>}<br>final average = sum \/ allAges.length; print(&#8216;The average age is $average&#8217;); }<\/td><td>void reducing() {<br>\/\/ Merge an element of the data together final <br>allAges = data.map&lt;int$gt((person) => person[&#8216;age&#8217;]); <br>final total = allAges.reduce((total, age) => total + age); <br>final average = total \/ allAges.length; <br>print(&#8216;The average age is $average&#8217;); }<br><\/td><\/tr><tr><td><br><\/td><td><br><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>if you do not want your code to start reducing from the first element, you can use <strong>fold()<\/strong>, fold itself has 2 arguments, the first is a starting point other than zero, and the other is just like reduce BUT INC<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">final numbers = &lt;double&gt;[10, 2, 5, 0.5];\nfinal result = numbers.fold&lt;double&gt;(100, (previousValue, element) =&gt; previousValue + element);\nprint(result); \/\/ 117.5<\/pre>\n\n\n\n<p><strong>reduce<\/strong>: In the function above, A reduce function will provide two parameters to the anonymous function (total and age in the example), the previous result and the current elements:&#8230; the function will use the two values to set a NEW VALUE for <strong>total, <\/strong>which is the same value that gets passed again and again as the iterator goes<\/p>\n\n\n\n<p>we then proceed to divide by the number of elements in the allAges array to get the average age<\/p>\n\n\n\n<p><strong>Flattening<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">void flattening() {\n  final matrix = [\n    [1, 0, 0],\n    [0, 0, -1],\n    [0, 1, 0],\n  ];\n  final linear = matrix.expand((row) =&gt; row);\n  print(linear);\n }<\/pre>\n\n\n\n<p><strong>expand<\/strong>: Flattening is how we would turn a 2d array (matrix for example) into a 1D array<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">The first-class functions pattern<\/h3>\n\n\n\n<p><strong>names.forEach(print);<\/strong> and <strong>.toList()<\/strong>; seen above are such functions<\/p>\n\n\n\n<p><strong>forEach()<\/strong><\/p>\n\n\n\n<p>forEach() function&nbsp; expects a function with the following signature<\/p>\n\n\n\n<p>void Function(T element)<\/p>\n\n\n\n<p>The <strong>print()<\/strong> function has the following signature:<\/p>\n\n\n\n<p>void Function(Object? object)&nbsp;<\/p>\n\n\n\n<p>Which means that the function forEach requires, can be the print function since the signatures are the same<\/p>\n\n\n\n<p>Since both of these expect a function parameter and the print function has the same signature, we can just provide the print function as the parameter!&nbsp;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Iterables<\/h3>\n\n\n\n<p>Iterables are <strong>lazy<\/strong>,&nbsp; laziness means that the function will only be executed when it\u2019s needed, not earlier. This means that we can take multiple higher-order functions and chain them together<\/p>\n\n\n\n<p>You can create more than one iterator from the same Iterable, Each time iterator is read, it returns a new iterator, and different iterators can be stepped through independently<\/p>\n\n\n\n<p>map keys (not just the mapm map keys) is an iterable for example, for (var book in kidsBooks.keys)&#8230;.<\/p>\n\n\n\n<p><strong>map and where<\/strong> return iterables, and iterables are lazy, so chaning the following only executes them after the one before executes, so as the list gets smaller, we don&#8217;t need to run every element through every function<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> final names = data\n    .map((raw) =&gt; Name(raw['first'], raw['last']))\n    .where((name) =&gt; name.last.startsWith('M'))\n    .where((name) =&gt; name.first.length &gt; 5)\n    .toList(growable: false);\n    <\/pre>\n\n\n\n<p>The above, map returns an iterable which is passed to where then where and finally, the iterable is transformed into a List<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">THE CASCADE OPERATOR&nbsp; (Unique to dart)<\/h3>\n\n\n\n<p>1- the <strong>builder pattern<\/strong> is a special kind of class whose only job is to configure and create other classes.<\/p>\n\n\n\n<p>1- The builder pattern without cascade operator<\/p>\n\n\n\n<p>When you want to add elemenets to a list with the add operator&#8230;<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">myList.add(\"item1\");\nmyList.add(\"item2\");\n\/\/ add again and again\u2026\nmyList.add(\"itemN\");\n    <\/pre>\n\n\n\n<p>But, since add returns null ! you CANNOT just do it with a dot because there is nothing that will get returned to get passed forward<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> THIS IS NO GO =&gt; myList.add(\"item1\").add(\"item1\")\u2026.add(\"itemN\");\n    <\/pre>\n\n\n\n<p>So, the cascade operator is JUST SYNTACTIC SUGAR that is dart specific<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">This is GO =&gt; myList..add(\"item1\")..add(\"item2\")\u2026..add(\"itemN\");<\/pre>\n\n\n\n<p>It is <strong>syntactic sugar<\/strong> where you can just skip the object name every time, and dart will know that all those operations need to be executed on the same object, that is it, nothing more to it<\/p>\n\n\n\n<p>Cascade operator long examples<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">class UrlBuilder {\n  String? _scheme;\n  String? _host;\n  String? _path;<br><br>&nbsp;UrlBuilder setScheme(String value) {\n    _scheme = value;\n    return this;\n  }<br><br>&nbsp;UrlBuilder setHost(String value) {\n    _host = value;\n    return this;\n  }<br><br>&nbsp;UrlBuilder setPath(String value) {\n    _path = value;\n    return this;\n  }<br><br>&nbsp;String build() {\n assert(_scheme != null);\n assert(_host != null);\n assert(_path != null);\n return '$_scheme:\/\/$_host\/$_path';\n  }\n }<br><br>void main() {\n final url = UrlBuilder()\n      .setScheme('https')\n      .setHost('dart.dev')\n      .setPath('\/guides\/language\/language-tour#cascade-notation-')\n      .build();\n print(url);\n}\n    <\/pre>\n\n\n\n<p>Now, the above has 3 setter methods,&nbsp; METHOD TO GROUP THEM, AND THEN ALL 4 ARE CALLED BY MAIN in one statement, this is the usual method in most languages<\/p>\n\n\n\n<p>in dart, we can use the cascade operator<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">class UrlBuilder {\n String scheme = '';\n String host = '';\n List routes = [];\n @override\n String toString() {\n   final paths = [host, if (routes != []) ...routes];\n    final path = paths.join('\/');\n    return '$scheme:\/\/$path';\n  }\n }<br><br>&nbsp;void cascadePlayground() {\n  final url = UrlBuilder()\n    ..scheme = 'https'\n    ..host = 'dart.dev'\n    ..routes = [\n      'guides',\n      'language',\n      'language-tour#cascade-notation',\n    ];\n  print(url);\n }\n    <\/pre>\n\n\n\n<p>The above is an elaboration on the &#8220;Builer pattern&#8221;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Extensions (WITHOUT INHERITENCE)<\/h3>\n\n\n\n<p>This is usefull when your program has so many string variables for example, and you want to add features to the existing variables without changing their type to a subclass&#8230; you can add methods to an existing class without changing it<\/p>\n\n\n\n<p>traditionally, when you want a class to inherit another, you say, <strong>class ExtendedClass extends baseClass {<\/strong><\/p>\n\n\n\n<p>Now, <strong>you can ALSO<\/strong> extend a class without creating a new class that inherits it!<\/p>\n\n\n\n<p>simply put, the following will add functionality to the string class without having to use the name of a new class<\/p>\n\n\n\n<p><strong>extension StringExtensions on String {<\/strong><\/p>\n\n\n\n<p><strong>Now, String myString = &#8220;Hello Extensions!&#8221;;<\/strong> will have methods from the &#8220;ExtendedClass&#8221; even though it was instantiated as String !<\/p>\n\n\n\n<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Null Safety<\/h3>\n\n\n\n<p>Sound null safety = March 2021<br><\/p>\n\n\n\n<p>unsound null safety: program runs with a mix of null safe and not null safe code,<br><\/p>\n\n\n\n<p>According to dart, this is more or less the definition&#8230;. in the docs it says (see last paragraph)<\/p>\n\n\n\n<p>For us, in the context of null safety, that means that if an expression has a static type that does not permit null, then no possible execution of that expression can ever evaluate to null. The language provides this guarantee mostly through static checks, but there can be some runtime checks involved too.<\/p>\n\n\n\n<p>it means that the compiler can perform optimizations that assume those properties are true.<\/p>\n\n\n\n<p>We only guarantee soundness in Dart programs that are fully null safe. Dart supports programs that contain a mixture of newer null safe code and older legacy code. In these mixed-version programs, null reference errors may still occur. In a mixed-version program, you get all of the static safety benefits in the portions that are null safe, but you don\u2019t get full runtime soundness until the entire application is null safe.<\/p>\n\n\n\n<p>INTERESTING&#8230; reminder: When calling a function, adding an exclamation mark at the end of parameter forces the compiler to send that value to the function and not look at null safety or type !<\/p>\n\n\n\n<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A quick revision of the Dart language syntax this document is a reminder of everything Dart related ! There is a different one for flutter. Why ? Because I have a problem, I don&#8217;t limit myself to a few languages like normal human beings, I know A LOT of programming languages, and when you don&#8217;t [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[203,160],"tags":[],"class_list":["post-4463","post","type-post","status-publish","format-standard","hentry","category-dart-flutter","category-software-development"],"_links":{"self":[{"href":"https:\/\/www.voodoo.business\/blog\/wp-json\/wp\/v2\/posts\/4463","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.voodoo.business\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.voodoo.business\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.voodoo.business\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.voodoo.business\/blog\/wp-json\/wp\/v2\/comments?post=4463"}],"version-history":[{"count":21,"href":"https:\/\/www.voodoo.business\/blog\/wp-json\/wp\/v2\/posts\/4463\/revisions"}],"predecessor-version":[{"id":4503,"href":"https:\/\/www.voodoo.business\/blog\/wp-json\/wp\/v2\/posts\/4463\/revisions\/4503"}],"wp:attachment":[{"href":"https:\/\/www.voodoo.business\/blog\/wp-json\/wp\/v2\/media?parent=4463"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.voodoo.business\/blog\/wp-json\/wp\/v2\/categories?post=4463"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.voodoo.business\/blog\/wp-json\/wp\/v2\/tags?post=4463"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}