Pilihan
Jenis opsi di F# digunakan ketika nilai aktual mungkin tidak ada untuk nilai atau variabel bernama. Opsi memiliki jenis yang mendasar dan dapat menyimpan nilai dari jenis tersebut, atau mungkin tidak memiliki nilai.
Komentar
Kode berikut mengilustrasikan fungsi yang menghasilkan jenis opsi.
let keepIfPositive (a: int) = if a > 0 then Some(a) else None
Seperti yang Anda lihat, jika input a
lebih besar dari 0, Some(a)
dihasilkan. Jika tidak, None
akan dihasilkan.
Nilai None
digunakan saat opsi tidak memiliki nilai aktual. Jika tidak, ekspresi Some( ... )
memberikan opsi suatu nilai. Nilai Some
dan None
berguna dalam pencocokan pola, seperti dalam fungsi berikut exists
, yang mengembalikan true
jika opsi memiliki nilai dan false
jika tidak.
let exists (x: int option) =
match x with
| Some(x) -> true
| None -> false
Menggunakan Opsi
Opsi umumnya digunakan ketika pencarian tidak mengembalikan hasil yang cocok, seperti yang ditunjukkan dalam kode berikut.
let rec tryFindMatch pred list =
match list with
| head :: tail -> if pred (head) then Some(head) else tryFindMatch pred tail
| [] -> None
// result1 is Some 100 and its type is int option.
let result1 = tryFindMatch (fun elem -> elem = 100) [ 200; 100; 50; 25 ]
// result2 is None and its type is int option.
let result2 = tryFindMatch (fun elem -> elem = 26) [ 200; 100; 50; 25 ]
Dalam kode sebelumnya, daftar dicari secara rekursif. Fungsi tryFindMatch
menerima fungsi predikat pred
yang mengembalikan nilai Boolean, serta sebuah daftar yang akan dicari. Jika elemen yang memenuhi predikat ditemukan, rekursi berakhir dan fungsi mengembalikan nilai sebagai opsi dalam ekspresi Some(head)
. Rekursi berakhir saat daftar kosong dicocokkan. Pada saat itu nilai head
belum ditemukan, dan None
dikembalikan.
Banyak fungsi pustaka F# yang mencari koleksi untuk nilai yang mungkin atau mungkin tidak ada mengembalikan jenis option
. Menurut konvensi, fungsi-fungsi ini dimulai dengan awalan try
, misalnya, Seq.tryFindIndex
.
Opsi juga dapat berguna ketika nilai mungkin tidak ada, misalnya jika ada kemungkinan bahwa pengecualian akan dilemparkan ketika Anda mencoba membuat nilai. Contoh kode berikut mengilustrasikan hal ini.
open System.IO
let openFile filename =
try
let file = File.Open(filename, FileMode.Create)
Some(file)
with ex ->
eprintf "An exception occurred with message %s" ex.Message
None
Fungsi openFile
dalam contoh sebelumnya memiliki jenis string -> File option
karena mengembalikan objek File
jika file berhasil dibuka dan None
jika terjadi pengecualian. Tergantung pada situasinya, ini mungkin bukan pilihan desain yang tepat untuk menangkap pengecualian daripada memungkinkannya menyebar.
Selain itu, masih dimungkinkan untuk meneruskan null
atau nilai null ke opsi kasus Some
. Ini umumnya harus dihindari, dan biasanya dalam pemrograman F# rutin, tetapi dimungkinkan karena sifat jenis referensi di .NET.
Properti dan Metode Opsi
Jenis opsi mendukung properti dan metode berikut.
Properti atau metode | Jenis | Deskripsi |
---|---|---|
None |
'T option |
Anggota statis yang membuat nilai opsi yang memiliki nilai None . |
IsNone | bool |
Mengembalikan true jika opsi memiliki nilai None . |
IsSome | bool |
Mengembalikan true jika opsi memiliki nilai yang tidak None . |
Some |
'T option |
Anggota statis yang membuat opsi dengan nilai yang bukan None . |
Nilai | 'T |
Mengembalikan nilai yang mendasar, atau melemparkan System.NullReferenceException jika nilainya None . |
Modul Opsi
Ada modul, Opsi, yang berisi fungsi berguna yang melakukan operasi pada opsi. Beberapa fungsi mengulangi fungsionalitas properti tetapi berguna dalam konteks di mana fungsi diperlukan.
Option.isSome dan Option.isNone adalah fungsi modul yang menguji apakah opsi menyimpan nilai.
Option.get mengambil nilainya, jika ada. Jika tidak ada nilai, itu memunculkan System.ArgumentException
.
Fungsi Option.bind menjalankan fungsi pada nilai, jika ada nilai. Fungsi harus mengambil tepat satu argumen, dan jenis parameternya harus merupakan jenis opsi. Nilai pengembalian fungsi adalah jenis opsi lain.
Modul opsi juga mencakup fungsi yang sesuai dengan fungsi yang tersedia untuk daftar, array, urutan, dan jenis koleksi lainnya. Fungsi-fungsi ini termasuk Option.map
, Option.iter
, Option.forall
, Option.exists
, Option.foldBack
, Option.fold
, dan Option.count
. Fungsi-fungsi ini memungkinkan opsi untuk digunakan seperti kumpulan nol atau satu elemen. Untuk informasi dan contoh selengkapnya, lihat diskusi tentang fungsi koleksi di Daftar.
Mengonversi ke Tipe Lain
Opsi dapat dikonversi ke daftar atau array. Ketika opsi dikonversi menjadi salah satu struktur data ini, struktur data yang dihasilkan memiliki nol atau satu elemen. Untuk mengonversi opsi ke array, gunakan Option.toArray
. Untuk mengonversi opsi ke daftar, gunakan Option.toList
.
Mengonversi Opsi dengan Nilai Default
Selain mengonversi ke daftar dan array, opsi dapat dikonversi ke jenis lain dengan menyediakan nilai default menggunakan fungsi Option.defaultValue
. Ini sangat berguna ketika Anda ingin memastikan nilainya bukan None
. Misalnya:
let optionString = Some("F#")
let defaultString = optionString |> Option.defaultValue ""
// defaultString is "F#"
let optionInt = None
let defaultInt = optionInt |> Option.defaultValue 0
// defaultInt is 0
Fungsi Option.defaultValue
memungkinkan Anda menangani kasus Some
dan None
dengan mulus tanpa pencocokan pola.