Porovnávání (F#)
Vzorky jsou pravidla pro transformování vstupní data.Používají se v celém jazyk F# porovnání s logické struktury nebo struktury dat, data rozloží náležitostech nebo extrahovat informace z data různými způsoby.
Poznámky
Vzorky se používají v mnoha konstrukce jazyka, například match výraz.Používají se při zpracování argumentů funkce v let vazby, lambda výrazů a v popisovačích výjimek spojených s try...with výraz.For more information, see Shoda výrazy (F#), Nechť vazby (F#), Lambda výrazy: Fun klíčové slovo (F#), and Výjimky: Pokuste se výraz (F#)....
Například v match výraz, pattern je co následuje symbol svislé čáry.
odpovídají expression s
| pattern when condition -> result-expression
...
Každý vzorek se chová jako pravidlo pro transformace vstupní nějakým způsobem.V match výraz každý vzorek je zkontrolován zase zda je kompatibilní s vzorek vstupní data.Pokud je nalezena shoda, je provedena výsledek výrazu.Pokud není nalezena shoda, je další pravidlo vzorek testován.Volitelné při condition části je vysvětleno v Shoda výrazy (F#).
V následující tabulce jsou uvedeny podporované vzorky.V době běhu je vstupní zkoušených každé z následujících vzorů v pořadí, které jsou uvedeny v tabulce a vzorky jsou rekurzivně, od první do poslední zobrazené v kódu a zleva doprava vzorků, na každém řádku.
Název |
Description |
Příklad |
---|---|---|
Konstantní vzorek |
Všechny číselné, znak nebo řetězcový literál, konstantu výčtu nebo definovaný identifikátor literál |
1.0, "test", 30, Color.Red |
Identifikátor vzorek |
Hodnota case discriminated unie, výjimkou popisek nebo případu aktivní vzorek |
Some(x) Failure(msg) |
Proměnná vzorek |
identifier |
a |
asvzorek |
vzorek jako identifikátor |
(a, b) as tuple1 |
NEBO vzorek |
pattern1 | pattern2 |
([h] | [h; _]) |
A vzorek |
pattern1 & pattern2 |
(a, b) & (_, "test") |
Nevýhody vzorek |
identifier :: list-identifier |
h :: t |
Seznamu vzorek |
[ pattern_1; ...; pattern_n ] |
[ a; b; c ] |
Maticový vzorec |
[| pattern_1; ..; pattern_n ] |
[| a; b; c |] |
Vzorek v závorce |
( pattern ) |
( a ) |
N-tice vzorek |
( pattern_1, ..., pattern_n ) |
( a, b ) |
Vzorek záznam |
{ identifier1 = pattern_1; ...; identifier_n = pattern_n } |
{ Name = name; } |
Maska zástupných znaků |
_ |
_ |
Vzorek spolu s anotace typu |
pattern : type |
a : int |
Typ testovací vzorek |
:?type asidentifier |
:? System.DateTime as dt |
Vzorek Null |
Null |
null |
Konstantní vzorky
Konstantní vzorky jsou číselné, znak a řetězcové literály výčtu konstant (s názvem typ výčtu zahrnuty).A match výraz, který má pouze konstantní vzorky lze porovnat případu prohlášení v jiných jazycích.Vstup je ve srovnání s hodnotu literálu a vzorek odpovídá-li shodné hodnoty.Typ literál musí být kompatibilní s typem vstup.
Následující příklad ukazuje použití literál vzorky a také používá proměnná vzorek a vzorek nebo.
[<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
Další příklad literál vzorek je vzorek na základě konstanty výčtu.Název typ výčtu musí zadat při použití konstanty výčtu.
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
Identifikátor vzorky
Pokud vzorek je řetězec znaků, který tvoří platný identifikátor, formulář identifikátor určuje, jak je vzorek shodují.Identifikátor je delší než jeden znak a začíná velká znakem, kompilátor pokusí provést odpovídající vzorek identifikátor.Identifikátor pro tento vzorek může být hodnota označené literál atribut, discriminated případě unie, identifikátor výjimku nebo případu aktivní vzorek.Pokud je nalezen žádný odpovídající identifikátor, shoda selže a další vzorek pravidlo proměnné vzorek je porovnán s vstup.
Discriminated unie vzorky mohou být jednoduché s názvem případů nebo mají hodnotu nebo n-tice obsahující více hodnot.Pokud je hodnota, je třeba zadat hodnotu identifikátoru nebo u n-tice, musíte zadat identifikátor pro všechny prvky n-tice vzorku n-tice.Příklady kódu v této části příklady.
option Discriminated unie, který má dva případy je typ Some a None.Jeden případ (Some) má hodnotu, ale ostatní (None) je stejně pojmenované případ.Proto Some musí mít hodnotu spojené s proměnnou Some , však None musí být uvedeny samostatně.Následující kód proměnné var1 je uvedena hodnota, která se získá porovnáním se Some případu.
let printOption (data : int option) =
match data with
| Some var1 -> printfn "%d" var1
| None -> ()
V následujícím příkladu PersonName discriminated unie obsahuje směs řetězce a znaky, které představují možné formy názvy.Jsou případy unie discriminated FirstOnly, LastOnly, a 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
Aktivní vzorky umožňují definovat složitější vlastní porovnávání.Další informace o aktivním vzorky, viz Aktivní vzorky (F#).
Případ, ve kterém je identifikátor výjimkou se používá pro porovnávání v rámci obslužné podprocesy výjimek.Informace o zpracování výjimek pro porovnávání se vzorky, Výjimky: Pokuste se výraz (F#)....
Proměnná vzorky
Přiřadí proměnné vzorek k názvu proměnné, které je k dispozici pro použití v provedení výraz vpravo od hledanou hodnotu -> symbol.Samotné variabilní vzorek odpovídá jakýkoliv vstup, ale proměnné vzorky se často objevuje v rámci jiné vzorky, proto povolení složitějších struktur, například záznamů a polí se rozložit na proměnné.
Příklad proměnné vzorek ve vzorku n-tice.
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 vzorek
as Vzorek je vzorek, který má as k němu klauzule.as Klauzuli hodnoty naváže na název, který lze použít ve výrazu spuštění match výrazu, nebo v případě použití tohoto vzorku v let vazbu, název je přidán jako závazné pro místní obor.
V následujícím příkladu as vzorku.
let (var1, var2) as tuple1 = (1, 2)
printfn "%d %d %A" var1 var2 tuple1
NEBO vzorek
Vzorek nebo při vstupních dat může odpovídat více vzorků a chcete provést v důsledku stejný kód.Typy obě strany nebo vzorek musí být kompatibilní.
Následující příklad ukazuje nebo vzorek.
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)
A vzorek
Vzorek a vyžaduje, aby vstupní shodovala dva vzorky.Typy obě strany vzorku a musí být kompatibilní.
V následujícím příkladu je jako detectZeroTuple v N-tice vzorek dále v tomto tématu, ale zde i var1 a var2 jsou jako hodnoty získané pomocí a vzorek.
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)
Nevýhody vzorek
Nevýhody vzorek se používá k rozloží první prvek seznamu hlavy, seznam, který obsahuje zbývající prvky a ocasu.
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
Seznamu vzorek
Vzor seznamu umožňuje seznamy musí rozložit na počet prvků.Seznamu vzorek sám může odpovídat pouze seznamy určitý počet prvků.
// 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 [ ] )
Maticový vzorec
Maticový vzorec podobná seznamu vzorek a lze rozložit matice po určitou dobu.
// 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 [| |] )
Vzorek v závorce
Závorky mohou být seskupeny kolem vzorky k dosažení požadovaného asociativita operátorů.V následujícím příkladu závorky slouží k řízení asociativitu mezi a vzorek a vzorek nevýhody.
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
N-tice vzorek
N-tice vzorek odpovídá vstupního formuláře n-tice a umožňuje tuple musí rozložit na jeho základních prvků pomocí porovnávání proměnné pro každou pozici v n-tice.
Následující příklad ukazuje n-tice vzorek a používá také literál vzorky, proměnné vzorky a vzor zástupných znaků.
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)
Vzorek záznam
Vzorek záznam slouží k extrahování hodnot polí záznamů.Vzorek neobsahuje odkaz všechna pole záznamu; libovolné pole stačí neúčastní odpovídající a nebude extrahován.
// 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"
Maska zástupných znaků
Maska zástupných znaků je reprezentován podtržítka (_) znaků a odpovídá jakýkoliv vstup, stejně jako vzorek proměnné, s výjimkou, že vstupní zahozeny namísto přiřazena proměnné.Vzor zástupných se často používá v rámci jiné vzorky jako zástupný znak pro hodnoty, které nejsou potřeba ve výrazu vpravo -> symbol.Vzor zástupných se také často používá na konci seznamu vzorek odpovídající jakýkoliv vstup neodpovídající.Zástupné vzorku je prokázána v mnoha příkladech kódu v tomto tématu.Viz předchozí kód pro jeden příklad.
Vzorky, které mají typ poznámky
Vzorky mohou mít typ poznámky.Tyto chovat jako ostatní poznámky typu a příručka odvození stejně jako ostatní poznámky typu.Závorky jsou vyžadovány kolem anotace type ve vzorcích.Následující kód ukazuje vzorek, který má anotaci typu.
let detect1 x =
match x with
| 1 -> printfn "Found a 1!"
| (var1 : int) -> printfn "%d" var1
detect1 0
detect1 1
Typ testovací vzorek
Testovací vzorek typu používá při párování vstupního proti typu.Typ vstupu je shoda s (nebo odvozený typ) typ určený ve vzorku se shodují se zdaří.
Následující příklad ukazuje typ testovací vzorek.
open System.Windows.Forms
let RegisterControl(control:Control) =
match control with
| :? Button as button -> button.Text <- "Registered."
| :? CheckBox as checkbox -> checkbox.Text <- "Registered."
| _ -> ()
Vzorek Null
Null vzorek odpovídá hodnotě null se mohou objevit při práci s typy, které umožňují hodnotu null.Null vzorky jsou často používány při spolupráci s .NET Framework kód.Například návratová hodnota.Rozhraní API NET může být vstup do match výraz.Můžete řídit tok programu, zda je vrácena hodnota null a také na jiných vlastnostech vrácenou hodnotu na základě.Můžete zabránit šíření zbytek programu nulové hodnoty null vzorek.
Následující příklad používá null vzorek a vzorek proměnné.
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()