Lesson 22 min

Data Types Deep Dive

00:00 / 00:00

Data Types Deep Dive

Dart is a strongly-typed language, meaning every value has a type, and the compiler uses this information to ensure safety and prevent runtime crashes. In this lesson, we will explore both primitive and advanced types in Dart.


Primitive Data Types

Primitive types are the building blocks of data representation in Dart.

1. Numbers (int, double, num)

Dart represents numbers in three ways:

  • int: Integer values no larger than 64 bits. (e.g., 1, 42, -10).
  • double: 64-bit double-precision floating-point numbers. (e.g., 3.14, -0.5).
  • num: A type that can hold either an int or a double. Both int and double are subtypes of num.
dart
void main() { int age = 25; double price = 19.99; num rating = 4.5; // Can be reassigned to an int rating = 5; // Valid }

2. Strings (String)

A String represents a sequence of characters. Dart strings are UTF-16 code units. You can use single or double quotes to declare strings.

dart
void main() { String firstName = 'Alice'; String lastName = "Smith"; // String Interpolation String fullName = "$firstName $lastName"; print("Length: ${fullName.length}"); // Multi-line Strings using triple quotes String message = """ This is a multi-line string. """; // Raw Strings (prefixed with r, ignores escape characters) String path = r"C:\programfiles\dart"; }

3. Booleans (bool)

Booleans represent logical truth values: true and false. In Dart, only boolean objects can evaluate to true in condition checks (no JS-like "truthy" or "falsy" concepts for strings/numbers).

dart
void main() { bool isPremium = true; if (isPremium) { print("Welcome VIP!"); } }

Special & Advanced Data Types

Dart provides several specialized types for scenarios where the compile-time type system is too restrictive or when representing absence of values.

1. dynamic

The dynamic type disables static type checking. A variable declared as dynamic can hold any value, and you can reassign it to values of completely different types.

[!WARNING] Using dynamic removes type safety. Avoid it unless interacting with JSON or dynamic external APIs.

dart
void main() { dynamic data = "Hello"; data = 42; // OK data = true; // OK }

2. Object

The Object class is the root class of the Dart class hierarchy, except for Null. Every non-null class in Dart inherits from Object. Unlike dynamic, Object still maintains static type checking.

dart
void main() { Object obj = "Hello"; // obj.length; // Compile Error: The getter 'length' isn't defined for the class 'Object'. if (obj is String) { print(obj.length); // OK: Type promotion to String } }

3. Null

The Null type has exactly one value: null. It is used to represent the absence of a value. Under sound null safety, standard types cannot hold null unless explicitly declared as nullable.

dart
void main() { String? nullableString = null; // OK because of '?' // String normalString = null; // Compile Error! }

4. Never

The Never type represents a type that can never be evaluated. It is used to indicate that a function will never return normally (e.g., it always throws an exception or loops indefinitely).

dart
Never throwError() { throw Exception("An error occurred"); }

Type Checking and Casts

You can inspect and convert types at runtime using operators:

  • is: Returns true if the object has the specified type.
  • is!: Returns true if the object does not have the specified type.
  • as: Casts an object to a specific type.
dart
void main() { num value = 10; if (value is int) { print("It's an integer!"); } // Explicit casting double doubleVal = value as double; // Throws TypeError if value is not double! }

Summary

  • Use int and double for numeric calculations.
  • Use String with interpolation for formatting text.
  • Use bool for conditions.
  • Minimize the use of dynamic to preserve type safety.
  • Leverage the is operator for runtime type validation.
WhatsApp