Masukkan Password
30 Combination of Positional & Named Parameters | Dart Tutorial #29
Video ini membahas kombinasi positional parameter dan named parameter dalam satu function Dart.
Ini penting karena setelah memahami masing-masing secara terpisah, sekarang kamu perlu tahu bagaimana keduanya bisa digunakan bersama dan aturan urutannya.
Ada satu aturan utama yang harus kamu ingat:
Positional parameters harus ditulis terlebih dahulu, kemudian named parameters di belakangnya.
Kita bahas pelan-pelan.
1. Ingat kembali positional parameter
Misalnya kita punya:
void test(int a, int b, int c) {
print("a = $a");
print("b = $b");
print("c = $c");
}
Ketiga parameter tersebut adalah positional.
Ketika dipanggil:
test(10, 20, 30);
Dart memasangkan berdasarkan posisi:
10 → a
20 → b
30 → c
Jadi:
posisi 1 → a
posisi 2 → b
posisi 3 → c
2. Sekarang kita gabungkan dengan named parameter
Misalnya kita ingin:
a → positional
b → named
c → named
Maka function-nya bisa dibuat seperti ini:
void test(
int a, {
int? b,
int? c,
}) {
print("a = $a");
print("b = $b");
print("c = $c");
}
Perhatikan strukturnya:
int a
↑
positional
kemudian:
{
int? b,
int? c,
}
↑
named
Jadi bentuknya:
POSITIONAL → POSITIONAL → NAMED → NAMED
3. Kenapa harus seperti itu?
Ini adalah aturan yang sangat penting dalam Dart:
Semua positional parameter harus berada sebelum named parameter.
Tidak boleh:
NAMED → POSITIONAL
Jadi tidak boleh membuat struktur seperti:
void test({
int? b,
}, int a) {
}
Karena positional parameter a berada setelah named parameter b.
Yang benar:
void test(
int a, {
int? b,
}) {
}
4. Kenapa Dart membuat aturan seperti ini?
Alasannya sebenarnya sangat masuk akal.
Positional parameter ditentukan berdasarkan urutan.
Misalnya:
void test(int a, int b, ...) {}
Ketika kita menulis:
test(10, 20);
Dart langsung tahu:
10 → a
20 → b
Sekarang bayangkan positional parameter muncul setelah named parameter.
Misalnya secara konsep:
named b
positional a
Kemudian kita menulis:
test(10, b: 20)
Dart harus menjaga aturan bahwa positional argument mengikuti posisi positional parameter.
Karena itu Dart menetapkan struktur yang sederhana:
positional dulu
↓
named setelahnya
5. Contoh pertama: 1 positional + 2 named
Kita punya tiga parameter:
void test(
int a, {
int? b,
int? c,
}) {
print("a = $a");
print("b = $b");
print("c = $c");
}
Strukturnya:
a → positional
b → named
c → named
6. Cara memanggilnya
Karena a adalah positional parameter, kita harus memberikan nilainya secara langsung:
test(10);
Apa yang terjadi?
10 → a
b → null
c → null
Output:
a = 10
b = null
c = null
Kenapa b dan c null?
Karena keduanya adalah named parameter optional:
int? b
int? c
7. Kita bisa memberikan nilai untuk c
Misalnya:
test(
10,
c: 40,
);
Perhatikan:
10 → a
c: 40 → c
Output:
a = 10
b = null
c = 40
Tidak perlu memberikan b.
Kenapa?
Karena b optional.
8. Kita juga bisa memberikan nilai untuk b
Misalnya:
test(
10,
b: 5,
c: 40,
);
Hasilnya:
a = 10
b = 5
c = 40
Jadi:
10 → a
5 → b
40 → c
Tetapi mekanismenya berbeda:
10 → positional
b: 5 → named
c: 40 → named
9. Hal yang menarik: urutan named parameter boleh diubah
Misalnya:
test(
10,
c: 40,
b: 5,
);
Ini boleh.
Hasilnya tetap:
a = 10
b = 5
c = 40
Karena:
a
ditentukan secara positional.
Sedangkan:
b: 5
c: 40
ditentukan berdasarkan nama.
Jadi named parameter tidak peduli urutan.
10. Tetapi positional parameter harus tetap di depan
Misalnya:
test(
10,
b: 5,
c: 40,
);
Ini benar.
Strukturnya:
10
↓
positional
b: 5
↓
named
c: 40
↓
named
Tetapi konsep seperti ini tidak boleh:
test(
b: 5,
10,
c: 40,
);
Karena argument positional tidak boleh diletakkan setelah named argument.
Jadi secara sederhana:
Positional argument dulu, named argument setelahnya.
11. Apakah a boleh dilewati?
Misalnya function:
void test(
int a, {
int? b,
int? c,
}) {}
Kemudian kita ingin hanya memberikan:
b: 5
Apakah bisa?
test(
b: 5,
);
Tidak bisa.
Kenapa?
Karena a adalah required positional parameter.
Jadi kita tetap harus memberikan a:
test(
10,
b: 5,
);
12. Ini perbedaan yang sangat penting
Dalam function:
void test(
int a, {
int? b,
int? c,
}) {}
statusnya:
a → positional + required
b → named + optional
c → named + optional
Jadi:
test(10);
valid.
test(10, b: 5);
valid.
test(10, c: 40);
valid.
test(10, b: 5, c: 40);
valid.
Tetapi:
test();
tidak valid karena a wajib.
13. Contoh kedua: 2 positional + 1 named
Sekarang kita ubah strukturnya.
Kita ingin:
a → positional
b → positional
c → named
Maka:
void test(
int a,
int b, {
int? c,
}) {
print("a = $a");
print("b = $b");
print("c = $c");
}
Strukturnya:
a → positional
b → positional
c → named
14. Cara memanggilnya
Karena a dan b adalah positional:
test(10, 20);
Maka:
10 → a
20 → b
c → null
Output:
a = 10
b = 20
c = null
15. Kalau ingin memberikan nilai c
Karena c adalah named parameter, kita harus menuliskan namanya:
test(
10,
20,
c: 50,
);
Hasil:
a = 10
b = 20
c = 50
Perhatikan mekanismenya:
10 → a
20 → b
c: 50 → c
16. Kenapa a dan b tidak perlu nama?
Karena mereka positional.
Kita cukup:
test(10, 20);
Dart sudah tahu:
nilai pertama → a
nilai kedua → b
Sedangkan c named, sehingga harus:
c: 50
17. Apakah kita bisa menulis c di tengah?
Misalnya:
test(
10,
c: 50,
20,
);
Tidak boleh.
Kenapa?
Karena 10 dan 20 adalah positional arguments.
Positional arguments harus berada di depan.
Jadi yang benar:
test(
10,
20,
c: 50,
);
18. Kenapa b tidak bisa dibuat named sementara a dan c positional?
Misalnya kita punya:
a
b
c
Kamu ingin:
a → positional
b → named
c → positional
Ini tidak bisa dilakukan dengan struktur parameter seperti itu.
Karena hasilnya secara urutan akan menjadi:
positional
named
positional
Padahal aturan Dart adalah:
positional
positional
positional
named
named
named
Jadi positional harus menjadi blok di depan, dan named menjadi blok di belakang.
19. Kalau memang ingin a dan c positional, b named?
Solusinya bukan memaksa urutannya.
Kamu perlu mengubah deklarasi parameter.
Misalnya secara konsep kamu ingin:
a → positional
c → positional
b → named
Maka deklarasinya harus diubah menjadi:
void test(
int a,
int c, {
int? b,
}) {
// ...
}
Sekarang struktur deklarasinya:
a → positional
c → positional
b → named
Pemanggilan:
test(
10,
30,
b: 20,
);
Hasilnya:
a = 10
b = 20
c = 30
Jadi yang penting bukan nama a, b, c, tetapi posisi parameter dalam deklarasi function.
20. Ini sebenarnya pola yang sangat sederhana
Kamu bisa membayangkan function seperti ini:
┌──────────────────────────────────────┐
│ FUNCTION │
│ │
│ POSITIONAL | NAMED │
│ | │
│ a | b │
│ c | d │
│ e | f │
└──────────────────────────────────────┘
Aturannya:
← positional → | ← named →
Tidak boleh:
positional → named → positional
21. Positional + named + required
Sekarang kita gabungkan dengan materi sebelumnya.
Named parameter secara default optional.
Misalnya:
void test(
int a, {
int? b,
int? c,
}) {}
Tetapi kita bisa membuat named parameter menjadi required:
void test(
int a, {
required int b,
int? c,
}) {
print("a = $a");
print("b = $b");
print("c = $c");
}
Sekarang:
a → positional required
b → named required
c → named optional
Pemanggilan:
test(
10,
b: 20,
);
valid.
Tetapi:
test(10);
tidak valid karena b wajib diberikan.
22. Ini sangat sering digunakan di Flutter
Misalnya kamu membuat function:
void createUser(
String name, {
required String email,
int age = 0,
}) {
print(name);
print(email);
print(age);
}
Strukturnya:
name → positional required
email → named required
age → named optional
default = 0
Pemanggilan:
createUser(
"Budi",
email: "budi@gmail.com",
);
Hasil:
Budi
budi@gmail.com
0
Atau:
createUser(
"Budi",
email: "budi@gmail.com",
age: 20,
);
Hasil:
Budi
budi@gmail.com
20
Ini adalah pola yang sangat umum dalam kode Dart dan Flutter.
23. Hubungan dengan constructor Flutter
Nanti ketika belajar class dan constructor, kamu akan sering menemukan pola seperti:
class User {
String name;
int age;
User(
this.name, {
required this.age,
});
}
Di sini:
name → positional
age → named required
Kemudian:
User(
"Budi",
age: 20,
);
Konsepnya persis sama.
24. Bedakan parameter dengan argument
Ini juga penting supaya kamu tidak bingung.
Deklarasi:
void test(
int a, {
int? b,
int? c,
}) {}
a, b, dan c disebut parameters.
Ketika dipanggil:
test(
10,
b: 20,
c: 30,
);
10, 20, dan 30 disebut arguments.
Jadi:
PARAMETER
↓
void test(int a, {int? b, int? c})
dan:
ARGUMENT
↓
test(10, b: 20, c: 30)
25. Perbedaan positional dan named dalam kombinasi
Mari kita lihat satu contoh lengkap:
void test(
String name,
int age, {
String? city,
String country = "Indonesia",
}) {
print("Name: $name");
print("Age: $age");
print("City: $city");
print("Country: $country");
}
Strukturnya:
name → positional required
age → positional required
city → named optional
country → named optional
default = "Indonesia"
Kita bisa:
test(
"Budi",
20,
);
Output:
Name: Budi
Age: 20
City: null
Country: Indonesia
Atau:
test(
"Budi",
20,
city: "Madiun",
);
Output:
Name: Budi
Age: 20
City: Madiun
Country: Indonesia
Atau:
test(
"Budi",
20,
country: "Japan",
city: "Tokyo",
);
Output:
Name: Budi
Age: 20
City: Tokyo
Country: Japan
Perhatikan bahwa:
country: "Japan",
city: "Tokyo",
boleh ditulis dalam urutan tersebut.
26. Aturan yang harus benar-benar kamu hafalkan
Ada 3 aturan utama.
Aturan 1 — Positional menggunakan posisi
test(10, 20);
Nilai pertama → parameter pertama.
Nilai kedua → parameter kedua.
Aturan 2 — Named menggunakan nama
test(
a: 10,
b: 20,
);
10 diberikan kepada a.
20 diberikan kepada b.
Urutan tidak penting.
Aturan 3 — Positional harus berada sebelum named
Contoh valid:
void test(
int a,
int b, {
int? c,
int? d,
}) {}
Struktur:
positional
positional
named
named
Tidak valid secara konsep:
positional
named
positional
named
27. Cara cepat membaca function
Kalau nanti kamu menemukan kode seperti:
void test(
int a,
String b, {
required double c,
bool d = false,
}) {}
Jangan panik.
Baca dari kiri ke kanan:
int a
↓
positional wajib
String b
↓
positional wajib
{
required double c
↓
named wajib
bool d = false
↓
named optional
default = false
}
Jadi untuk memanggilnya:
test(
10,
"Hello",
c: 20.5,
);
d tidak perlu diberikan karena punya default:
d = false
28. Cheat sheet
| Bentuk | Jenis | Wajib? |
|---|---|---|
int a | Positional | ✅ |
[int? a] | Optional positional | ❌ |
{int? a} | Optional named | ❌ |
{int a = 0} | Named + default | ❌ |
{required int a} | Named required | ✅ |
Dan kalau digabung:
void test(
int a,
int b, {
int? c,
required int d,
}) {}
artinya:
a → positional wajib
b → positional wajib
c → named optional
d → named wajib
Pemanggilan:
test(
10,
20,
d: 40,
);
Boleh juga:
test(
10,
20,
c: 30,
d: 40,
);
29. Satu hal yang perlu diluruskan dari video
Video mengatakan bahwa named parameter “harus” ditulis setelah positional parameter. Untuk deklarasi function, benar: positional parameters harus mendahului named parameters.
Namun ada sedikit nuansa ketika membahas pemanggilan function: kamu juga menulis positional arguments sebelum named arguments.
Contoh:
test(
10,
20,
c: 30,
);
Bukan:
test(
c: 30,
10,
20,
);
Jadi secara praktis, saat memanggil function, biasakan pola:
positional arguments dulu
↓
named arguments setelahnya
Kesimpulan
Materi ini sebenarnya hanya ingin mengajarkan satu pola besar:
POSITIONAL PARAMETERS → NAMED PARAMETERS
Contoh:
void test(
int a,
int b, {
int? c,
}) {}
Artinya:
a → positional
b → positional
c → named
Pemanggilan:
test(
10,
20,
c: 30,
);
Dart membaca:
10 → a
20 → b
30 → c
Kalau:
void test(
int a, {
int? b,
int? c,
}) {}
maka:
test(
10,
c: 30,
);
menghasilkan:
a = 10
b = null
c = 30
Dan kalau:
void test(
int a, {
required int b,
int c = 0,
}) {}
maka:
a → positional, wajib
b → named, wajib
c → named, optional, default 0
Kalimat yang paling penting:
Dalam satu function, positional parameter harus berada di depan, sedangkan named parameter berada di belakang. Positional diisi berdasarkan urutan, named diisi menggunakan
namaParameter: nilai.
Kalau pola ini sudah kamu kuasai, kode Flutter seperti Container(width: ..., height: ...), constructor widget, dan berbagai function API Flutter akan jauh lebih mudah dibaca.