Function

Dalam Dart, fungsi juga merupakan objek — hal ini sedikit berbeda dari bahasa pemrograman lain.

Fungsi adalah objek kelas pertama

Dart adalah bahasa berorientasi objek sepenuhnya: fungsi itu sendiri adalah objek dengan tipe Function.

Fungsi dapat ditugaskan ke variabel dan dikirim sebagai argumen ke fungsi lain;

Instansi kelas dapat dipanggil langsung layaknya fungsi

1 Definisi standar fungsi

// Deklarasi lengkap dengan anotasi tipe kembalian dan parameter
bool isNoble(int atomicNumber) {
  return _nobleGases[atomicNumber] != null;
}Code language: JavaScript (javascript)

Contoh lengkap

// Tabel pasangan nomor atom gas mulia
final Map<int, String> _nobleGases = {
  2: 'He',
  10: 'Ne',
  18: 'Ar',
  36: 'Kr',
  54: 'Xe',
  86: 'Rn',
};

// Deklarasi lengkap dengan tipe kembalian dan tipe parameter
// Tipe int tidak menerima null; gunakan int? untuk parameter yang boleh bernilai null
bool isNoble(int? atomicNumber) {
  return _nobleGases[atomicNumber] != null;
}

void main() {
  print(isNoble(null));       // null bukan kunci peta → false
  print(isNoble(2));          // Cocok dengan gas mulia → true
  print(isNoble(9));          // Tidak ada kecocokan → false
  print(isNoble(86));         // Cocok dengan gas mulia → true
}Code language: PHP (php)
false
true
false
trueCode language: JavaScript (javascript)

2 Menghilangkan anotasi tipe

Panduan gaya Effective Dart mewajibkan anotasi tipe eksplisit lengkap untuk API publik yang bisa diakses luar.

Anotasi tipe boleh dihilangkan pada fungsi privat internal

Contoh


final Map&lt;int, String> _nobleGases = {
  2: 'He',
  10: 'Ne',
  18: 'Ar',
  36: 'Kr',
  54: 'Xe',
  86: 'Rn',
};


isNoble(atomicNumber) {
  return _nobleGases&#91;atomicNumber] != null;
}

void main() {
  print(isNoble(null));       // null bukan kunci peta → false
  print(isNoble(2));          // Cocok dengan gas mulia → true
  print(isNoble(9));          // Tidak ada kecocokan → false
  print(isNoble(86));         // Cocok dengan gas mulia → true
}

Code language: PHP (php)

Pada contoh di atas, fungsi isNoble tidak menuliskan tipe kembalian bool dan tipe parameter int?, namun tetap berfungsi normal.

Ketika kamu tidak menulis tipe, Dart akan melakukan inferensi tipe otomatis:

  • Parameter atomicNumber: Tanpa tipe eksplisit → disimpulkan sebagai dynamic (tipe dinamis, menerima semua jenis nilai: angka, string, null)
  • Nilai kembalian: Tanpa anotasi tipe di awal → Dart menyimpulkan tipe kembalian adalah bool dari ekspresi setelah return, tanpa perlu menuliskannya di kode
Mengapa API publik wajib pakai tipe eksplisit?

Keterbacaan: Pengembang yang memanggil fungsi kamu langsung melihat tipe input dan output, tidak perlu membaca kode internal untuk menebak;

Keamanan tipe: Tipe dynamic menonaktifkan pemeriksaan statis; mengirim tipe yang salah tidak akan menghasilkan error kompilasi dan sering menyebabkan crash saat program berjalan;

Intellisense IDE: Anotasi tipe mengaktifkan pelengkapan otomatis dan petunjuk parameter di editor; tanpa tipe, IDE tidak bisa menampilkan saran yang akurat.

Kapan boleh menghilangkan anotasi tipe?

Hanya disarankan untuk kode privat lokal: fungsi yang hanya dipakai di dalam file saat ini dan tidak pernah dipanggil dari luar.

Sintaks singkat panah (=>)

Jika badan fungsi (kode di dalam {}) hanya berisi satu ekspresi kembalian, kamu bisa gunakan sintaks panah.

Contoh

bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;Code language: PHP (php)
  • => expr setara dengan { return expr; };
  • Hanya ekspresi yang boleh ditulis di antara panah dan titik koma; perintah seperti if dilarang (pakai operator ternaria sebagai gantinya).
// Tabel pasangan nomor atom gas mulia
final Map<int, String> _nobleGases = {
  2: 'Helium',
  10: 'Neon',
  18: 'Argon',
  36: 'Kripton',
  54: 'Xenon',
  86: 'Radon',
};

// Fungsi singkat panah: langsung mengembalikan ekspresi dalam satu baris, setara fungsi blok dengan return
bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;

void main() {
  // Uji gas mulia yang ada
  print(isNoble(2));   // true
  print(isNoble(18));  // true

  // Uji unsur umum
  print(isNoble(6));   // false (Karbon)
  print(isNoble(99));  // false (tidak ada unsur yang cocok)
}Code language: PHP (php)

Parameter

Fungsi mendukung parameter posisi wajib, diikuti salah satu dari dua pilihan: parameter bernama atau parameter posisi opsional — keduanya tidak boleh dicampur.

Koma di akhir baris , diizinkan saat mendeklarasikan atau memanggil parameter untuk meningkatkan keterbacaan kode.

1. Parameter bernama Named parameters

Dibatasi kurung kurawal {}, secara bawaan opsional; tambahkan required untuk memaksa pengisian.

1) Parameter bernama dasar yang boleh null (tanpa nilai bawaan, nilai default adalah null, tipe harus ditandai ?)

void enableFlags({bool? bold, bool? hidden}) {}
// Saat panggil, tulis nama parameter secara eksplisit
enableFlags(bold: true, hidden: false);
Code language: JavaScript (javascript)

Contoh lengkap

/// Aktifkan bendera gaya teks: tebal, tersembunyi
void enableFlags({bool? bold, bool? hidden}) {
  print('Tebal: $bold, Tersembunyi: $hidden');
}

void main() {
  // Kirim semua parameter bernama
  enableFlags(bold: true, hidden: false);

  // Kirim hanya satu parameter bernama, yang lain bernilai null
  enableFlags(bold: true);

  // Kirim hanya hidden
  enableFlags(hidden: true);

  // Tidak kirim parameter apapun, kedua nilai bernilai null
  enableFlags();
}Code language: JavaScript (javascript)

Hasil eksekusi

D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
Tebal: true, Tersembunyi: false
Tebal: true, Tersembunyi: null
Tebal: null, Tersembunyi: true
Tebal: null, Tersembunyi: nullCode language: JavaScript (javascript)

2) Tetapkan nilai bawaan konstan saat kompilasi (tidak perlu tanda ? karena sudah ada nilai default)

void enableFlags({bool bold = false, bool hidden = false}) {}
enableFlags(bold: true); // hidden otomatis pakai false
Code language: JavaScript (javascript)

Contoh

/// Aktifkan bendera gaya teks: tebal, tersembunyi
void enableFlags({bool bold = false, bool hidden = false}) {
  print('Tebal: $bold, Tersembunyi: $hidden');
}

void main() {
  enableFlags();//Tidak kirim parameter, keduanya pakai nilai default false → Tebal: false, Tersembunyi: false
}Code language: JavaScript (javascript)

3) Parameter bernama wajib dengan required (Catatan: Sering dipakai di konstruktor komponen Flutter. Contoh di bawah adalah kode Flutter; pelajari lebih lanjut di tutorial Flutter.)

const Scrollbar({super.key, required Widget child});
// Parameter required juga menerima tipe yang boleh null
const Scrollbar({super.key, required Widget? child});
Code language: JavaScript (javascript)

Dart tidak mewajibkan meletakkan parameter bernama di akhir daftar; bisa disisipkan di posisi mana saja daftar parameter

repeat(times: 2, () {})Code language: CSS (css)
2. Parameter posisi opsional Optional positional parameters

Dibatasi kurung siku [], nilainya null jika dilewatkan; nilai bawaan konstan bisa didefinisikan.

// Tanpa nilai bawaan, tipe ditandai ?
String say(String from, String msg, &#91;String? device]) {
  var result = '$from says $msg';
  if (device != null) result = '$result with a $device';
  return result;
}
assert(say('Bob', 'Howdy') == 'Bob says Howdy');
assert(say('Bob', 'Howdy', 'smoke signal') == 'Bob says Howdy with a smoke signal');
Code language: PHP (php)

Contoh lengkap

// [String? device] parameter posisi opsional tanpa nilai bawaan, bernilai null jika dilewatkan
String say(String from, String msg, [String? device]) {
  var result = '$from says $msg';
  if (device != null) {
    result = '$result with a $device'; //Tambah informasi perangkat ke kalimat jika device tidak null
  }
  return result;
}

void main() {
  // Lewatkan parameter opsional ketiga
  String res1 = say('Bob', 'Howdy');
  print(res1);

  // Kirim parameter posisi opsional ketiga
  String res2 = say('Bob', 'Howdy', 'smoke signal');
  print(res2);

  // Kirim null secara manual ke parameter opsional
  String res3 = say('Alice', 'Hi', null);
  print(res3);
}Code language: JavaScript (javascript)

Tetapkan nilai bawaan:

String say(String from, String msg, &#91;String device = 'carrier pigeon']) {
  return '$from says $msg with a $device';
}
assert(say('Bob', 'Howdy') == 'Bob says Howdy with a carrier pigeon');
Code language: PHP (php)

Contoh lengkap

// Parameter posisi opsional dengan nilai bawaan carrier pigeon (merpati pos)
String say(String from, String msg, [String device = 'carrier pigeon']) {
  return '$from says $msg with a $device';
}

void main() {
  // Lewatkan parameter opsional ketiga, otomatis pakai nilai bawaan carrier pigeon
  String res1 = say('Bob', 'Howdy');
  print(res1); //Bob says Howdy with a carrier pigeon

  // Kirim perangkat khusus untuk ganti nilai bawaan
  String res2 = say('Bob', 'Howdy', 'smoke signal');
  print(res2); //Bob says Howdy with a smoke signal

  String res3 = say('Alice', 'Hello', 'mobile phone');
  print(res3); // Alice says Hello with a mobile phone

  String res4 = say('Jack', 'Tom', 'website foxdevelop.com');
  print(res4); // Jack says Tom with a website foxdevelop.com
}Code language: JavaScript (javascript)

Hasil eksekusi

Built firstdart:firstdart.
Bob says Howdy with a carrier pigeon
Bob says Howdy with a smoke signal
Alice says Hello with a mobile phone
Jack says Tom with a website foxdevelop.comCode language: JavaScript (javascript)


Fungsi titik masuk main ()

Setiap program Dart wajib memiliki fungsi tingkat atas main(); ini satu-satunya titik eksekusi awal program.

  1. Versi dasar tanpa parameter
void main() {
  print('Hello, welcome to foxdevelop.com!');
}
Code language: JavaScript (javascript)
Hello, welcome to foxdevelop.com!Code language: CSS (css)
  1. Program baris perintah yang menerima argumen peluncuran
// Perintah jalankan: dart run firstdart.dart 1 test
void main(List&lt;String> arguments) {
  print(arguments); // &#91;1, test]
}
Code language: JavaScript (javascript)

Gunakan pustaka resmi args untuk parsing argumen baris perintah yang kompleks.

Ganti firstdart.dart di atas dengan nama file Dart milikmu


Fungsi sebagai objek kelas pertama First-class objects

1. Kirim fungsi sebagai parameter

void printElement(int element) =&gt; print(element);
var list = &#91;1, 2, 3];
list.forEach(printElement); // Kirim fungsi secara langsung
Code language: PHP (php)

Contoh lengkap

void main() {
    void printElement(int element) => print(element);
    var list = [1, 2, 3];
    list.forEach(printElement); // Kirim fungsi secara langsung
}Code language: PHP (php)

Hasil keluaran

1
2
3

2. Tetapkan fungsi anonim ke variabel

void main() {
    var loudify = (msg) => '!!! ${msg.toUpperCase()} !!!';
    print(loudify('hello')); //!!! HELLO !!! 
}Code language: JavaScript (javascript)

Tipe fungsi Function Type

Kamu bisa deklarasikan tipe variabel fungsi secara eksplisit

Format: TipeKembalian Function(DaftarParameter, {ParameterBernama})

void greet(String name, {String greeting = 'Hello'}) =&gt; print('$greeting $name!');
// Deklarasikan variabel tipe fungsi
void Function(String, {String greeting}) g = greet;
g('Dash', greeting: 'Howdy');
Code language: JavaScript (javascript)

Gunakan typedef untuk membuat alias tipe fungsi, meningkatkan penggunaan ulang dan keterbacaan.

{String greeting}) → Satu parameter bernama greeting bertipe String

void main() {
    void greet(String name, {String greeting = 'Hello'}) => print('$greeting $name!');
    // Deklarasikan variabel tipe fungsi
    void Function(String, {String greeting}) g = greet;
    g('Jack', greeting: 'Howdy');
}Code language: JavaScript (javascript)

Hasil keluaran

Howdy Jack!

Fungsi anonim (Lambda / Closure penutup leksikal)

Fungsi tanpa nama tetap, dua cara penulisan:

  1. Sintaks blok (multi baris)
void main() {
    const list = ['apples', 'bananas'];
    var uppercaseList = list.map((item) {
      return item.toUpperCase();
    }).toList();
    print(uppercaseList);
}Code language: PHP (php)

(item) { return item.toUpperCase(); } pada kode di atas adalah fungsi anonim (lambda)

Hasil keluaran: [APPLES, BANANAS]

  1. Singkatan panah (ekspresi satu baris)
void main() {
    const list = &#91;'fox', 'develop','foxdevelop.com'];
    var uppercaseList = list.map((item) => item.toUpperCase()).toList();
    uppercaseList.forEach((item) => print('$item: ${item.length}'));
}
Code language: PHP (php)

Hasil keluaran

FOX: 3
DEVELOP: 7
FOXDEVELOP.COM: 14Code language: HTTP (http)

Lingkup leksikal Lexical scope

Dart menggunakan lingkup leksikal statis: lingkup variabel ditentukan oleh hierarki kurung kurawal kode, lingkup dalam bisa mengakses semua variabel lingkup luar.

bool topLevel = true;
void main() {
  var insideMain = true;
  void myFunction() {
    var insideFunction = true;
    void nestedFunction() {
      var insideNestedFunction = true;
      // Semua bisa diakses
      assert(topLevel &amp;&amp; insideMain &amp;&amp; insideFunction &amp;&amp; insideNestedFunction);
    }
  }
}
Code language: JavaScript (javascript)

Penutup leksikal Lexical closures

Penutup: objek fungsi dapat menangkap dan menyimpan variabel lingkup luar, serta mengaksesnya meskipun sudah keluar dari lingkup asli.

Function makeAdder(int addBy) {
  // Tangkap variabel luar addBy
  return (int i) =&gt; addBy + i;
}

void main() {
  var add2 = makeAdder(2);
  var add4 = makeAdder(4);
  assert(add2(3) == 5);
  assert(add4(3) == 7);
}
Code language: PHP (php)

Penjelasan langkah demi langkah alur eksekusi di atas

Langkah 1: var add2 = makeAdder(2);

  1. Jalankan makeAdder, kirim addBy = 2
  2. Buat fungsi anonim: (int i) => 2 + i
  3. Tetapkan fungsi ini ke variabel add2. Saat ini add2 adalah objek fungsi dengan badan (int i) => 2 + i; menerima bilangan bulat i dan mengembalikan i+2
  4. Eksekusi fungsi makeAdder selesai, tapi fungsi anonim mengingat secara permanen addBy=2

Langkah 2: var add4 = makeAdder(4);

  1. Jalankan kembali makeAdder, kirim addBy = 4
  2. Buat fungsi anonim baru yang benar-benar terpisah: (int i) => 4 + i
  3. Tetapkan ke add4, yang menyimpan salinan mandiri miliknya sendiri addBy=4 tanpa mengganggu add2. Artinya nilai addBy disimpan terpisah di dua objek fungsi add2 dan add4, satu simpan 2 dan satu lagi 4
  • Pemanggilan makeAdder(2) menghasilkan penutup mandiri dengan nilai terikat unik addBy = 2, ditugaskan ke add2;
  • Pemanggilan makeAdder(4) menghasilkan penutup baru yang terpisah sepenuhnya dengan nilai terikat unik addBy = 4, ditugaskan ke add4;
  • add2 dan add4 adalah objek fungsi yang benar-benar terpisah, masing-masing menyimpan variabel addBy yang ditangkap secara pribadi tanpa saling mengganggu.

Langkah 3: Panggil add2(3)

Jalankan fungsi internal: 2 + 3 = 5, pernyataan assert terpenuhi

Langkah 4: Panggil add4(3)

Jalankan fungsi internal: 4 + 3 = 7, pernyataan assert terpenuhi

Tear-off fungsi

Jika kamu panggil fungsi / metode tanpa kurung, akan dibuat tear-off (penutup ringkas), menggantikan lambda anonim buatan tangan agar kode lebih rapi.

Ini sintaks yang disarankan; cukup kirim fungsi secara langsung.

var charCodes = &#91;68, 97, 114, 116];
var buffer = StringBuffer();
charCodes.forEach(print); // Tear-off fungsi
charCodes.forEach(buffer.write); // Tear-off metode
Code language: PHP (php)

Sintaks setara yang lebih panjang

charCodes.forEach((code) =&gt; print(code));
charCodes.forEach((code) =&gt; buffer.write(code));
Code language: PHP (php)

Pemeriksaan kesamaan fungsi

  • Fungsi tingkat atas, metode statis: == menghasilkan true jika nama fungsi sama persis;
  • Metode instansi: Hanya tear-off yang terikat ke instansi objek yang sama dianggap sama.
void foo() {}
class A {
  static void bar() {}
  void baz() {}
}
void main() {
  var x = foo;
  assert(foo == x);

  x = A.bar;
  assert(A.bar == x);

  var v = A(), w = A(), y = w;
  x = w.baz;
  assert(y.baz == x); // Instansi sama → sama
  assert(v.baz != w.baz); // Instansi berbeda → tidak sama
}
Code language: JavaScript (javascript)

Nilai kembalian Return values

  1. Semua fungsi memiliki nilai kembalian: Jika tidak ada return eksplisit, di akhir kode akan ditambahkan secara implisit return null;
foo() {}
assert(foo() == null);
Code language: JavaScript (javascript)
  1. Kembalikan beberapa nilai: gunakan tuple Record
(String, int) foo() {
  return ('something', 42);
}
Code language: JavaScript (javascript)

Aksesor Getter & Setter

Membaca atau menetapkan properti apakah pada dasarnya sama dengan memanggil getter atau setter miliknya; variabel biasa secara otomatis menghasilkan aksesor implisit, kamu juga bisa mendefinisikannya secara eksplisit secara manual.

Kelebihan: Kode luar mengakses secara seragam pakai .namaProperti, logika internal bisa diubah kapan saja tanpa memperbaiki kode pemanggil luar.

String _secret = 'Hello';

// Getter untuk membaca
String get secret {
  print('Getter dipanggil');
  return _secret.toUpperCase();
}

// Setter untuk penetapan nilai
set secret(String newMsg) {
  print('Setter dipanggil');
  if (newMsg.isNotEmpty) _secret = newMsg;
}

void main() {
  print(secret); // Membaca, aktifkan getter → HELLO
  secret = 'Dart is fun'; // Penetapan nilai, aktifkan setter
  print(secret); // DART IS FUN
}
Code language: JavaScript (javascript)

* Generator Generators

Membuat urutan secara malas sesuai permintaan, dua varian: sinkron dan asinkron, gunakan yield untuk mengeluarkan nilai.

  1. Generator sinkron sync*, mengembalikan Iterable
Iterable&lt;int> naturalsTo(int n) sync* {
  int k = 0;
  while (k &lt; n) yield k++;
}
Code language: HTML, XML (xml)
  1. Generator asinkron async*, mengembalikan Stream
Stream&lt;int> asyncNaturalsTo(int n) async* {
  int k = 0;
  while (k &lt; n) yield k++;
}
Code language: JavaScript (javascript)
  1. Optimasi generator rekursif yield* (meneruskan ke generator lain untuk meningkatkan performa)
Iterable&lt;int> naturalsDownFrom(int n) sync* {
  if (n &gt; 0) {
    yield n;
    yield* naturalsDownFrom(n - 1);
  }
}
Code language: HTML, XML (xml)

Tinggalkan Balasan

Alamat email Anda tidak akan dipublikasikan. Ruas yang wajib ditandai *