Dart

Control Flow in Dart

Hey guys, welcome to the new article! Today, we’re diving into Control Flow in Dart Programming Langauge.

When writing a computer program, you need to be able to tell the computer what to do in different scenarios. For example, a calculator app would need to perform one action if the user taps the addition button, and another action if the user taps the subtraction button.

In computer programming terms, this concept is known as the code makes at multiple points. In this tutorial, you’ll learn how to make decisions and repeat tasks in your programs.

Making comparisons

In Dart, you’ve already seen some basic types like int, double, and String. Each of these types is meant to hold specific kinds of data.
For example int is used for whole numbers, double is for decimal numbers, and String is for text.

Now, think about questions that can be answered with just “yes” or “no”. For instance:

  • Is the door open?
  • Do pigs fly?
  • Is the traffic light red?

You might think of using String to “yes” or “no” answers, or int with 0 for “no” and 1 for “yes”. But this can be confusing if you accidentally get unexpected answers like “42” or “celery”.

To avoid this confusion, Dart has a special type called bool (short for “Boolean”). A bool variable can only hold two values: true or false. This makes it perfect for yes-no questions, ensuring there’s no ambiguity. For example

bool isDoorOpen = true;
bool doPigsFly = false;

In these cases, isDoorOpen is true (yes, the door is open) and doPigFly is false (no, pigs do not fly). Using bool makes your code clearer and prevents mistakes with unexpected values.

Boolean values

Dart has a data type just for this. It’s called bool, which is short for Boolean.
A Boolean value can have one of two states. While in general you could refer to the states as yes and no, on and off, or 0 and 1, most programming languages Dart included, call them true and false.

The word Boolean was named after George Boole, the man who pioneered an entire field of mathematics around the concept of true and false. Since computer themselves are based on electrical circuits which can be in a binary state of on or off, Boolean math is fundamental to computer science.

When programming in a high level language like Dart, you don’t need to understand all of the Boolean logic that’s happening at the circuit level, but there’s still a lot about Boolean math you can apply to decision making in your own code.

To start your exploration of Booleans in Dart, create some Boolean variables like so:

Control Flow in Dart

Because of Dart’s type inference, you can leave off the type annotation:

Control Flow in Dart

Boolean operators

Booleans are commonly used to compare values. For example, you may have two values and you want to know if they’re equal. Either they are equal, which would be true, or they aren’t equal, which would be false.

Now let’ see how to make that comparison in Dart.

Testing equality

You can test for equality using the equality operator, which is denoted by ==, that is, two equals signs.
Write the following line:

Control Flow in Dart

Dart infers that doesOneEqualTwo is a bool. Clearly, 1 does not equal 2, and therefore doesOneEqualTwo will be false.

Testing inequality

You can also find out if two values are not equal using the != operator:

Control Flow in Dart

This time, the result of the comparison is true because 1 does not equal 2, so doesOneNotEqualTwo will be true.

The prefix ! operator, also called the not-operator or bang operator, toggles true to false and false to true.

Testing greater and less than

There are two other operators to help you compare two values and determine if a value is grater than (>) or less than (<) another value. You know these from mathematics:

Control Flow in Dart

It’s not rocket science to work out that isOneGreaterThanTwo will equal false and that isOneLessThanTwo will equal true.

The <= operator lets you test if a value is less than or equal to another value. It’s a combination of < and ==, and will therefore return true if the first value is less than, or equal to, the second value.

Control Flow in Dart

Boolean Logic

Each of the examples above tests just one condition. When George Bole invented the Boolean, he had much more planned for it these humble beginnings. He invented Boolean logic, which lets you combine multiple conditions to form a result.

AND operator

Imagine Ray wants to go cycling with Vicki this weekend, but two things need to happen for that to work out:

  • It must be sunny.
  • Vicki must finish her art project.

If either of these condition isn’t met, Ray and Vicki can’t go cycling.
This is a classic example of a Boolean AND operation. Both condition need to be true for the final outcome (going cycling) to be true.

In Dart, the AND operator is written as &&. Here’s how you use it:

Control Flow in Dart

If either isSunny or isFinished were false, then willGoCycling would be false as well.

The OR Operator

Now, let’s say Vicki wants to draw a Bird, but she needs a model.
She could either travel to Australia or she could find a photograph on the internet. If only one of two conditions need to be true in order for the result to be true, this is an example of a Boolean OR operation. The only instance where the result would be false is if both input Booleans were false.
If Vicki doesn’t go to Australia and she also doesn’t find a photograph on the internet, then she won’t draw a Bird.

In Dart, the operator for Boolean OR is written ||, used like so:

Control Flow in Dart

Print canDrawBird to see that its value is true. If both values on the right were false, then canDrawBird would be false. If both were true, then canDrawBird would still be true.

Operator precedence

As was the case in the Ray and Vicki examples above, Boolean logic is usually applied to multiple conditions. When you want to determine if two conditions are true, you use AND, while if you only care whether one of the two conditions is true, you use OR.

Here are a few more examples:

Control Flow in Dart

Each of these tests two separate conditions, combining them with either AND or OR.

It’s also possible to use Boolean logic to combine more than two comparisons. For example, you can form a complex comparison like so:

3 > 4 && 1 < 2 || 1 < 4

But now it gets a little confusing. You have three conditions with two different logical operators. With the comparisons simplified, you have the following form:

false && true || true

Depending on the order you perform the AND and OR operations, you get different results. If you evaluate AND first, the whole expressions is true, while if you evaluate OR first, the whole expression is false.

This is where operator precedence comes in. The following list shows the order that Dart uses to evaluate expressions containing comparison and logical operators:

!
>= > <= <
== !=
&&
||
Operator precedence

Operators higher in the list are executed before operators lower in the list. You can see that && has a higher precedence than ||. So back to case from before:

false && true || true

First Dart will evaluate false && true, which is false. Then Dart will take that false to evaluate false || true, which is true. Thus the whole expression evaluates to true.

Overriding precedence with parentheses

If you want to override the default operator precedence, you can put parentheses around the parts Dart should evaluate first.

Compare the following two expressions:

3 > 4 && ( 1 < 2 || 1 < 4) //false
(3 > 4 && 1 < 2 ) || 1 < 4 // true

The parentheses in the first line force Dart to do the OR operation before the AND operation, even though that isn’t the default order. This results in the entire expression evaluating to false instead of true, as it would have if you hadn’t used parentheses.

Even when parentheses are not strictly required, as in the second of the two expression above, they can still help to make the code more readable. For this reason, it’s usually a good idea to use parentheses when you’re performing a logical operation or more than two conditions.

String equality

Sometimes you’ll want to determine if two strings are equal. For example, a children’s game of naming an animal in a photo would need to determine if the player answered correctly.

In Dart, you can compare strings using the standard equality operator, ==, in exactly the same way as you compare numbers. For example:

Control Flow in Dart

Here, dogEqualToCat is a Boolean, which is this case is false because the string ‘dog’ does not equal to string ‘cat’.

The if statement

The first and most common way of controlling the flow to a program is through the use of if statement, which allows the program to do something only if a certain condition is true. For example, consider the following.

Control Flow in Dart

This is a simple if statement. The condition, which is always a Boolean expression, is the part within the parentheses that follows the if statement.

If the condition is true, then the if statement will execute the code between the braces. If the condition is false, then the if statement won’t execute the code between the braces.

Obviously, the condition ( 2 > 1 ) is true, so when you run that you’ll see:

Yes, 2 is greater than 1.

The else clause

You can extend an if statement to provide code to run in the event that the condition turns out to be false. This is know as the else clause.

Here’s an example:

Control Flow in Dart

If animal equals either ‘Cat’ or ‘Dog’, then the statement will execute the first block of code. If animal does not equal either ‘Cat’ or ‘Dog’, then the statement will run the block inside the else clause of the if statement.

Run that code and you’ll see the following in the debug console:
Animal is not a house pet.

Else-if chains

You can go even further with if statements. Sometimes you want to check one condition, and then check another condition, and then check another condition if the first condition isn’t true.
This is where else – if comes into play, nesting another if statement in the else clause of a previous if statement.

You can use it like so:

Control Flow in Dart

In this example, the first if statement will check if trafficLight is equal to ‘red’. Since it’s not, the nest if statement will check if trafficLight is equal to ‘yellow’. It is equal to ‘yellow’, so no check will be made for the case of ‘green’.

Run the code and it will print the following:

Slow down

These nested if statements test multiple conditions, one by one, until a true condition is found. Only the code associated with the first true condition encountered will be executed regardless of whether there are subsequent else – if conditions that evaluate to true. In other words, the order of your conditions matters!

You can add an else clause at the end to handle the case where none of the conditions are true. It this example, you do need the else clause to ensure that command has a value by the time you print it out.

Variable scope

If statements introduce a new concept called scope. Scope is the extent to which a variable can be seen throughout your code. Dart uses curly braces as the boundary markers in determining a variable’s scope. If you define a variable inside a pair of curly braces, then you’re not allowed to use that variable outside of those braces.

To see how this works, replace the main function with the following code:

Control Flow in Dart

Note the following points:

  • There are three variables: global, local and insideIf.
  • There are two sets of nested curly braces, one for the body of main and one for the body of the if statement.
  • The variable named global is defined outside of the main function and outside of any curly braces. That makes it a top-level variable, which means it has a global scope. That is, it’s visible everywhere in the file.
    You can see print (global) references it both in the if statement body and in the main function body.
  • The variable named local is defined inside the body of the main function. This makes it a local variable and it has local scope. It’s visible inside the main function including inside the if statement, but local is not visible outside of the main function.
  • The variable named insideIf is defined inside the body of the if statement. That means insideIf is only visible within the scope defined by the if statement’s curly braces.

Since the final part statement is trying to reference insideIf outside of its scope, Dart gives you the following error.

Undefined name 'insideIf'

Delete that final print statement to get rid of the error.

As a general rule, you should make your variables have the smallest scope that they can get by with. Another way to say that is, define your variables as close to where you use them as possible. doing so makes their purpose more clear, and it also prevents you from using changing them in places where you shouldn’t .

The ternary conditional operator

You’ve worked with operators that have two operands. For example, in (myAge > 16), the two operands are myAge and 16. But there’s also an operator that takes three operands: the ternary conditional operator. It’s strangely related to if statements – you’ll see why this is in just a bit.

Let’s take an example of telling a student whether their exam score is passing or not. Write an if-else statement to achieve this:

Control Flow in Dart

That’s pretty clear, but it’s a lot of code. Wouldn’t it be nice if you could shrink this to just a couple of lines? Well, you can, thanks to the ternary conditional operator!

The ternary conditional operator takes a conditions and returns one of two values, depending on whether the condition is true or false. The syntax is as follows:

(condition) ? valueIfTrue : valueIfFalse;

Use the ternary conditional operator to rewrite your long code block above, like so:

Control Flow in Dart

In this example, the condition to evaluate is score >= 60. If the condition is true, the result assigned to message will be ‘You passed’; if the condition is false, the result will instead be ‘You failed’. Since 83 is greater than 60, the student receives good news.

The ternary conditional operator makes basic if-else statements much more compact, which is turn can make your code more readable.

However, for situations where using this operator makes your code less readable, then stick with the full if-else statement. Readability is always more important than fancy programming tricks that give the same result.

Check out more articles related to Dart Tutorial:

String in Dart

Type Inference Variable in Dart | Dart Tutorial #2

Dart Tutorial is for Beginners from Scratch #1

3 thoughts on “Control Flow in Dart

  1. Pingback: Loop in Dart
  2. Pingback: Dart OOPs Concept

Leave a Reply

Your email address will not be published. Required fields are marked *

Back To Top