Top features of Dart3: Introduction
Tags: blogging, article, development
Published: 2024-05-10 06:25:41

---
title: Top features of Dart3: Introduction
published: true
description: 
tags: blogging,,article,,development
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xpz90dm7e705tm1cq9ms.png
#Use a ratio of 100:42 for best results.
#published_at: 2024-05-09 12:17 +0000
---


**1. Pattern Matching and Enhanced Control Flow**

* **Switch Expressions with Patterns:** Go beyond simple value comparisons in switch statements. Use patterns to match complex data structures and their properties:
```dart
enum Season { spring, summer, autumn, winter }

String describeSeason(Season season) {
  switch (season) {
    case Season.spring:
      return 'Time for flowers!';
    case Season.summer:
      return 'Get ready for the beach!';
    case Season.autumn:
      return 'Leaves are changing!';
    case Season.winter:
      return 'Bundle up!';
  }
}

void main() {
  print(describeSeason(Season.summer)); // Output: Get ready for the beach!
}
```

* **If-Case Statements:** Similar to pattern matching in switch, you can now use if statements with case clauses for more concise conditional logic:

```dart
String getGreeting(int timeOfDay) {
  if (timeOfDay < 12) {
    return 'Good morning!';
  } else if (timeOfDay < 17) {
    return 'Good afternoon!';
  } else {
    return 'Good evening!';
  }
}

void main() {
  print(getGreeting(10)); // Output: Good morning!
}
```

**2. Records: Lightweight Data Structures**

* **Immutable and Concise:** Create anonymous, immutable data structures without defining a full class. Ideal for returning multiple values from functions:

```dart
Point getLocation() {
  return const Point(x: 10, y: 20); // Concise record creation
}

void main() {
  final point = getLocation();
  print(point.x); // Output: 10 (Records provide property access)
}
```

**3. Destructuring with Pattern Matching**

* **Extract Values from Data Structures:** Elevate code readability by extracting values directly from patterns in assignments:

```dart
void processPerson(Person person) {
  final name = person.name;
  final age = person.age;
  // ... use name and age
}

void main() {
  final person = Person(name: 'Alice', age: 30);
  processPerson(person);

  // With destructuring:
  final Person(name, age) = person; // Extract name and age directly
  // ... use name and age
}
```

**4. Class Modifiers for Enhanced Control**

* `sealed`: Restrict subclasses and ensure all possible cases are handled when using a class hierarchy.
```dart
sealed class Shape {
  const Shape();
}

class Circle extends Shape {
  final double radius;
  const Circle(this.radius);
}

class Square extends Shape {
  final double sideLength;
  const Square(this.sideLength);
}

void main() {
  // Compile-time error: Triangle is not a subclass of sealed class Shape
  // class Triangle extends Shape {}
}
```

* `abstract`: Enforce subclasses to implement abstract methods and prevent direct instantiation of the abstract class.
```dart
abstract class HospitalStaff {
  // Abstract method - subclasses must define work behavior
  void performDuties();

  String get name; // Concrete property (optional)
}

class Doctor extends HospitalStaff {
  final String specialization;

  Doctor(this.name, this.specialization);

  @override // Ensures correct implementation
  void performDuties() {
    print('$name the doctor is diagnosing patients.');
  }
}

class Nurse extends HospitalStaff {
  final String department;

  Nurse(this.name, this.department);

  @override
  void performDuties() {
    print('$name the nurse is assisting patients in the $department department.');
  }
}

void main() {
  // Cannot directly create a HospitalStaff object
  // HospitalStaff staff = HospitalStaff(); // Compile-time error

  // Create concrete subclass objects (Doctor and Nurse)
  Doctor drAmitJ = Doctor('Dr. Amit J', 'Cardiology');
  Nurse varshaK = Nurse('Varsha K', 'Emergency');

  drAmitJ.performDuties(); // Dr. Amit J the doctor is diagnosing patients.
  varshaK.performDuties();  // Varsha K the nurse is assisting patients in the Emergency department.
}
```

* `mixin`: Promote code reusability by allowing multiple classes to inherit behavior from a mixin.
```dart
mixin Treatable {
  // Abstract method - subclasses must define treatment behavior
  void provideTreatment();

  String get diagnosis; // Optional property
}

class Doctor {
  final String name;
  final String specialization;

  Doctor(this.name, this.specialization);

  void performDuties() {
    print('$name the doctor is diagnosing patients.');
  }
}

class Nurse extends HospitalStaff {
  final String department;

  Nurse(this.name, this.department);

  void performDuties() {
    print('$name the nurse is assisting patients in the $department department.');
  }
}

class Patient with Treatable {
  final String name;
  final String condition;

  Patient(this.name, this.condition);

  @override
  void provideTreatment() {
    print('Providing treatment for $condition to $name.');
  }

  // Can inherit diagnosis from Treatable if needed
}

void main() {
  // Doctor and Nurse classes remain unchanged

  Patient raviKumar = Patient('Ravi Kumar', 'Flu');
  raviKumar.provideTreatment(); // Providing treatment for Flu to Ravi Kumar.
}
```

* `non-nullable`: Enforce non-null semantics on specific class members for stricter type safety.


```dart
class Patient {
  final String name; // Non-nullable - must be initialized with a value

  // Can be nullable if a patient might not have a diagnosis yet
  final String? diagnosis;

  Patient(this.name, {this.diagnosis});
}

class Doctor {
  final String name;
  final String specialization; // Non-nullable - specialization is required

  Doctor(this.name, this.specialization);

  void treatPatient(Patient patient) {
    if (patient.diagnosis != null) { // Check for null before accessing diagnosis
      print('Dr. $name is treating $patient.name for ${patient.diagnosis}.');
    } else {
      print('Dr. $name is examining $patient.name.');
    }
  }
}

void main() {
  Patient raviKumar = Patient('Ravi Kumar'); // Valid - name is non-nullable
  // Patient raviKumar; // Error: 'name' must be initialized

  Doctor drAmit = Doctor('Dr. Amit J', 'Cardiology'); // Valid - both fields are non-nullable

  drAmit.treatPatient(raviKumar); // Outputs: Dr. Amit J is examining Ravi Kumar. (diagnosis is null)
}
```

Want to learn more about Dart3? Check out the resources [link](https://dart.dev/resources/dart-3-migration#introduction)!

Until next time, keep calm and code on.🧑🏻‍💻