Dart Basic Syntax & Types – Complete Reference Cheatsheet

Introduction

Dart is a client-optimized programming language developed by Google, primarily used for building mobile, desktop, server, and web applications. It’s the foundation of Flutter framework and known for its strong typing system, null safety, and modern syntax. Understanding Dart’s basic syntax and type system is crucial for effective Flutter development and general Dart programming.

Why Dart Matters:

  • Powers Flutter for cross-platform development
  • Compiles to native ARM & x64 machine code
  • Features null safety and sound type system
  • Supports both AOT and JIT compilation
  • Easy to learn for developers coming from Java, C#, or JavaScript

Core Concepts & Principles

1. Everything is an Object

  • All values in Dart are objects, including numbers, functions, and null
  • Every object is an instance of a class that derives from Object

2. Static Type System with Type Inference

  • Dart uses static typing but can infer types automatically
  • Variables can be explicitly typed or use var, dynamic, or Object

3. Null Safety

  • Dart 2.12+ enforces null safety by default
  • Types are non-nullable unless explicitly marked with ?

4. Sound Type System

  • Runtime type checks match static type analysis
  • Helps prevent runtime errors and improves performance

Basic Syntax Structure

Program Structure

// Import statements
import 'dart:core';

// Main function (entry point)
void main() {
  print('Hello, Dart!');
}

// Function definition
String greetUser(String name) {
  return 'Hello, $name!';
}

Comments

// Single-line comment

/*
  Multi-line comment
  Can span multiple lines
*/

/// Documentation comment
/// Used for generating documentation

Semicolons and Blocks

  • Statements end with semicolons (;)
  • Code blocks use curly braces ({})
  • Indentation is by convention (2 spaces recommended)

Variable Declaration & Assignment

Declaration Methods

MethodDescriptionExampleWhen to Use
varType inferred from assignmentvar name = 'John';When type is obvious
finalRuntime constant (set once)final time = DateTime.now();For values set once at runtime
constCompile-time constantconst pi = 3.14159;For compile-time known values
lateLate initializationlate String description;For non-nullable vars initialized later
Explicit typeDirect type specificationString name = 'John';For clarity or when needed

Variable Examples

// Type inference
var count = 42;          // int
var message = 'Hello';   // String
var items = <String>[];  // List<String>

// Explicit typing
int age = 25;
String username = 'dart_dev';
bool isActive = true;

// Constants
final currentTime = DateTime.now();  // Runtime constant
const maxRetries = 3;               // Compile-time constant

// Late initialization
late String configValue;
void initConfig() {
  configValue = 'initialized';
}

Data Types

Primitive Types

Numbers

// Integers
int wholeNumber = 42;
int hexValue = 0xFF;
int negative = -10;

// Doubles (floating-point)
double decimal = 3.14159;
double scientific = 1.42e5;
double negative = -2.5;

// num (supertype of int and double)
num flexible = 42;      // Can be int or double
flexible = 3.14;        // Now it's double

Strings

// String literals
String single = 'Single quotes';
String double = "Double quotes";
String multiline = '''
Multiple
lines
here''';

// String interpolation
String name = 'Alice';
int age = 30;
String message = 'Hello $name, you are $age years old';
String expression = 'Next year: ${age + 1}';

// Raw strings (no interpolation)
String raw = r'Raw string with $variable and \n';

Booleans

bool isTrue = true;
bool isFalse = false;
bool fromExpression = 5 > 3;  // true

// Null safety - nullable boolean
bool? maybeTrue = null;

Collection Types

Lists (Arrays)

// List declaration
List<int> numbers = [1, 2, 3, 4, 5];
var fruits = ['apple', 'banana', 'orange'];
List<String> empty = [];

// List operations
numbers.add(6);                    // Add element
numbers.addAll([7, 8, 9]);        // Add multiple
numbers.insert(0, 0);             // Insert at index
numbers.remove(5);                // Remove value
numbers.removeAt(0);              // Remove at index

// List properties
print(numbers.length);            // Get length
print(numbers.isEmpty);           // Check if empty
print(numbers.first);             // First element
print(numbers.last);              // Last element

Sets

// Set declaration
Set<String> colors = {'red', 'green', 'blue'};
var uniqueNumbers = <int>{1, 2, 3, 4, 5};
Set<String> empty = {};

// Set operations
colors.add('yellow');             // Add element
colors.addAll(['purple', 'pink']); // Add multiple
colors.remove('red');             // Remove element
bool hasBlue = colors.contains('blue'); // Check membership

Maps (Key-Value Pairs)

// Map declaration
Map<String, int> scores = {'Alice': 95, 'Bob': 87, 'Charlie': 92};
var userInfo = {
  'name': 'John',
  'age': 30,
  'email': 'john@example.com'
};

// Map operations
scores['David'] = 88;             // Add/update entry
scores.remove('Bob');             // Remove entry
bool hasAlice = scores.containsKey('Alice'); // Check key
List<String> names = scores.keys.toList();   // Get keys
List<int> values = scores.values.toList();   // Get values

Null Safety

Nullable vs Non-nullable Types

TypeDeclarationDescription
Non-nullableString nameCannot be null, must be initialized
NullableString? nameCan be null or contain a String value
Latelate String nameNon-nullable but initialized later

Null Safety Operators

// Null-aware operators
String? nullableName = null;

// Null-aware access (?.)
int? length = nullableName?.length;

// Null coalescing (??)
String displayName = nullableName ?? 'Unknown';

// Null assertion (!)
String definitelyNotNull = nullableName!; // Throws if null

// Null-aware assignment (??=)
nullableName ??= 'Default Name'; // Assign only if null

Null Safety Best Practices

// Good: Check before use
String? getUserName() => null;

void printUserName() {
  String? name = getUserName();
  if (name != null) {
    print('User: $name');
  }
}

// Good: Use null coalescing
String getDisplayName(String? name) {
  return name ?? 'Anonymous';
}

// Good: Late initialization for non-nullable
class User {
  late String name;
  
  void initialize(String userName) {
    name = userName;
  }
}

Operators

Arithmetic Operators

int a = 10, b = 3;

int sum = a + b;        // Addition: 13
int diff = a - b;       // Subtraction: 7
int product = a * b;    // Multiplication: 30
double quotient = a / b; // Division: 3.333...
int intDiv = a ~/ b;    // Integer division: 3
int remainder = a % b;  // Modulo: 1

// Increment/Decrement
a++;  // Post-increment
++a;  // Pre-increment
b--;  // Post-decrement
--b;  // Pre-decrement

Comparison Operators

bool equal = a == b;      // Equal to
bool notEqual = a != b;   // Not equal to
bool greater = a > b;     // Greater than
bool less = a < b;        // Less than
bool greaterEq = a >= b;  // Greater than or equal
bool lessEq = a <= b;     // Less than or equal

Logical Operators

bool x = true, y = false;

bool and = x && y;        // Logical AND
bool or = x || y;         // Logical OR
bool not = !x;            // Logical NOT

Assignment Operators

int value = 10;

value += 5;   // value = value + 5
value -= 3;   // value = value - 3
value *= 2;   // value = value * 2
value ~/= 4;  // value = value ~/ 4
value %= 3;   // value = value % 3

Control Flow

Conditional Statements

If-Else

int score = 85;

if (score >= 90) {
  print('Grade: A');
} else if (score >= 80) {
  print('Grade: B');
} else if (score >= 70) {
  print('Grade: C');
} else {
  print('Grade: F');
}

// Ternary operator
String result = score >= 60 ? 'Pass' : 'Fail';

Switch Statement

String grade = 'B';

switch (grade) {
  case 'A':
    print('Excellent!');
    break;
  case 'B':
    print('Good job!');
    break;
  case 'C':
    print('Fair');
    break;
  default:
    print('Keep trying!');
}

Loops

For Loop

// Traditional for loop
for (int i = 0; i < 5; i++) {
  print('Count: $i');
}

// For-in loop
List<String> names = ['Alice', 'Bob', 'Charlie'];
for (String name in names) {
  print('Hello, $name!');
}

// For-each method
names.forEach((name) => print('Hi, $name!'));

While Loop

int count = 0;
while (count < 5) {
  print('Count: $count');
  count++;
}

// Do-while loop
int number = 0;
do {
  print('Number: $number');
  number++;
} while (number < 3);

Functions

Function Declaration & Types

Function TypeSyntaxExample
BasicreturnType functionName(parameters) { }int add(int a, int b) => a + b;
ArrowreturnType functionName(parameters) => expression;String greet(String name) => 'Hello $name';
Anonymous(parameters) { } or (parameters) => expressionvar multiply = (int x, int y) => x * y;
Optional PositionalfunctionName([optional])void log(String msg, [String level = 'info'])
Named ParametersfunctionName({required/optional})void createUser({required String name, int? age})

Function Examples

// Basic function
int calculateArea(int length, int width) {
  return length * width;
}

// Arrow function
double calculateCircumference(double radius) => 2 * 3.14159 * radius;

// Optional positional parameters
void greetUser(String name, [String greeting = 'Hello']) {
  print('$greeting, $name!');
}

// Named parameters
void createAccount({
  required String username,
  required String email,
  String? phone,
  bool isActive = true
}) {
  print('Account created: $username');
}

// Higher-order functions
List<int> processNumbers(List<int> numbers, int Function(int) processor) {
  return numbers.map(processor).toList();
}

// Usage examples
greetUser('Alice');                    // Uses default greeting
greetUser('Bob', 'Hi');               // Custom greeting
createAccount(username: 'john', email: 'john@email.com');
var doubled = processNumbers([1, 2, 3], (x) => x * 2);

Type System Deep Dive

Type Checking & Casting

// Type checking
dynamic value = 'Hello';
if (value is String) {
  print('Length: ${value.length}'); // Smart cast
}

// Type casting
var number = value as String; // Throws if not String

// Safe casting
String? safeString = value as String?;

Generic Types

// Generic class
class Box<T> {
  T content;
  Box(this.content);
  
  T getContent() => content;
}

// Generic function
T getFirstElement<T>(List<T> list) {
  return list.first;
}

// Usage
Box<String> stringBox = Box('Hello');
Box<int> intBox = Box(42);
String firstFruit = getFirstElement(['apple', 'banana']);

Type Aliases

// Type alias for complex types
typedef StringProcessor = String Function(String);
typedef UserMap = Map<String, dynamic>;

// Usage
StringProcessor upperCase = (s) => s.toUpperCase();
UserMap user = {'name': 'Alice', 'age': 30};

Common Challenges & Solutions

Challenge 1: Null Safety Migration

Problem: Converting legacy code to null-safe Dart Solution:

// Before (legacy)
String name;

// After (null-safe)
String? name;          // If can be null
late String name;      // If initialized later
String name = '';      // If has default value

Challenge 2: Type Inference Confusion

Problem: Unclear when to use var vs explicit types Solution:

// Use var when type is obvious
var names = <String>['Alice', 'Bob'];  // Clear it's List<String>

// Use explicit types for clarity
Map<String, List<int>> complexData = {}; // Complex type, be explicit

// Use dynamic sparingly
dynamic jsonData = parseJson(response);  // When type truly unknown

Challenge 3: Collection Initialization

Problem: Choosing between different collection types Solution:

// Use List for ordered, indexed access
List<String> orderedItems = ['first', 'second', 'third'];

// Use Set for unique values
Set<String> uniqueTags = {'dart', 'flutter', 'mobile'};

// Use Map for key-value relationships
Map<String, int> inventory = {'apples': 10, 'bananas': 15};

Challenge 4: Function Parameter Confusion

Problem: When to use positional vs named parameters Solution:

// Use positional for obvious, few parameters
int add(int a, int b) => a + b;

// Use named for many parameters or unclear meaning
void createUser({
  required String name,
  required String email,
  int age = 0,
  bool isActive = true
}) { }

Best Practices & Tips

Code Style & Conventions

  • Use lowerCamelCase for variables, methods, and parameters
  • Use UpperCamelCase for classes, enums, and typedefs
  • Use lowercase_with_underscores for libraries and file names
  • Prefer final over var when the value won’t change
  • Use const for compile-time constants

Performance Tips

// Good: Use const constructors when possible
const widget = Text('Hello');

// Good: Use string interpolation instead of concatenation
String message = 'Hello $name, today is $date';

// Good: Use collection literals
var list = <String>[]; // Instead of List<String>()
var map = <String, int>{}; // Instead of Map<String, int>()

// Good: Use cascade notation for multiple operations
var paint = Paint()
  ..color = Colors.blue
  ..strokeWidth = 2.0
  ..style = PaintingStyle.stroke;

Error Handling

// Use try-catch for error handling
try {
  int result = int.parse('not a number');
} catch (e) {
  print('Error: $e');
} finally {
  print('Cleanup code here');
}

// Use specific exception types when possible
try {
  // risky operation
} on FormatException catch (e) {
  print('Format error: $e');
} on Exception catch (e) {
  print('General error: $e');
}

Memory Management

// Good: Close resources properly
class DatabaseConnection {
  void close() {
    // cleanup code
  }
}

// Good: Use weak references for callbacks to avoid memory leaks
void setupCallback(void Function() callback) {
  // Store callback reference appropriately
}

Quick Reference Tables

Common String Methods

MethodDescriptionExample
lengthGet string length'hello'.length // 5
isEmptyCheck if empty''.isEmpty // true
contains()Check substring'hello'.contains('ell') // true
startsWith()Check prefix'hello'.startsWith('he') // true
endsWith()Check suffix'hello'.endsWith('lo') // true
substring()Extract substring'hello'.substring(1, 4) // 'ell'
split()Split into list'a,b,c'.split(',') // ['a','b','c']
trim()Remove whitespace' hello '.trim() // 'hello'
toUpperCase()Convert to uppercase'hello'.toUpperCase() // 'HELLO'
toLowerCase()Convert to lowercase'HELLO'.toLowerCase() // 'hello'

Common List Methods

MethodDescriptionExample
add()Add single elementlist.add('item')
addAll()Add multiple elementslist.addAll(['a', 'b'])
insert()Insert at indexlist.insert(0, 'first')
remove()Remove by valuelist.remove('item')
removeAt()Remove by indexlist.removeAt(0)
indexOf()Find index of elementlist.indexOf('item')
contains()Check if containslist.contains('item')
sort()Sort in placelist.sort()
reversedGet reversed viewlist.reversed.toList()
map()Transform elementslist.map((x) => x * 2)

Resources for Further Learning

Official Documentation

  • Dart Language Tour: https://dart.dev/guides/language/language-tour
  • Dart API Reference: https://api.dart.dev/
  • Effective Dart Guide: https://dart.dev/guides/language/effective-dart

Interactive Learning

  • DartPad: https://dartpad.dev/ (Online Dart editor)
  • Dart Codelabs: https://dart.dev/codelabs
  • Flutter Widget of the Week: https://www.youtube.com/playlist?list=PLjxrf2q8roU23XGwz3Km7sQZFTdB996iG

Books & Courses

  • “Dart in Action” by Chris Buckett
  • “Flutter in Action” by Eric Windmill
  • Dart/Flutter courses on Udemy, Coursera, and YouTube

Community Resources

  • Dart GitHub: https://github.com/dart-lang/dart
  • Stack Overflow: Tag questions with dart
  • Reddit: r/dartlang and r/FlutterDev
  • Discord: Flutter Community Discord Server

Tools & IDEs

  • VS Code: With Dart and Flutter extensions
  • Android Studio/IntelliJ: With Dart and Flutter plugins
  • Vim/Emacs: With appropriate Dart language support
  • Online IDEs: CodePen, Repl.it with Dart support

This cheatsheet covers Dart’s fundamental syntax and type system. For advanced topics like asynchronous programming, object-oriented features, and Flutter-specific concepts, refer to the additional resources provided.

Scroll to Top