Udostępnij za pośrednictwem


Wzorzec dopasowania (F#)

Wzorce są reguły do przekształcania danych wejściowych.Służą one całej F# języka do porównywania danych ze struktury logicznej lub struktur, rozkładać dane na części składowe lub wyodrębnienia informacji z danych na różne sposoby.

Uwagi

Wzorki są używane w wielu konstrukcje języka, takie jak match wyrażenie.Są one używane podczas przetwarzania argumentów dla funkcji w let wiązania, wyrażenia lambda i procedur obsługi wyjątków, związane z try...with wyrażenie.For more information, see Dopasowanie wyrażeń (F#), Niech powiązania (F#), Wyrażenia lambda: Fun słowa kluczowego (F#), and Wyjątki: Spróbuj... z wyrażenia (F#).

Na przykład w match wyrażenie, pattern się, co następuje symbol potoku.

odpowiada expression z

| pattern when condition -> result-expression

...

Każdy deseń działa jako regułę do przekształcania danych wejściowych w jakiś sposób.W match wyrażenie, każdy deseń jest badany z kolei jeśli dane wejściowe jest zgodny z wzorcem.Jeśli zostanie znaleziony odpowiednik, wynikiem wyrażenia jest wykonywany.Jeśli nie, bada się dalej reguła deseń.Opcjonalne podczas condition częściowo wyjaśniony jest w Dopasowanie wyrażeń (F#).

Desenie obsługiwanych przedstawiono w poniższej tabeli.W czasie wykonywania danych wejściowych jest testowana każdego z następujących wzorów w kolejności, wymienione w tabeli i desenie są rekursywnie, od najpierw do ostatniego pojawiających się w twoim kodzie i od lewej do prawej, w oparciu o desenie, w każdym wierszu.

Nazwa

Opis

Przykład

Stała wzorca

Wszelkie numeryczne, znak, lub literał ciągu znaków, stałej wyliczeniowej lub określonego identyfikatora literału

1.0, "test", 30, Color.Red

Wzorzec identyfikatora

Wartość case dyskryminowanych Unii, etykieta wyjątek lub przypadku deseń active

Some(x)

Failure(msg)

Deseń zmiennej

identifier

a

aswzorzec

Deseń jako identyfikator

(a, b) as tuple1

LUB wzorzec

pattern1 | pattern2

([h] | [h; _])

I wzorka

pattern1 & pattern2

(a, b) & (_, "test")

Wady wzorca

identifier :: list-identifier

h :: t

Deseń z listy

[ pattern_1; ...; pattern_n ]

[ a; b; c ]

Macierz deseniu

[| pattern_1; ..; pattern_n ]

[| a; b; c |]

Deseń ujętego w nawiasy

( pattern )

( a )

Deseń krotki

( pattern_1, ..., pattern_n )

( a, b )

Deseń rekordu

{ identifier1 = pattern_1; ...; identifier_n = pattern_n }

{ Name = name; }

Deseń symboli wieloznacznych

_

_

Deseń wraz z wskazanie typu

pattern : type

a : int

Wzór testowy typu

:?type asidentifier

:? System.DateTime as dt

Deseń zerowy

NULL

null

Stałe wzorce

Stałe wzorce są stałe wyliczenie numeryczne, znaków i literały ciągów znaków (o nazwie typ wyliczenia włączone).A match wyrażenie, które ma tylko stałe wzorce można porównać do wyrażenia case w innych językach.Dane wejściowe jest porównywana z wartością literału i dopasowuje wzorzec, jeśli wartości są równe.Typu literał musi być zgodny z typem danych wejściowych.

Poniższy przykład demonstruje użycie literału desenie i również używa zmiennych wzoru i lub.

[<Literal>]
let Three = 3

let filter123 x =
    match x with
    // The following line contains literal patterns combined with an OR pattern.
    | 1 | 2 | Three -> printfn "Found 1, 2, or 3!"
    // The following line contains a variable pattern.
    | var1 -> printfn "%d" var1

for x in 1..10 do filter123 x

Innym przykładem literału deseń jest deseń, oparty na stałe wyliczania.Kiedy używać stałych wyliczenia, należy określić nazwę typu wyliczania.

type Color =
    | Red = 0
    | Green = 1
    | Blue = 2

let printColorName (color:Color) =
    match color with
    | Color.Red -> printfn "Red"
    | Color.Green -> printfn "Green"
    | Color.Blue -> printfn "Blue"
    | _ -> ()

printColorName Color.Red
printColorName Color.Green
printColorName Color.Blue

Identyfikator desenie

Jeśli deseń jest ciąg znaków, który stanowi ważny identyfikator, formie identyfikator Określa, jak deseń jest dopasowywane.Jeśli identyfikator ma więcej niż jeden znak i rozpoczyna się od znaku wielkimi literami, kompilator próbuje dopasować je do wzorca identyfikatora.Identyfikator ten wzór może być wartości oznakowane za pomocą literału atrybut, dyskryminowanych przypadku Unii, identyfikator wyjątku lub przypadku deseń active.Jeśli zostanie znaleziony nie pasującego identyfikatora, dopasowanie nie powiedzie się i dalej reguła deseń zmiennej deseń jest porównywany z danych wejściowych.

Dyskryminowanych Unii desenie mogą być proste o nazwie przypadkach lub mogą mieć wartość lub spoiny zawierające wiele wartości.Jeżeli istnieje wartość, należy określić identyfikator dla wartości lub w odniesieniu do spoiny musi dostarczyć deseń krotki z identyfikatorem dla każdego elementu krotki.Zobacz przykłady kodu w tej sekcji przykłady.

option Typu jest dyskryminowanych Unii, który ma dwa przypadki, Some i None.Jednym przypadku (Some) ma wartość, ale inne (None) jest nazwany sprawy.W związku z tym Some musi mieć zmiennej na wartość skojarzoną z Some , ale None muszą znajdować się samodzielnie.W poniższym kodzie zmiennej var1 znajduje się wartość, która jest uzyskiwana przez dopasowanie do Some przypadku.

let printOption (data : int option) =
    match data with
    | Some var1  -> printfn "%d" var1
    | None -> ()

W poniższym przykładzie PersonName Unii dyskryminowanych zawiera mieszankę ciągi i znaki, które reprezentują możliwe formy nazw.Są przypadki dyskryminowanych Unii FirstOnly, LastOnly, i FirstLast.

type PersonName =
    | FirstOnly of string
    | LastOnly of string
    | FirstLast of string * string

let constructQuery personName = 
    match personName with
    | FirstOnly(firstName) -> printf "May I call you %s?" firstName
    | LastOnly(lastName) -> printf "Are you Mr. or Ms. %s?" lastName
    | FirstLast(firstName, lastName) -> printf "Are you %s %s?" firstName lastName

Desenie Active umożliwiają definiowanie bardziej złożone dopasowania deseń niestandardowy.Aby uzyskać więcej informacji na temat active desenie zobacz Desenie Active (F#).

Sprawa, w której identyfikator jest wyjątek jest używany w dopasowanie do wzorca w kontekście procedury obsługi wyjątków.Aby uzyskać informacje o dopasowanie do wzorca w obsługi wyjątków, zobacz Wyjątki: Spróbuj... z wyrażenia (F#).

Desenie zmiennej

Deseń zmiennej przypisuje wartość filtrowanego nazwy zmiennej, która jest dostępna do użycia w wyrażeniu wykonanie na prawo od -> symbol.Deseń zmiennej samodzielnie dopasowuje wszelkie dane wejściowe, ale zmiennej desenie często pojawiają się w ramach innych wzorców, dlatego włączenie bardziej złożonych struktur, takich jak krotek i tablice, aby zostać rozłożony na zmienne.

W poniższym przykładzie zademonstrowano zmiennej wzoru w obrębie deseń krotki.

let function1 x =
    match x with
    | (var1, var2) when var1 > var2 -> printfn "%d is greater than %d" var1 var2 
    | (var1, var2) when var1 < var2 -> printfn "%d is less than %d" var1 var2
    | (var1, var2) -> printfn "%d equals %d" var1 var2

function1 (1,2)
function1 (2, 1)
function1 (0, 0)

jako wzorzec

as Wzorzec jest wzorzec, który ma as klauzuli dołączone do niego.as Klauzuli wiąże wartość dopasowanych do nazwy używanego w wyrażeniu wykonanie match wyrażenie, lub w przypadku gdy ten wzorzec jest używane w let wiążące, nazwa zostanie dodana jako wiążących do zakresu lokalnego.

W poniższym przykładzie użyto as wzoru.

let (var1, var2) as tuple1 = (1, 2)
printfn "%d %d %A" var1 var2 tuple1

LUB wzorzec

Deseń lub jest używany podczas wprowadzania danych można dopasować wielu wzorców i chcesz wykonać w wyniku tego samego kodu.Typy obie strony wzorca lub muszą być zgodne.

W poniższym przykładzie zademonstrowano deseń lub.

let detectZeroOR point =
    match point with
    | (0, 0) | (0, _) | (_, 0) -> printfn "Zero found."
    | _ -> printfn "Both nonzero."
detectZeroOR (0, 0)
detectZeroOR (1, 0)
detectZeroOR (0, 10)
detectZeroOR (10, 15)

I wzorka

Deseń i wymaga, że dane wejściowe są zgodne z dwóch wzorów.Typy obie strony wzorca i muszą być zgodne.

Przypomina poniższy przykład detectZeroTuple przedstawione w Wzoru krotka w dalszej części tego tematu, ale tutaj zarówno var1 i var2 są uzyskiwane jako wartości przy użyciu wzoru I.

let detectZeroAND point =
    match point with
    | (0, 0) -> printfn "Both values zero."
    | (var1, var2) & (0, _) -> printfn "First value is 0 in (%d, %d)" var1 var2
    | (var1, var2)  & (_, 0) -> printfn "Second value is 0 in (%d, %d)" var1 var2
    | _ -> printfn "Both nonzero."
detectZeroAND (0, 0)
detectZeroAND (1, 0)
detectZeroAND (0, 10)
detectZeroAND (10, 15)

Wady wzorca

Deseń wad jest używana do listy do pierwszego elementu headi listy, która zawiera wszystkie pozostałe elementy ogona.

let list1 = [ 1; 2; 3; 4 ]

// This example uses a cons pattern and a list pattern.
let rec printList l =
    match l with
    | head :: tail -> printf "%d " head; printList tail
    | [] -> printfn ""

printList list1

Deseń z listy

Deseń z listy umożliwia być rozłożony na pewną liczbę elementów listy.Sam wzorzec listy można dopasować tylko listy określoną liczbę elementów.

// This example uses a list pattern.
let listLength list =
    match list with
    | [] -> 0
    | [ _ ] -> 1
    | [ _; _ ] -> 2
    | [ _; _; _ ] -> 3
    | _ -> List.length list

printfn "%d" (listLength [ 1 ])
printfn "%d" (listLength [ 1; 1 ])
printfn "%d" (listLength [ 1; 1; 1; ])
printfn "%d" (listLength [ ] )

Macierz deseniu

Deseń tablicy jest podobna do struktury listy i może służyć do tablic określonej długości.

// This example uses array patterns.
let vectorLength vec =
    match vec with
    | [| var1 |] -> var1
    | [| var1; var2 |] -> sqrt (var1*var1 + var2*var2)
    | [| var1; var2; var3 |] -> sqrt (var1*var1 + var2*var2 + var3*var3)
    | _ -> failwith "vectorLength called with an unsupported array size of %d." (vec.Length)

printfn "%f" (vectorLength [| 1. |])
printfn "%f" (vectorLength [| 1.; 1. |])
printfn "%f" (vectorLength [| 1.; 1.; 1.; |])
printfn "%f" (vectorLength [| |] )

Deseń ujętego w nawiasy

Mogą być grupowane nawiasy wokół wzorki, aby osiągnąć żądany łączność.W poniższym przykładzie nawiasy są używane do kontrolowania łączność między wzoru i i wad.

let countValues list value =
    let rec checkList list acc =
       match list with
       | (elem1 & head) :: tail when elem1 = value -> checkList tail (acc + 1)
       | head :: tail -> checkList tail acc
       | [] -> acc
    checkList list 0

let result = countValues [ for x in -10..10 -> x*x - 4 ] 0
printfn "%d" result

Deseń krotki

Deseń krotka pasuje do danych wejściowych w postaci spoiny i umożliwia krotka zostać rozłożony na jego składowe elementy za pomocą zmiennych dla każdej pozycji w krotce dopasowania do wzorca.

Poniższy przykład demonstruje deseń krotka i używa również wzorce literału, zmiennej desenie i deseń symboli wieloznacznych.

let detectZeroTuple point =
    match point with
    | (0, 0) -> printfn "Both values zero."
    | (0, var2) -> printfn "First value is 0 in (0, %d)" var2
    | (var1, 0) -> printfn "Second value is 0 in (%d, 0)" var1
    | _ -> printfn "Both nonzero."
detectZeroTuple (0, 0)
detectZeroTuple (1, 0)
detectZeroTuple (0, 10)
detectZeroTuple (10, 15)

Deseń rekordu

Deseń rekord jest używana do rekordów, aby wyodrębnić wartości pól.Deseń nie musi odwoływać się do wszystkich pól rekordu; wszelkie pominięte pola po prostu nie uczestniczą w dopasowywania i nie są ekstrahowane.

// This example uses a record pattern.

type MyRecord = { Name: string; ID: int }

let IsMatchByName record1 (name: string) =
    match record1 with
    | { MyRecord.Name = nameFound; MyRecord.ID = _; } when nameFound = name -> true
    | _ -> false

let recordX = { Name = "Parker"; ID = 10 }
let isMatched1 = IsMatchByName recordX "Parker"
let isMatched2 = IsMatchByName recordX "Hartono"

Deseń symboli wieloznacznych

Deseń symboli wieloznacznych jest reprezentowany przez znak podkreślenia (_) znaków i dopasowuje wszelkie dane wejściowe, podobnie jak zmienna deseń, chyba, że dane wejściowe są odrzucane zamiast przypisana do zmiennej.Deseń symboli wieloznacznych jest często używany w ramach innych wzorców jako symbol zastępczy dla wartości, które nie są potrzebne w wyrażeniu na prawo od -> symbol.Deseń symboli wieloznacznych jest również często używany na końcu listy wzorców do dopasowywania wszelkich niedopasowane dane wejściowe.Deseń symboli wieloznacznych jest wykazana w wielu przykładach kodu w tym temacie.Zobacz poprzedni kod, na przykład jeden.

Wzorców, które mają typ adnotacji

Desenie mogą mieć typu adnotacji.Te zachowują się podobnie jak inne wskazanie typu i przewodnik wnioskowanie, podobnie jak inne wskazanie typu.Nawiasy są wymagane wokół adnotacje typu we wzorcach.Poniższy kod pokazuje wzorzec wskazania typu.

let detect1 x =
    match x with
    | 1 -> printfn "Found a 1!"
    | (var1 : int) -> printfn "%d" var1
detect1 0
detect1 1

Wzór testowy typu

Wzór testowy typu jest używany do dopasowywania wprowadzania przeciwko typu.Typ określony w strukturze dopasowanie powiedzie się, jeśli typ danych wejściowych jest dopasowanie do (lub pochodnych typu).

W poniższym przykładzie zademonstrowano wzór testowy typu.

open System.Windows.Forms

let RegisterControl(control:Control) =
    match control with
    | :? Button as button -> button.Text <- "Registered."
    | :? CheckBox as checkbox -> checkbox.Text <- "Registered."
    | _ -> ()

Deseń zerowy

Deseń zerowy dopasowuje wartość null, które mogą pojawiać się podczas pracy z typami, które Zezwalaj na wartości null.Desenie Null są często używane przy współpracy z .NET Framework kodu.Na przykład, wartość zwracana.NET API może być wejście do match wyrażenie.Można sterować przepływem programu na podstawie, czy zwracana jest wartość null, a także na inne cechy zwróconą wartość.Deseń zerowy można użyć, aby zapobiec wartości null do pozostałej części programu.

W poniższym przykładzie użyto null wzoru i zmienna.

let ReadFromFile (reader : System.IO.StreamReader) =
    match reader.ReadLine() with
    | null -> printfn "\n"; false
    | line -> printfn "%s" line; true

let fs = System.IO.File.Open("..\..\Program.fs", System.IO.FileMode.Open)
let sr = new System.IO.StreamReader(fs)
while ReadFromFile(sr) = true do ()
sr.Close()

Zobacz też

Informacje

Dopasowanie wyrażeń (F#)

Desenie Active (F#)

Inne zasoby

F# Language Reference