DEV Community

Cover image for Exploring Dart 3.0's Powerful Pattern Matching and Destructuring
Dom Jocubeit
Dom Jocubeit

Posted on • Originally published at dom.jocubeit.com on

Exploring Dart 3.0's Powerful Pattern Matching and Destructuring

Dart is a versatile programming language and has introduced new features that enhance code expressiveness and development productivity. Among these features, pattern matching and destructuring stand out as powerful tools. In this article, we'll delve into the world of patterns in Dart, exploring their various use cases and showcasing real-world examples.

Patterns in Dart: Matching Values and Destructuring Objects

Patterns are a syntactic category in Dart, representing the shape of a set of values that can be matched against actual values. They serve two main purposes: pattern matching and pattern destructuring.

Pattern Matching

Pattern matching enables developers to test whether a value meets specific criteria, such as having a particular shape, being a constant, equaling something else, or having a specific type. Let's look at some real-world examples:

  1. Matching a Shape:
import 'dart:math';

class Rectangle { 
  final double width; 
  final double height; 

  Rectangle({required this.width, required this.height}); 
}

class Hexagon {
  final double sideLength;

  Hexagon({required this.sideLength});
}

void calculateArea(dynamic shape) { 
  switch(shape) {
    case Rectangle(width: double w, height: double h):
      final area = w * h;
      print('Area: $area');
      break;
    case Hexagon(sideLength: double l):
      final area = (3 * sqrt(3) * pow(l, 2)) / 2;
      print('Area: $area');
      break;
  }
}

void main() { 
  calculateArea(Rectangle(width: 5, height: 10)); // Area: 50 
  calculateArea(Hexagon(sideLength: 6.9)); // Area: 123.6944084225314
}
Enter fullscreen mode Exit fullscreen mode
  1. Matching a Constant:
const String example = 'example.com';
const String gmail = 'gmail.com';

void validateEmail(String email) {
  final pattern = RegExp(r'^[\w-]+@([\w-]+\.)+[\w-]+$');
  final match = pattern.firstMatch(email);

  if (match != null) {
    final domain = match.group(1);
    switch (domain) {
      case example:
        print('Valid email from example.com');
        break;
      case gmail:
        print('Valid email from gmail.com');
        break;
      default:
        print('Valid email from another domain');
    }
  } else {
    print('Invalid email format');
  }
}

void main() {
  validateEmail('john.doe@example.com'); // Output: Valid email from example.com
  validateEmail('jane.smith@gmail.com'); // Output: Valid email from gmail.com
  validateEmail('foo@bar.com'); // Output: Valid email from another domain
  validateEmail('invalid_email'); // Output: Invalid email format
}
Enter fullscreen mode Exit fullscreen mode

Pattern Destructuring

Pattern destructuring provides a convenient way to break down an object into its constituent parts, extracting values for further use. Let's explore some practical scenarios:

  1. Destructuring a List:
void processCoordinates(List<double> coordinates) {
  var [x, y, z] = coordinates;
  print('x: $x, y: $y, z: $z');
}

void main() {
  processCoordinates([10.5, 20.3, 5.1]); // Output: x: 10.5, y: 20.3, z: 5.1
}
Enter fullscreen mode Exit fullscreen mode
  1. Destructuring a Map Entry:
void processUser(MapEntry<String, int> userEntry) {
  var {key: username, value: age} = userEntry;
  print('Username: $username, Age: $age');
}

void main() {
  var user = MapEntry('JohnDoe', 25);
  processUser(user); // Output: Username: JohnDoe, Age: 25
}
Enter fullscreen mode Exit fullscreen mode

Common Use Cases for Patterns in Dart

  1. Simplifying Data Validation: Patterns prove valuable when validating complex data structures like JSON. They allow us to check if the structure conforms to our expectations and extract specific values effortlessly.

  2. Enhancing Switch Statements: Switch statements become more powerful with pattern matching, enabling multiple cases to share a body or matching against various patterns to execute specific code blocks based on input conditions.

  3. Efficient Variable Assignment: Patterns provide a concise and expressive way to declare and assign variables simultaneously, making code more readable and reducing redundancy.

What have we learned?

With pattern matching and destructuring, Dart empowers developers to write more expressive and concise code. Whether you're validating data, manipulating objects, or enhancing control flow, patterns offer a powerful and flexible toolset. By leveraging these features, you can improve your Dart programming skills and boost productivity in real-world scenarios.

Other information

I used another free credit at STOCKIMG.AI to generate a horizontal poster using disco diffusion for the article poster image. This time I used the image from my first post as the primer, with some words about pattern matching and destructuring. The image above is the generated result. This time I was expecting something similar and result is interesting. Given the two article topics are similar, I thought Id go ahead and use it.

Top comments (0)