Dart Basics : Data Types and Containers
Introduction
Today, we’ll explore the fundamentals of the Dart language, the backbone of Flutter, developed and supported by Google.
This beginner-friendly introduction to Dart is perfect for those just starting with the language. Whether you’re new to Dart or prefer learning through reading rather than videos, we strongly recommend beginning here.
Numbers in Dart
Int: Stores whole numbers without a decimal point.
Double: Stores numbers with a decimal point.
Num: Can hold both integer and floating-point values.
BigInt: Handles very large integer values exceeding the standard int
limits.
//* Example
int age = 30;
int year = 2023;
int negativeNumber = -15;
double price = 19.99;
double pi = 3.1415;
double negativeDouble = -7.5;
num count = 10; // Initially an integer
count = 10.5; // Now a double
//* Use num when your code needs to handle both int and double types, and you want to avoid writing separate logic for each.
BigInt bigNumber = BigInt.parse('123456789012345678901234567890');
//* BigInt needs a special constructor to assign a large value
Quick Tip
Int, Double, Num, BigInt, and other data types each come with a number of constructors or methods or properties that you can use in your IDE (eg. VSCODE) by typing a “.” (dot) after a variable
Let’s try
Declare a variable with Num and check some method/property it contains
String
A Dart string (String object) holds a sequence of UTF-16 code units. You can use either single or double quotes to create a string.
//Example
var s1 = 'Single quotes work well for string literals.';
var s2 = "Double quotes work just as well.";
var s3 = 'It\'s easy to escape the string delimiter.';
var s4 = "It's even easier to use the other delimiter.";
Beyond Very Basic ( String)
The String class defines such methods as split(), contains(), startsWith(), endsWith(), and more.
Let’s try
1. Create a string and use the dot(.) method to find if a string starts with a particular word, or ends with or contains.
2. Declare a string and use that variable in another string to print both together. (using $)
3. Concatenate two strings ( using +)
Booleans (bool)
The simple true or false.
//Example
bool hasItem = true;
bool hasOffer = false;
Let’s try
Create a program that checks if a user is eligible to vote (use bool to store isCitizen and isAbove18).
Declare bool variable and assign true/false and use it with if-else ( if else is on a different page)
Records
Dart’s Records data type allows for grouping multiple values into a single composite object without needing to create a class or struct.
Records are lightweight, immutable, and positional, making them ideal for returning multiple values from a function or bundling related values together in a concise way.
How to Write
var recordName = (value1, value2, value3, …);
Accessing Values:
You can access the individual values using positional accessors like .item1, .item2, etc.
//Example
var record = ('John', 25, true);
print(record.item1); // It will print in console John
print(record.item2); // It will print in console 25
print(record.item3); // It will print in console true
//* Named Records:
//* Dart also allows naming some or all values in a record, improving readability.
var namedRecord = (name: 'Alice', age: 30);
print(namedRecord.name); // Alice
print(namedRecord.age); // 30
//* Mixed Named and Positional:
//* You can mix named and positional values.
var mixedRecord = ('Flutter', version: 3.3);
print(mixedRecord.item1); // Flutter
print(mixedRecord.version); // 3.3
Quick Tip
1. Records are immutable; once created, their values cannot be changed.
2. Unlike lists, they have a fixed size and cannot be dynamically resized.
Let’s try
1. Create a record to store your favorite book’s title, author, and publication year. Access and print each value.
2. Use named records to represent a user’s profile with name, email, and isVerified values. Print the user’s email.
Lists in Dart (List, also known as Arrays)
A List in Dart is an ordered collection of objects, where each object is identified by an index starting from zero. Lists can be either fixed-length or growable. They are highly flexible and come with various built-in methods for easy manipulation.
Declaring Lists
1. Fixed-Length List
The size is defined at the time of declaration and cannot be changed later.
2. var fixedList = List.filled(5, 0); // A fixed-length list of size 5, initialized with 0
3. Growable List
The size is dynamic, and elements can be added or removed.
var growableList = [1, 2, 3];
growableList.add(4); // Adding an element
//Example
var fixedList = List.filled(3, 0);
print(fixedList); // [0, 0, 0]
var growableList = [1, 2, 3];
growableList.add(4); // Adding an element
print(growableList); // [1, 2, 3, 4]
growableList.removeAt(1); // Removing the element at index 1
print(growableList); // [1, 3, 4]
Common Methods and Properties
1. add(): Adds an element to the end of the list.
2. insert(index, value): Inserts an element at the specified index.
3.remove(value): Removes the first occurrence of the specified value.
4.removeAt(index): Removes the element at the specified index.
5.length: Returns the number of elements in the list.
6. contains(value): Checks if the list contains a specific value.
7. indexOf(value): Returns the index of the first occurrence of the value.
8. isEmpty: Returns true if the list has no elements.
9. isNotEmpty: Returns true if the list contains at least one element.
Let’s try
1. Create a fixed-length list and update a value
2. Check if a growable list contains a specific value
3. Find the index of an element in a list
This introduction covers the essential operations for working with lists in Dart.
Set
A Set in Dart is an unordered collection of unique items. Unlike Lists, sets do not allow duplicate elements and do not maintain the order of elements.
Declaring Sets
Using a Set Constructor
A constructor in Dart is a special method used to initialize objects when they are created. It typically sets up initial values for instance variables or performs other setup tasks.
var names = <String>{};
names.add(‘Alice’);
names.add(‘Bob’);
Using Set Literals
Literals are fixed values that appear directly in your code.
var numbers = {1, 2, 3, 4};
Empty Set To define an empty set, you must specify the type:
var emptySet = <int>{};
//Example
var fruits = {'Apple', 'Banana', 'Mango'};
print(fruits); // {Apple, Banana, Mango}
fruits.add('Orange'); // Adding a new element
print(fruits); // {Apple, Banana, Mango, Orange}
fruits.add('Apple'); // Adding a duplicate element (will be ignored)
print(fruits); // {Apple, Banana, Mango, Orange}
Common Methods and Properties
1. add(value): Adds a new value to the set.
2. addAll(iterable): Adds all elements from an iterable (e.g., list) to the set.
3. remove(value): Removes a specific value from the set.
4. contains(value): Checks if the set contains a specific value.
5. intersection(otherSet): Returns a new set containing the common elements of two sets.
6. union(otherSet): Returns a new set containing all unique elements of both sets.
7. difference(otherSet): Returns a new set with elements from the current set that are not in the other set.
8. length: Returns the number of elements in the set.
9. isEmpty: Checks if the set is empty.
10. isNotEmpty: Checks if the set is not empty.
Let’s try
1. Create a set and perform a union operation.
2. Find the intersection of two sets
3. Remove a value from a set.
Hint:
var setA = {1, 2, 3};
var setB = {3, 4, 5};
var unionSet = setA.union(setB);
print(unionSet); // {1, 2, 3, 4, 5}
Map
A Map in Dart is a collection of key-value pairs. Each key in a map is unique, and it maps to a single value. Maps are useful for storing data where each value is associated with a unique key.
Declaring Maps
Using Map Literals
var person = {
‘name’: ‘John’,
‘age’: 30,
‘isEmployed’: true
};
Using the Map Constructor
var emptyMap = Map(); // Creates an empty map
var person = Map<String, dynamic>();
person[‘name’] = ‘Alice’;
person[‘age’] = 25;
//Example
var capitals = {
'USA': 'Washington, D.C.',
'India': 'New Delhi',
'France': 'Paris'
};
print(capitals['India']); // New Delhi
capitals['Germany'] = 'Berlin'; // Adding a new key-value pair
print(capitals); // {USA: Washington, D.C., India: New Delhi, France: Paris, Germany: Berlin}
capitals.remove('France'); // Removing a key-value pair
print(capitals); // {USA: Washington, D.C., India: New Delhi, Germany: Berlin}
Common Methods and Properties
1. [ ]: Access or modify the value associated with a key.
2. addAll(Map other): Adds all key-value pairs from another map.
3. containsKey(key): Checks if the map contains a specific key.
4. containsValue(value): Checks if the map contains a specific value.
5. remove(key): Removes the key-value pair associated with the key.
6. keys: Returns an iterable of all keys in the map.
7. values: Returns an iterable of all values in the map.
8. length: Returns the number of key-value pairs.
9. isEmpty: Returns true if the map is empty.
10. isNotEmpty: Returns true if the map is not empty.
Let’s try
1. Create a map and check if a key exists
2. Iterate over keys and values
3. Merge two maps
Runes or grapheme (Runes; often replaced by the characters API)
In Dart, Runes represent Unicode code points. Unicode defines a unique numeric value for every character, which allows consistent encoding and representation across different systems.
Dart provides the Runes class to work with these Unicode code points, although it is often replaced by the more modern characters API for handling complex characters.
Declaring Runes
Using String Literals You can include Unicode characters in strings using the \u or \u{} escape sequences:
var heart = ‘\u2665’; // Unicode for ♥
var smiley = ‘\u{1F600}’; // Unicode for 😀
print(heart); // ♥
print(smiley); // 😀
Using Runes Class
var input = Runes(‘\u2665 \u{1F600}’);
print(String.fromCharCodes(input)); // ♥ 😀
//Example
var heart = '\u2665'; // Unicode for ♥
var smiley = '\u{1F600}'; // Unicode for 😀
print(heart); // ♥
print(smiley); // 😀
var runes = Runes('I \u2665 Dart \u{1F600}');
print(String.fromCharCodes(runes)); // I ♥ Dart 😀
Characters API (Recommended for Modern Use)
The characters API provides more advanced handling of Unicode strings, especially when dealing with complex characters like emojis or multi-code point sequences.
Using Characters API
import ‘package:characters/characters.dart’;
void main() {
var complexString = ‘👨👩👧👦’; // Family emoji, a sequence of multiple code points
print(complexString.length); // 11 (incorrect for characters)
print(complexString.characters.length); // 1 (correct count of characters)
}
Common Methods and Properties
1. Runes(String): Creates a Runes object from a string with Unicode escape sequences.
2. String.fromCharCodes(runes): Converts a Runes object back to a string.
Let’s try
1. Convert Unicode code points to a string:
2. Use Characters API for complex characters:
Symbol
A Symbol in Dart is an object that represents the name of an identifier in a Dart program. Symbols are particularly useful when you need to refer to identifiers (like variable or method names) in a dynamic or reflective context without using string literals. They ensure that identifiers are referenced correctly and efficiently.
A Symbol object represents an operator or identifier declared in a Dart program. You might never need to use symbols, but they’re invaluable for APIs that refer to identifiers by name because minification changes identifier names but not identifier symbols.
Declaring Symbols
1. Using the Symbol Constructor
Symbol symbolName = Symbol(‘identifierName’);
2. Using Symbol Literals (#) The more common way to create a Symbol is by using the # prefix:
var symbolName = #identifierName;
void main() {
var symbol1 = Symbol(‘myVariable’);
var symbol2 = #myVariable; // Equivalent to symbol1
print(symbol1); // Symbol(“myVariable”)
print(symbol2); // Symbol(“myVariable”)
// Comparing two symbols
print(symbol1 == symbol2); // true
}
Use Cases of Symbols
Symbols are primarily used in:
1. Reflection: When working with the dart:mirrors library, you can use Symbols to dynamically refer to class members.
2. Metadata Annotations: To identify named parameters or other constructs without using string literals.
Common Methods and Properties
Symbols themselves do not have many built-in methods, as they are primarily used for reference purposes. However, their utility becomes evident when used alongside reflection tools.
Let’s try
1. Create and print a symbol.
2. Compare two symbols.
3. Use a symbol in a reflective context.
This introduction covers the basics of Symbols in Dart, focusing on their creation and common use cases.
//Example
import 'dart:mirrors';
class Person {
String name = 'John Doe';
}
void main() {
var person = Person();
var instanceMirror = reflect(person);
var symbol = #name;
print(instanceMirror.getField(symbol).reflectee); // John Doe
}
Urshimo Anrahm
November 25, 2024 @ 2:20 am
This is dope 🔥