Chapter sebelumnya memperkenalkan anonymous function — dan diam-diam juga memperkenalkan tipe datanya: function_handle. Handle tidak harus lahir dari anonymous function; handle juga bisa menunjuk ke fungsi bernama apa pun, baik fungsi bawaan seperti sqrt maupun fungsi buatan kita di berkas .m. Begitu sebuah fungsi menjadi data, kita bisa menyimpannya di variabel, menaruhnya di cell array dan struct, mengirimkannya sebagai argumen, bahkan membangun algoritma generik yang menerima aturan sebagai masukan. Chapter ini membahas ke mana-mana bersama function handle. Cakupannya:

  • membuat handle ke fungsi bernama dengan @namaFungsi
  • memanggil handle secara langsung maupun lewat feval
  • konversi nama fungsi ke teks dan sebaliknya (func2str, str2func)
  • menyimpan handle di cell array/struct dan mem-pass-nya antar fungsi

@namaFungsi: Handle ke Fungsi Bernama #

Aturannya: f = @sqrt membuat handle yang menunjuk fungsi bernama sqrt — tanpa tanda kurung dan tanpa argumen, karena kita mengambil fungsinya, bukan hasil pemanggilannya. Mekanisme di balik layar: handle menyimpan tautan ke fungsi beserta workspace penangkapan (kosong untuk fungsi bernama); ketika handle dipanggil f(16), MATLAB menjalankan fungsi yang ditunjuk dengan argumen tersebut. Sintaks feval(f, 25) mencapai hasil yang sama — bentuk klasik dari era sebelum handle bisa dipanggil langsung, yang kini masih kita temui di kode lama:

matlab
f = @sqrt;
fprintf('class(f)           : %s\n', class(f));
fprintf('f(16)              : %d\n', f(16));
fprintf('feval(f, 25)       : %d\n', feval(f, 25));

Output yang Dihasilkan:

text
class(f)           : function_handle
f(16)              : 4
feval(f, 25)       : 5

Tiga cara menciptakan handle beserta kebalikannya:

OperasiContohHasil
handle ke fungsi bernama@sqrthandle ke sqrt
anonymous function@(x) x^2 + 1handle dengan ekspresi sendiri
dari teks namastr2func('abs')handle ke fungsi bernama abs
balik ke teksfunc2str(f)char nama fungsi/ekspresi

func2str dan str2func #

Dua konverter ini menjembatani dunia handle dan dunia teks — berguna untuk label plot, pesan galat, atau memilih fungsi dari nama yang dibangun saat runtime. str2func menerima char nama fungsi dan mengembalikan handle; func2str sebaliknya mengembalikan char pendek yang menjelaskan isi handle, termasuk untuk anonymous function:

matlab
fprintf('func2str(f)        : %s\n', func2str(f));
g = str2func('abs');
fprintf('g(-7)              : %d\n', g(-7));

% uji tipe: MATLAB tidak punya isfunctionhandle, pakai isa
fprintf('isa(f, handle)     : %d\n', isa(f, 'function_handle'));

% handle ke anonymous function diperlakukan sama
h = @(x) x^2 + 1;
fprintf('func2str(h)        : %s\n', func2str(h));

Output yang Dihasilkan:

text
func2str(f)        : sqrt
g(-7)              : 7
isa(f, handle)     : 1
func2str(h)        : @(x) x^2+1

Menyimpan Handle dalam Cell Array dan Struct #

Handle adalah nilai biasa, sehingga hukum penyimpanan array dan struct berlaku padanya. Cell array (dari Chapter Cell Array) menampung handle campuran; struct memberi nama pada tiap slot. Pemanggilannya memakai indexing lalu kurung argumen:

matlab
% menyimpan handle di cell array dan struct
daftarFungsi = {@sqrt, @abs, @(x) x^2 + 1};
fprintf('daftarFungsi{1}(9) : %d\n', daftarFungsi{1}(9));
daftar = struct('nama', {'akar', 'mutlak'}, 'f', {f, @abs});
fprintf('daftar(2).f(-4)    : %d\n', daftar(2).f(-4));

Output yang Dihasilkan:

text
daftarFungsi{1}(9) : 3
daftar(2).f(-4)    : 4

Mari kita bedah baris-baris kode di atas:

  1. Baris 2 (daftarFungsi = {@sqrt, @abs, ...}): kurung kurawal membuat cell array 1×3 yang tiap selnya berisi satu handle — tipe isinya boleh berbeda-beda, bahkan campuran fungsi bernama dan anonymous.
  2. Baris 3 (daftarFungsi{1}(9)): indeks kurung kurawal mengambil handle @sqrt, lalu kurung (9) langsung memanggilnya — hasil sqrt(9).
  3. Baris 4-5 (struct('nama', {...}, 'f', {...})): struct array 1×2 dengan field nama (char) dan f (handle); daftar(2).f mengambil handle @abs dari elemen kedua.

Mem-pass Fungsi sebagai Argumen #

Puncak pemakaian handle: mengirim fungsi sebagai input fungsi lain. Berkas terapkan.m menerima handle f lalu memanggilnya untuk setiap elemen array — algoritma yang sama bekerja untuk @sqrt, @abs, atau anonymous function apa pun:

matlab
function hasil = terapkan(f, x)
% terapkan Menerapkan function handle f pada setiap elemen x.
%   hasil = terapkan(f, x) memanggil f untuk tiap elemen array x dan
%   mengembalikan hasilnya sebagai array dengan ukuran yang sama.

hasil = zeros(size(x));
for k = 1:numel(x)
    hasil(k) = f(x(k));
end
end

Mari kita bedah baris-baris kode di atas:

  1. Baris 1 (function hasil = terapkan(f, x)): parameter f adalah handle — dari sudut pandang deklarasi, ia variabel biasa bertipe function_handle.
  2. Baris 6 (hasil = zeros(size(x));): preallocation hasil seukuran x, kebiasaan dari Chapter for Loop.
  3. Baris 7-9 (for k = ... hasil(k) = f(x(k));): di tiap iterasi, handle f dipanggil dengan elemen x(k) — pemanggil yang menentukan fungsi apa yang dijalankan baris ini.

Pemanggilan dari contoh.m:

matlab
% mem-pass fungsi sebagai argumen fungsi lain
hasil1 = terapkan(@sqrt, [4 9 16 25]);
fprintf('terapkan(@sqrt)    : %d %d %d %d\n', hasil1);
hasil2 = terapkan(@(x) x + 1, [1 2 3]);
fprintf('terapkan(anonim)   : %d %d %d\n', hasil2);

Output yang Dihasilkan:

text
terapkan(@sqrt)    : 2 3 4 5
terapkan(anonim)   : 2 3 4

Ringkasan #

@namaFungsi menciptakan function handle ke fungsi bernama — tanpa kurung, karena yang diambil adalah fungsinya. Handle dipanggil langsung f(x) atau lewat feval bentuk lama; func2str/str2func mengubahnya bolak-balik dengan teks. Sebagai data, handle hidup di variabel, cell array, dan struct, serta bisa dikirim sebagai argumen — memungkinkan algoritma generik seperti terapkan(f, x) yang menyerahkan pilihan fungsi kepada pemanggil. MATLAB tidak punya isfunctionhandle; uji tipe dengan isa(f, 'function_handle'). Berkas contoh.m dan terapkan.m di bagian bawah halaman memuat contoh utuh yang sudah teruji.