Dart : A Powerful Programming Language

Dart is a client-optimized programming language for apps on multiple platforms. It is developed by Google and is used to build mobile, desktop, server, and web applications. Dart is an object-oriented, class-based, garbage-collected language with C-style syntax. Dart can compile to either native code or JavaScript.

Dart was released by Google in 2011 and was initially designed as a replacement for JavaScript. Since then, the release of the Flutter SDK for iOS, Android, and web development has put a new spotlight on the Dart language. The most recent version of Dart at the time of this recording is 2.4.

Dart has many similarities to other languages you may already be familiar with, such as Java, C#, Swift, and Kotlin. Dart has the following language characteristics:

  • Statically typed
  • Type inference
  • String expressions
  • Multi-paradigm including OOP and functional
  • Can mimic dynamic types using dynamic

In addition to its use for mobile and web development, Flutter is the development kit for Fuchsia, an experimental operating system under development at Google.

This tutorial will introduce you to Dart basics such as:

  • Variables, data types, and operators
  • Conditionals and loops
  • Functions, anonymous functions, and closures
  • Arrow function syntax

You can go beyond the basics and learn more about Object-Oriented Programming in Dart as well as Dart collection types such as lists, sets, and maps.

Getting Started

Dartpad

DartPad is setup like a typical IDE. There is:

  • An Editor pane on the left
  • A Run button to run code in the editor
  • A Console on the upper right showing output
  • An Info panel on the bottom right showing information highlighted code
  • A Samples dropdown to show some sample code
  • A Share button you can use to share DartPad files you’ve created

Down in the lower bottom right, there’s a checkbox to show some more panels related to using Dart for web programming, and some text showing the current version of Dart being used in DartPad.

Core Concepts

Clear out all the code in the default DartPad, and add a `main` function to the editor:

Main Function

The main function is preceded by a return type, which in Dart is void, meaning nothing is returned. The parentheses after main indicate that this is a function definition, and the curly braces contain the body of the function. Inside main, you add the Dart code for your program.

Variables, Comments, and Data Types

Add a new variable to main:

Like C and Java, each Dart statement ends in a semicolon. You’ve created a myAge variable set it equal to 35.

You can use the built-in print function in Dart to print the variable to the console, so add that call after the variable:

Basic Dart Types

Dart uses int for integers, double for floating points, and bool for booleans. ints and doubles are both derived from a type named num. You use the String type to represent sequences of characters. Dart also has a keyword dynamic which lets you mimic dynamic typing in the statically typed Dart.

You can also use type inference for types other than int. Enter a variable pi equal to 3.14 like so:

pi is inferred to be a double since you used a floating-point value to initialize it. You can see that in the Dart info panel

You can also just use double as the type instead of var:

In this case, you’ve initialized c, the symbol for the speed of light, with an int, but because you specified the type as double, c is in fact a double. Dart will convert the int to a double in order to initialize c. So unlike Swift, Dart has implicit type-conversion.

The dynamic Keyword

If you use the dynamic keyword instead of var, you get what is effectively a dynamically-typed variable:

You can set numberOfKittens to a String using quotes (see below for more on the String type)

numberOfKittens has a type, as it must since Dart has static typing. But that type is dynamic, which means you can assign other values with other types to it. So you can assign an int value below your print statement.

Or if you have a kitten in Schrödinger’s box, you could assign a double value:

step by step procedure

Operators

There are arithmetic operators, equality, increment and decrement, comparison, and logical operators.

Dart also allows for operator overloading like C++ and Kotlin, but that’s beyond the scope of this tutorial.

The arithmetic operators work just liked you’d expect. Add a bunch of operations to your DartPad:

print(40 + 2); // 42
print(44 - 2); // 42
print(21 * 2); // 42
print(84 / 2); // 42

You can initialize variables using arithmetic expressions:

var atltuae = 84.0 / 2;
print(atltuae); // 42

Dart converts the int to a double prior to the operation, so that the resulting variable is inferred to be a double.

Dart has double-equals equality and not-equals operators:

print(42 == 43); // false
print(42 != 43); // true

There are pre- and post-fix increment and decrement operators:

print(atltuae++); // 42
print(--atltuae); // 42

Because the use of increment is postfix, 42 is printed before the increment occurs. The decrement is prefix, so 43 is decremented to 42 and then the value 42 is printed.

Dart has the typical comparison operators like less than and greater than or equal to.

print(42 < 43); // true
print(42 >= 43); // false

There are also the usual compound arithmetic/assignment operators

atltuae += 1; print(atltuae); // 43
atltuae -= 1; print(atltuae); // 42
atltuae *= 2; print(atltuae); // 84
atltuae /= 2; print(atltuae); // 42

And Dart has the usual modulo operator.

print(392 % 50); // 42

The logical operators such as && for and and || for or look just like those from other languages.

print((41 < atltuae) && (atltuae < 43)); // true
print((41 < atltuae) || (atltuae > 43)); // true

And the negation operator is the exclamation mark, turning false to true and true to false.

print(!(41 < atltuae)); // false

Strings

Like for the other types we’ve seen, you can use either var and type inference or String to create a string variable:

var firstName = 'Albert';
String lastName = "Einstein";

Similar to languages like Kotlin and Swift, you can embed values and expressions inside strings to create new strings, using the dollar sign symbol $.

var physicist = "$firstName $lastName";
print(physicist); // Albert Einstein

You can combine adjacent strings, for example, long strings that go multiple lines, simply by placing the strings next to one another or on separate lines:

var quote = 'If you can\'t' ' explain it simply\n'
"you don't understand it well enough.";
print(quote);
// If you can't explain it simply
// you don't understand it well enough.

Here in the first string, you used single quotes and so used an escape sequence \' to embed a quotation mark for can't into the string. The escape sequences used in Dart are similar to those used in other C-like languages, for example, \n for a newline.

Since you used double-quotes to delimit the second string, you did not need an escape sequence for the single quote on don't.

You can also combine strings using the + operator:

var energy = "Mass" + " times " + "c squared";
print(energy); // Mass times c squared

You can use triple quotes to have a string run multiple lines and preserve formatting:

var model = """
I'm not creating the universe.
I'm creating a model of the universe,
which may or may not be true.""";
print(model);
// I'm not creating the universe.
// I'm creating a model of the universe,
// which may or may not be true.

If you need to have escape sequences shown within the string, you can use raw strings, which are prefixed by r.

var rawString = r"If you can't explain it simply\nyou don't understand it well enough.";
print(rawString);
// If you can't explain it simply\nyou don't understand it well enough.

Go ahead and click Run in DartPad to see all your strings in the console.

Control Flow

Conditionals

Suppose you have an animal variable that’s currently a fox.

var animal = 'fox';

You can use an if statement to check whether the animal is a cat or dog, and run some corresponding code if so.

if (animal == 'cat' || animal == 'dog') {
print('Animal is a house pet.');
}

Here you’ve used the equality and or operators to create a bool value inside the condition for the if statement.

You can use an else clause to run alternative code if the condition is false:

} else {
print('Animal is NOT a house pet.');
}
// Animal is NOT a house pet.

You can also combine multiple if/else statements into an if/else if/else construct:

if (animal == 'cat' || animal == 'dog') {
print('Animal is a house pet.');
} else if (animal == 'rhino') {
print('That\'s a big animal.');
} else {
print('Animal is NOT a house pet.');
}
// Animal is NOT a house pet.

You can have as many else if branches in between if and else as needed.

While Loops

There are two forms of while loop in Dart, while and do-while. The difference is that for while, the loop condition is before the code block, and in do-while the condition is after. So for do-while, the code block is guaranteed to run at least one time.

Create a variable i initialized to 1:

var i = 1;

You can use a while loop to print i while incrementing it, and set the condition to be that i is less than 10:

while (i < 10) {
print(i);
i++;
}
// 1
// 2
// 3
// 4
// 5
// 6
// 7
// 8
// 9

Run the code and you see the numbers 1 to 9 printed out by the while loop.

Reset i in DartPad and then add a do-while loop:

i = 1;
do {
print(i);
++i;
} while (i < 10);
// 1
// 2
// 3
// 4
// 5
// 6
// 7
// 8
// 9

The results here are the same as before, just this time, the loop body ran once before the loop exit condition was checked.

continue and break

You must be careful when using continue in your code. For example, if you take the do-while loop from above, and say you want to continue when i is equal to 5, that could result in an infinite loop that just keeps running, depending in where you place the continue statement:

do {
print(i);
if (i == 5) {
continue;
}
++i;
} while (i < 10);
// 1
// 2
// 3
// 4
// 5
// 5
// 5
// 5
// 5
// 5
// 5
// 5
// 5
// 5
// ...

The infinite loop occurs since once i is 5, you never increment i, and the condition always stays true.

If you run this in DartPad, the infinite loop will cause the browser to hang. Instead use break, so that the loop will end after i reaches 5:

do {
print(i);
if (i == 5) {
break;
}
++i;
} while (i < 10);
// 1
// 2
// 3
// 4
// 5

Run the code now and see that the loop ends after 5 iterations.

For Loops

Dart has both a C-like form of a for loop, with an initialization, loop condition, and an action, as well a for-in loop for iterating over a collection of objects. In the first form, the initialization runs before the first loop iteration. The condition is checked on entering each iteration, and the action is run before starting the next iteration.

For the for-in form, a variable is set to each element in a collection of Dart objects for each subsequent iteration of the loop. Let’s say you want to sum up the values of the first 10 integers.

Create a variable for the sum:

var sum = 0;

Then use a for loop in which you initialize a loop counter i to 1, check that i is less than or equal to 10, and increment i after every loop. Inside the loop use a compound assignment to add i to the running sum:

for (var i = 1; i <= 10; i++) {
sum += i;
}
print("The sum is $sum"); // The sum is 55

Run your code in DartPad to see the sum.

An example of a Dart collection is a simple list of numbers made with square brackets:

var numbers = [1, 2, 3, 4];

You can use a for-in loop to iterate over the list:

for (var number in numbers) {
print(number);
}
// 1
// 2
// 3
// 4

The variable number takes on the value of each element of numbers as you iterate in the loop.

Lists like numbers also have a function you can call on them named forEach, which simplifies the previous loop down to one line:

numbers.forEach((number) => print(number));
// 1
// 2
// 3
// 4

Here you’ve used an anonymous function and arrow syntax, both of which you’ll see later on in the section on Functions.

Finally, like while loops, for loops can also use continue and break to control flow within the loop. For example, if you want to skip printing the number 3, you can use a continue statement in the for-in loop:

for (var number in numbers) {
if (number == 3) {
continue;
}
print(number);
}
// 1
// 2
// 4

Functions

function

A function consists of a return type, a function name, a parameter list in parentheses, and then a function body enclosed in braces. The code you’re turning into the function goes inside the braces. When you call the function, you pass in arguments that match the types of the parameters of the function.

Typically, functions are defined either outside other functions or inside Dart classes, but you can also nest Dart functions in one another. For example, you can add the functions in this section inside main.

Write a new function in DartPad that will just check to see if a given string is banana.

bool isBanana(String fruit) {
return fruit == 'banana';
}

The function uses return to return a bool value determined by the argument passed to the function. This function will always return the same value for any given input. If a function does not need to return a value, you can set the return type to void, such as for the main function.

You can call the function by passing in a string. Then you might pass the result of that call onto print:

var fruit = 'apple';
print(isBanana(fruit)); // false

You can change the argument passed to functions, and call them again with a new argument:

fruit = 'banana';
print(isBanana(fruit)); // true

The result of calling the function depends entirely on the arguments passed in.

Optional Parameters

String fullName(String first, String last, [String title]) {
return "${title == null ? "" : "$title "}$first $last";
}

If an optional parameter is not included in the function call, the value used is null for the parameter inside the function body.

Then you can call the function with or without the optional parameter:

print(fullName("Joe", "Howard"));
// Joe Howard
print(fullName("Albert", "Einstein", "Professor"));
// Professor Albert Einstein

Optional Named Arguments

bool withinTolerance({int value, int min, int max}) {
return min <= value && value <= max;
}

Then you can pass in arguments in a different order by supplying the parameter names with a colon:

print(withinTolerance(min: 1, max: 10, value: 11)); // false

Like for optional parameters, arguments with optional names do not need to be added to a function call, and the corresponding parameters will be given the value null in the function.

Default Values

bool withinTolerance({int value, int min = 0, int max = 10}) {
return min <= value && value <= max;
}

You can then leave off the parameters with default values when calling the function.

print(withinTolerance(value: 5)); // true

Run your code to see your new functions in action.

First-Class Functions

You can use the Function type to specify that a parameter named op is a function itself:

int applyTo(int value, int Function(int) op) {
return op(value);
}

So if you have a function named square:

int square(int n) {
return n * n;
}

You can pass square to applyTo as an argument:

print(applyTo(3, square)); // 9

You can assign a function to a variable:

var op = square;

Then you can call the function on the variable as if it were an alias for the original function:

print(op(5)); // 25

You’ll see more about returning functions from other functions a bit later.

Anonymous Functions and Closures

You can assign an anonymous function to a variable:

var multiply = (int a, int b) {
return a * b;
};

The right-hand-side consists of a parameter list and a function body.

Since multiply now holds an anonymous function, you can call it as you would any other function:

print(multiply(14, 3)); // 42

You’ve seen a preview earlier of lists and the forEach function. forEach is a great example of using an anonymous function.

So if you have a list of numbers:

numbers = [1, 2, 3];

You can call forEach on the list and pass in an anonymous function that triples an element and prints out the tripled value:

numbers.forEach((number) { 
var tripled = number * 3;
print(tripled);
// 3
// 6
// 9
});

You can return an anonymous function from another function:

Function applyMultiplier(num multiplier) {
return (num value) {
return value * multiplier;
};
}

This is useful for generating functions with a given behavior but with varying input parameter values. So the return value here is a function that takes one num parameter and multiplies it by the multiple used to generate the function.

An example is creating a variable named triple which multiplies its input by 3:

var triple = applyMultiplier(3);

You can calling triple with either type of num:

print(triple(6)); // 18
print(triple(14.0)); // 42

Anonymous functions in Dart act as closures, which means they “close-over” variables defined outside of themselves. For example, the return value of the applyMultiplier function above is a closure that has access to the multiplier variable defined elsewhere, in that case in the parameter list for applyMultiplier itself.

Arrow Syntax

For example, multiply above becomes:

var multiply = (int a, int b) => a * b;

You’ve removed the braces and the return statement.

You can also use arrow syntax with applyMultiplier:

Function applyMultiplier(num multiplier) =>
(num value) => value * multiplier;

You’ve used arrow syntax twice here: the first is denoting the return value for the applyMultiplier function, the second is within the return value itself, which is an anonymous function.

In the example just above using forEach, you cannot use arrow syntax, since the body of the function you're passing to forEach has more than one line of code.

“Any fool can write code that a computer can understand. Good programmers write code that humans can understand.” ― Martin Fowler

I am flutter/dart developer trying to learn new things .

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store