Pencocokan Ekspresi

Ekspresi match memberikan kontrol percabangan yang didasarkan pada perbandingan ekspresi dengan seperangkat pola.

Sintaks

// Match expression.
match test-expression with
| pattern1 [ when condition ] -> result-expression1
| pattern2 [ when condition ] -> result-expression2
| ...

// Pattern matching function.
function
| pattern1 [ when condition ] -> result-expression1
| pattern2 [ when condition ] -> result-expression2
| ...

Keterangan

Ekspresi pencocokan pola memungkinkan percabangan kompleks berdasarkan perbandingan ekspresi pengujian dengan serangkaian pola. Dalam ekspresi match, ekspresi-pengujian dibandingkan dengan setiap pola secara bergantian, dan ketika kecocokan ditemukan, ekspresi-hasil yang sesuai dievaluasi dan nilai yang dihasilkan adalah dikembalikan sebagai nilai ekspresi kecocokan.

Fungsi pencocokan pola yang ditunjukkan dalam sintaks sebelumnya adalah ekspresi lambda di mana pencocokan pola dilakukan segera pada argumen. Fungsi pencocokan pola yang ditunjukkan dalam sintaks sebelumnya setara dengan yang berikut ini.

fun arg ->
    match arg with
    | pattern1 [ when condition ] -> result-expression1
    | pattern2 [ when condition ] -> result-expression2
    | ...

Untuk informasi selengkapnya tentang ekspresi lambda, lihat Ekspresi Lambda: funKata Kunci.

Seluruh rangkaian pola harus mencakup semua kemungkinan kecocokan variabel input. Sering kali, Anda menggunakan pola wildcard (_) sebagai pola terakhir untuk mencocokkan nilai input yang sebelumnya tidak cocok.

Kode berikut mengilustrasikan beberapa cara ekspresi match digunakan. Untuk referensi dan contoh semua pola yang mungkin dapat digunakan, lihat Pencocokan Pola.

let list1 = [ 1; 5; 100; 450; 788 ]

// Pattern matching by using the cons pattern and a list
// pattern that tests for an empty list.
let rec printList listx =
    match listx with
    | head :: tail -> printf "%d " head; printList tail
    | [] -> printfn ""

printList list1

// Pattern matching with multiple alternatives on the same line.
let filter123 x =
    match x with
    | 1 | 2 | 3 -> printfn "Found 1, 2, or 3!"
    | a -> printfn "%d" a

// The same function written with the pattern matching
// function syntax.
let filterNumbers =
    function | 1 | 2 | 3 -> printfn "Found 1, 2, or 3!"
             | a -> printfn "%d" a

Penjaga pada pola

Anda dapat menggunakan klausul when untuk menentukan kondisi tambahan yang harus dipenuhi variabel agar sesuai dengan pola. Klausul seperti itu disebut sebagai penjaga. Ekspresi setelah kata kunci when tidak dievaluasi kecuali kecocokan dibuat dengan pola yang terkait dengan penjaga itu.

Contoh berikut mengilustrasikan penggunaan penjaga untuk menentukan rentang numerik untuk pola variabel. Perhatikan bahwa beberapa kondisi digabungkan dengan menggunakan operator Boolean.

let rangeTest testValue mid size =
    match testValue with
    | var1 when var1 >= mid - size/2 && var1 <= mid + size/2 -> printfn "The test value is in range."
    | _ -> printfn "The test value is out of range."

rangeTest 10 20 5
rangeTest 10 20 10
rangeTest 10 20 40

Perhatikan bahwa karena nilai selain harfiah tidak dapat digunakan dalam pola, Anda harus menggunakan klausul when jika Anda harus membandingkan beberapa bagian input terhadap nilai. Hal ini ditunjukkan dalam segmen kode berikut:

// This example uses patterns that have when guards.
let detectValue point target =
    match point with
    | (a, b) when a = target && b = target -> printfn "Both values match target %d." target
    | (a, b) when a = target -> printfn "First value matched target in (%d, %d)" target b
    | (a, b) when b = target -> printfn "Second value matched target in (%d, %d)" a target
    | _ -> printfn "Neither value matches target."
detectValue (0, 0) 0
detectValue (1, 0) 0
detectValue (0, 10) 0
detectValue (10, 15) 0

Perhatikan bahwa ketika pola penyatuan ditutupi oleh penjaga, penjaga berlaku untuk semua pola, bukan hanya yang terakhir. Misalnya, dengan kode berikut, penjaga when a > 41 berlaku untuk A a dan B a:

type Union =
    | A of int
    | B of int

let foo() =
    let test = A 42
    match test with
    | A a
    | B a when a > 41 -> a // the guard applies to both patterns
    | _ -> 1

foo() // returns 42

Lihat juga