Fitur Patterns hanya bisa digunakan jika versi Dart minimal 3.0 ke atas
I. Fungsi Utama Pattern
Pattern adalah kategori sintaks mandiri di Dart (sama tingkatan dengan pernyataan dan ekspresi) yang menggambarkan bentuk struktur nilai. Terdapat dua kemampuan inti yang bisa dipakai bersamaan: Pencocokan (Match) dan Dekonstruksi (Destructure).
- Pencocokan Match:Memverifikasi apakah nilai sesuai dengan struktur yang diharapkan
- Apakah sama dengan konstanta tertentu
- Apakah sesuai tipe data yang ditentukan
- Apakah memiliki struktur spesifik (List/Map/Objek/Record)
- Apakah memenuhi syarat tambahan
- Dekonstruksi Destructure:Jika pencocokan berhasil, ekstrak field dan elemen dalam nilai secara cepat lalu ikat ke variabel baru
1. Contoh pencocokan konstanta
void main() {
int number = 1;
switch (number) {
case 1:
print('one'); // Pencocokan pola konstanta number == 1
default:
print('angka lain');
}
}Code language: Dart (dart)
Hasil eksekusi
one
2. Pencocokan sub-pola bersarang
Pola mendukung sub-pola bersarang untuk memeriksa struktur internal langkah demi langkah
void main() {
const a = 'a';
const b = 'b';
var obj = [ 'a', 'b'];
switch (obj) {
case [a, b]:
print('$a, $b');
default:
print('tidak cocok');
}
}Code language: Dart (dart)
Hasil eksekusi
a, b
3. Contoh dasar dekonstruksi
var numList = [1, 2, 3];
// Pola List untuk mendekonstruksi elemen list dan ikat ke variabel baru
var [x, y, z] = numList;
print(x + y + z); // 6 x = 1, y = 2, z = 3Code language: PHP (php)
4. Pencocokan pola bersarang + dekonstruksi
void main() {
var list = ['b', 99];
switch (list) {
// Pola OR logis: elemen pertama a atau b, elemen kedua diikat ke variabel c
case ['a' || 'b', var c]:
print(c); // 99
}
}Code language: Dart (dart)
II. Contoh Penggunaan Pattern yang Sering Dipakai
1. Deklarasi variabel lokal
Digunakan untuk penugasan dekonstruksi, bisa membuat banyak variabel sekaligus
// Dekonstruksi pola Record + List bersarang
var (str, [n1, n2]) = ('text', [10, 20]);
print(str); //text
print(n1 + n2); //30Code language: Dart (dart)
2. Penugasan ulang variabel yang sudah ada (tukar nilai tanpa variabel sementara)
var (a, b) = ("kiri", "kanan");
(b, a) = (a, b); // Tukar nilai dua variabel
print('$a $b'); // kanan kiriCode language: Dart (dart)
3. Percabangan switch /if-case (paling sering dipakai, klausa pelindung when)
Setiap case bisa diisi pola yang dapat dibantah: jika tidak cocok, lanjut cek case berikutnya
Contoh case dasar untuk banyak tipe
void testSwitch(dynamic obj) {
switch (obj) {
case 1:
print('angka 1');
case >= 10 && <= 20:
print('angka rentang 10 sampai 20');
case (var a, var b):
print('Record: $a,$b');
default:
print('tidak ada yang cocok');
}
}Code language: Dart (dart)
Pola OR logis: satu logika untuk beberapa cabang
enum Color { red, yellow, blue, green }
void main() {
Color color = Color.red;
bool isPrimary = switch (color) {
Color.red || Color.yellow || Color.blue => true,
_ => false,
};
print(isPrimary); // true
}
Code language: PHP (php)
Klausa pelindung when (filter syarat tambahan setelah pola cocok)
sealed class Shape {}
class Square { final double size; Square(this.size); }
class Circle { final double size; Circle(this.size); }
void checkShape(Shape shape) {
switch (shape) {
// Cocokkan Square dan Circle sekaligus, tambah syarat size>0
case Square(size: var s) || Circle(size: var s) when s > 0:
print('bentuk simetris valid');
default:
print('bentuk tidak valid');
}
}Code language: Dart (dart)
Perbedaan when dengan if biasa
void compareWhen((int, int) pair) {
switch (pair) {
case (int a, int b):
if (a > b) print('nilai pertama lebih besar');
// Jika syarat if gagal: seluruh switch berhenti, case selanjutnya tidak dieksekusi
case (int a, int b) when a > b:
print('【pelindung when】nilai pertama lebih besar');
// Jika syarat when gagal: hanya lewati case ini, lanjut cek case berikutnya
case (int a, int b):
print('nilai pertama lebih kecil atau sama');
}
}
void main() {
print("===== Uji (5, 2) a > b =====");
compareWhen((5, 2));
print("\n===== Uji (2, 5) a < b =====");
compareWhen((2, 5));
}Code language: Dart (dart)
4. Perulangan for /for-in (dekonstruksi MapEntry paling praktis)
void main() {
Map<String, int> hist = {'a': 23, 'b': 100};
// Penulisan lengkap
for (var MapEntry(key: key, value: count) in hist.entries) {
print('$key : $count');
}
// Sintaks singkat: key:key disederhanakan jadi :key
for (var MapEntry(:key, value: count) in hist.entries) {
print('$key : $count');
}
}Code language: Dart (dart)
Hasil eksekusi
D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
a : 23
b : 100
a : 23
b : 100
Code language: CSS (css)
III. Skenario Penggunaan Pattern di Proyek Nyata
1: Fungsi dengan banyak nilai balik (dekonstruksi Record)
Cara penulisan tradisional (rumit)
(String, int) userInfo() => ("Lily", 13);
void main() {
var info = userInfo();
var name = info.$1;
var age = info.$2;
}
Code language: Dart (dart)
Cara singkat dengan pola
var (name, age) = userInfo();
// Dekonstruksi Record field bernama
final (:name, :age) = getData(); // Mengembalikan (name: "Doug", age:25)Code language: Dart (dart)
Contoh lengkap
(String, int) userInfo() => ("Lily", 18);
({String name, int age}) getData() => (name: "Doug", age: 25);
void main() {
{
var (name, age) = userInfo();
print("Nama: $name, umur: $age");
}
// Variabel name/age internal tidak bertabrakan dengan di luar blok
{
final (:name, :age) = getData();
print("Nama: $name, umur: $age");
}
}Code language: Dart (dart)
2: Dekonstruksi instance kelas (pola objek)
class Foo {
final String one;
final int two;
Foo({required this.one, required this.two});
}
void main() {
final Foo myFoo = Foo(one: "test", two: 66);
var Foo(:one, :two) = myFoo;
print('$one $two'); //test 66
}Code language: Dart (dart)
3: Tipe Data Aljabar (Kelas sealed + perhitungan dengan switch)
Mengolah sekelompok subclass terkait secara seragam tanpa metode instance yang tersebar
import 'dart:math';
sealed class Shape {}
class Square implements Shape { final double length; Square(this.length); }
class Circle implements Shape { final double radius; Circle(this.radius); }
double calculateArea(Shape shape) => switch (shape) {
Square(length: var l) => l * l,
Circle(radius: var r) => pi * r * r,
};
Code language: Dart (dart)
Contoh implementasi penuh
import 'dart:math';
// Kelas induk tertutup, subclass hanya bisa dibuat di file ini saja
sealed class Shape {}
// Subclass Persegi
class Square implements Shape {
final double length;
Square(this.length);
}
// Subclass Lingkaran
class Circle implements Shape {
final double radius;
Circle(this.radius);
}
// Hitung luas seragam dengan ekspresi switch + pola objek
double calculateArea(Shape shape) => switch (shape) {
// Cocokkan Square, ambil length ke variabel l
Square(length: var l) => l * l,
// Cocokkan Circle, ambil radius ke variabel r
Circle(radius: var r) => pi * r * r,
};
void main() {
// Buat instance bentuk
Shape square = Square(5);
Shape circle = Circle(3);
// Hitung luas
double squareArea = calculateArea(square);
double circleArea = calculateArea(circle);
print("Luas persegi: $squareArea"); // 25.0
print("Luas lingkaran: ${circleArea.toStringAsFixed(2)}"); // 28.27
}Code language: Dart (dart)
Hasil eksekusi
D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
Luas persegi: 25.0
Luas lingkaran: 28.27Code language: CSS (css)
4: Validasi dan dekonstruksi data JSON (sederhanakan banyak lapis pengecekan)
(Tanpa Pattern) Perlu pengecekan tipe bersarang banyak, kode menjadi panjang
void oldCheck(Map data) {
if (data is Map<String, Object?> && data.containsKey('user')) {
var user = data['user'];
if (user is List && user.length == 2) {
String name = user[0] as String;
int age = user[1] as int;
print('$name $age');
}
}
}Code language: Dart (dart)
Pola if-case: satu baris untuk validasi struktur + tipe + ikatan variabel
void newCheck(Map data) {
if (data case {'user': [String name, int age]}) {
print('Pengguna $name, umur $age');
}
}Code language: Dart (dart)
Pola ini sekaligus memverifikasi hal berikut:
- data berupa Map dan tidak bernilai null
- Terdapat kunci bernama user
- Nilai dari kunci user adalah list dengan 2 elemen
- Elemen pertama String, elemen kedua int
- Variabel lokal name dan age otomatis terikat nilai
Contoh penggunaan nyata
void main() {
// 1. Struktur JSON valid: cocok
final validJson = {
'user': ['Lily', 13]
};
newCheck(validJson); // Output: Pengguna Lily, umur 13
// 2. Tipe data list tidak sesuai: umur string, tidak cocok
final wrongTypeJson = {
'user': ['Tom', '16']
};
newCheck(wrongTypeJson); // Tidak ada output
// 3. List user kurang elemen: tidak ada umur, tidak cocok
final shortJson = {
'user': ['Jack']
};
newCheck(shortJson); // Tidak ada output
// 4. Kunci user tidak ada sama sekali: tidak cocok
final noUserJson = {
'info': ['Bob', 20]
};
newCheck(noUserJson); // Tidak ada output
}
// Validasi struktur & tipe sekaligus dekonstruksi dengan pola Map+List if-case
void newCheck(Map data) {
if (data case {'user': [String name, int age]}) {
print('Pengguna $name, umur $age');
} else {
print('Format data tidak valid');
}
}Code language: PHP (php)
Pencocokan dengan Pattern