Dart Basics

Get an introduction to the basics of the Dart programming language, used for development with the Flutter SDK for mobile, web and beyond. By Jonathan Sande.

4.6 (19) · 2 Reviews

Download materials
Save for later
Share
You are currently viewing page 4 of 5 of this article. Click here to view the first page.

Collections

Collections are useful for grouping related data. Dart includes several different types of collections, but this tutorial will cover the two most common ones: List and Map.

Lists

Lists in Dart are similar to arrays in other languages. You use them to maintain an ordered list of values. Lists are zero-based, so the first item in the list is at index 0:

List of desserts

Here’s a list of different desserts:

List desserts = ['cookies', 'cupcakes', 'donuts', 'pie'];

You enclose the elements of a list in square brackets: [ ]. You use commas to separate the elements.

At the beginning of the line, you can see that the type is List. You’ll notice there is no type included. Dart infers that list has type List.

Here’s a list of integers:

final numbers = [42, -1, 299792458, 100];

Click numbers in DartPad and you’ll see that Dart recognizes the type as a List of int.

Dart List of int

Working With List Elements

To access the elements of a list, use subscript notation by putting the index number between square brackets after the list variable name. For example:

final firstDessert = desserts[0];
print(firstDessert); // cookies

Since list indices are zero-based, desserts[0] is the first element of the list.

Add and remove elements with add and remove respectively:

desserts.add('cake');
print(desserts); 
// [cookies, cupcakes, donuts, pie, cake]

desserts.remove('donuts');
print(desserts); 
// [cookies, cupcakes, pie, cake]

Run the code to see the results.

Dart list add and remove methods

Earlier, you learned about for loops. Dart’s for-in loop that works especially well with lists. Try it out:

for (final dessert in desserts) {
  print('I love to eat $dessert.');
}
// I love to eat cookies.
// I love to eat cupcakes.
// I love to eat pie.
// I love to eat cake.

You don’t need to use an index. Dart just loops through every element of desserts and assigns it each time to a variable named dessert.

Getting hungry? Well, you can’t have any dessert until you’ve finished your vegetables. :]

Maps

When you want a list of paired values, Map is a good choice. Dart Maps are similar to dictionaries in Swift and maps in Kotlin.

Dart maps

Here’s an example of a map in Dart:

Map<String, int> calories = {
  'cake': 500,
  'donuts': 150,
  'cookies': 100,
};

You surround Maps with curly braces { }. Use commas to separate a map’s elements.

Elements of a map are called key-value pairs, where the key is on the left of a colon and the value is on the right.

You find a value by using the key to look it up, like this:

final donutCalories = calories['donuts'];
print(donutCalories); // 150

The key, 'donuts', is inside the square brackets after the map name. In this case, it maps to a value of 150.

Click donutCalories in DartPad and you’ll see that the inferred type is int? rather than int. That’s because, if a map doesn’t contain the key that you’re looking up, it’ll return a null value.

Dart Map output

Add a new element to a map by specifying the key and assigning it a value:

calories['brownieFudgeSundae'] = 1346;
print(calories);
// {cake: 500, donuts: 150, cookies: 100, brownieFudgeSundae: 1346}

Run that code and you’ll see the map printed in horizontal format with your new dessert at the end.

Functions

Functions let you package multiple related lines of code into a single body. You then summon the function to avoid repeating those lines of code throughout your Dart app.

Dart function

A function consists of the following elements:

  • Return type
  • Function name
  • Parameter list in parentheses
  • Function body enclosed in brackets

Defining Functions

The code you’re turning into a function goes inside the curly brackets. When you call the function, you pass in arguments that match the types of the parameters of the function.

Next, you’ll write a new function in DartPad that will check to see if a given string is banana:

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

The function uses return to return a bool. The argument you pass to the function determines the bool.

This function will always return the same value type for any given input. If a function doesn’t need to return a value, you can set the return type to void. main does this, for example.

Working With Functions

You can call the function by passing in a string. You might then pass the result of that call to print:

void main() {
  var fruit = 'apple';
  print(isBanana(fruit)); // false
}

Nesting Functions

Typically, you define functions either outside other functions or inside Dart classes. However, you can also nest Dart functions. For example, you can nest isBanana inside main.

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

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

You can also change the argument you to a function, then call it again with the new argument:

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

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

Optional Parameters

If a parameter to a function is optional, you can surround it with square brackets and make the type nullable:

String fullName(String first, String last, [String? title]) {
  if (title == null) {
    return '$first $last';
  } else {
    return '$title $first $last';
  }
}

In this function, title is optional. It will default to null if you don’t specify it.

Now, 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

Named Parameters and Default Values

When you have multiple parameters, it can be confusing to remember which is which. Dart solves this problem with named parameters, which you get by surrounding the parameter list with curly brackets: { }.

These parameters are optional by default, but you can give them default values or make them required by using the required keyword:

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

value is required, while min and max are optional with default values.

With named parameters, you can pass in arguments in a different order by supplying the parameter names with a colon:

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

You can 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.

Named and default parameters