Desen Eşleştirme (F#)

Desenler, dönüştürme giriş verileri kurallardır.Bunlar, verileri mantıksal bir yapıyla veya yapılarla karşılaştırmak, verileri bileşenlerine ayırmak veya çeşitli şekillerde verilerden bilgi ayıklamak için F# dilinde kullanılır.

Notlar

Desenler, match ifadeleri gibi kullanılan birçok dil yapılarında kullanılır.Bunlar let bağlarında, lambda ifadelerinde ve try...with ifadesiyle ilişkili özel durum işleyicilerde işlevler için bağımsız değişkenler işlenirken kullanılır.Daha fazla bilgi için bkz. Eşleşme İfadeleri (F#), let Bağlamaları (F#), Lambda İfadeleri: fun Anahtar Sözcüğü (F#) ve Özel Durumlar: try...with İfadesi (F#).

Örneğin match ifadesinde pattern, kanal simgesini izleyen şeydir.

expression ile eşleştirin

| pattern [ when condition ] -> result-expression

...

Her desen bir şekilde girişi dönüştürme kuralı olarak işlev görür.match ifadesinde her desen sırayla incelenir ve veri girişinin desen ile uyumlu olup olmadığı incelenir.Bir eşleme bulunursa sonuç ifade yürütülür.Bir eşleme bulunmazsa sonraki desen kuralı test edilir.İsteğe bağlı condition bölümü Eşleşme İfadeleri (F#) bölümünde açıklanmıştır.

Desteklenen desenler aşağıdaki tabloda gösterilmiştir.Çalışma sırasında girdi tabloda listelenme sırasına göre şu desenlerden her birine ilişkin test edilir ve desenler yinelemeli olarak kodda görünen sırada baştan sona, her satırdaki desenler için soldan sağa uygulanır.

Ad

Tanımlama

Örnek

Sabit desen

Tüm sayısal, karakter veya dize değişmez değeri, numaralandırma sabiti veya tanımlı değişmez değer tanımlayıcısı

1.0, "test", 30, Color.Red

Tanımlayıcı desen

Ayrılmış birleşimin büyük/küçük harf değeri, özel durum etiketi veya etkin desen çalışması

Some(x)

Failure(msg)

Değişken deseni

identifier

a

as deseni

pattern as identifier

(a, b) as tuple1

OR deseni

pattern1 | pattern2

([h] | [h; _])

AND deseni

pattern1 & pattern2

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

Olumsuz desen

identifier :: list-identifier

h :: t

Liste deseni

[ pattern_1; ... ; pattern_n ]

[ a; b; c ]

Dizi deseni

[| pattern_1; ..; pattern_n ]

[| a; b; c |]

Parantezlenmiş desen

( pattern )

( a )

Tanımlama grubu düzeni

( pattern_1, ... , pattern_n )

( a, b )

Kayıt düzeni

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

{ Name = name; }

Joker karakter deseni

_

_

Tür ek açıklaması ile birlikte desenleyin

pattern : type

a : int

Test desenini yazın

:?identifier ] olaraktype

:? System.DateTime as dt

Null desen

null

null

Sabit Desenler

Sabit desenler sayısal, karakter ve dize değişmez değerleri, numaralandırma sabitidir (numaralandırma türü adı dahil).Başka dillerdeki case deyimiyle kıyaslanabilen, yalnızca sabit desenlere sahip match deyimi.Girdi değişmez değerle karşılaştırılır ve değerleri aynıysa desen eşleşir.Değişmez değerin türü giriş türü ile uyumlu olmalıdır.

Aşağıdaki örnek, değişmez değer desenlerinin kullanımını gösterir ve ayrıca bir değişken desen ve bir VEYA deseni kullanır.

[<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

Değişmez değer deseninin başka bir örneği, numaralandırma sabitlerini temel alan bir desendir.Numaralandırma sabitlerini kullandığınızda, numaralandırma türü adı belirtmeniz gerekir.

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

Tanımlayıcı desenler

Desen, geçerli bir tanımlayıcı oluşturan karakter dizesi ise, tanımlayıcının biçimi desen eşleştirilmesini belirler.Tanımlayıcı tek bir karakterden daha uzunsa ve büyük harfli bir karakterle başlarsa, derleyici tanımlayıcı desen eşleştirmesi yapmaya çalışır.Bu desenin tanımlayıcısı; Değişmez Değer özniteliği, ayrılmış bir birleşim durumu, bir özel durum tanımlayıcısı veya etkin bir desen çalışması ile işaretlenmiş bir değer olabilir.Eşleşen hiçbir tanımlayıcı bulunmazsa, eşleştirme başarısız olur ve sonraki desen kuralı, değişken desen girdiyle karşılaştırılır.

Ayrılmış birleşim desenleri basit adlandırılmış çalışmalar olabilir veya bir değere sahip olabilir ya da birden çok değer içeren bir tanımlama grubu olabilir.Bir değer varsa değer için bir tanımlayıcı seçmelisiniz.Bir kayıt düzeni olması durumunda, düzenin her öğesi için bir tanımlayıcısı olan kayıt düzeni deseni veya bir veya birkaç adlandırılmış birlik alanı için alan adı olan bir tanımlayıcı sağlamanız gerekir.Örnekler için bu bölümdeki kod örneklerine bakınız.

option türü, Some ve None olmak üzere iki duruma sahip ayrılmış bir birleşimdir.Bir durumda (Some) bir değere sahiptir, ancak diğeri (None) sadece adlı bir durumdur.Bu nedenle Some, Some örneğiyle ilişkili değer için bir değişkene sahip olmalı ancak None tek başına görünmelidir.Aşağıdaki kodda var1 değişkenine, Some durumuyla eşleştirilerek elde edilen değeri verilir.

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

Aşağıdaki örnekte, PersonName ayrılmış birleşik yapıda olası ad formlarını temsil eden dize ve karakter karışımı vardır.Ayrılmış birleşimin durumları FirstOnly, LastOnly ve FirstLast olur.

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

Ad alanları içeren ayrılmış bileşenlerde bir ad alanının değerini ayıklamak eşit işaretini (=) kullanırsınız.Örneğin aşağıdaki gibi bir bildirim ile ayrılmış bir bileşim düşünebilirsiniz.

type Shape =
| Rectangle of height : float * width : float
| Circle of radius : float

İfadeyle eşleşen desendeki adlandırılmış alanları aşağıdaki gibi kullanabilirsiniz.

let matchShape shape =
    match shape with
    | Rectangle(height = h) -> printfn "Rectangle with length %f" h
    | Circle(r) -> printfn "Circle with radius %f" r

Adlandırılmış alan kullanımı isteğe bağlıdır, dolayısıyla önceki örnekte, hem Circle(r) hem de Circle(radius = r) aynı etkiye sahip olur.

Birden çok alan belirtirken, ayırıcı olarak noktalı virgül (;) kullanın.

match shape with
| Rectangle(height = h; width = w) -> printfn "Rectangle with height %f and width %f" h w
| _ -> ()

Etkin desenler, daha karmaşık özel desen eşleştirmeleri tanımlamanıza olanak sağlar.Etkin desenler hakkında daha fazla bilgi için bkz. Etkin Desenler (F#).

Tanımlayıcının özel durum olduğu bir durum, özel durum işleyicilerinin bağlamında eşleşen desende kullanılır.Uzantı işlemede desen eşleme hakkındaki bilgiler için bkz. Özel Durumlar: try...with İfadesi (F#).

Değişken Desenleri

Değişken desen, eşleştirilen değeri bir değişken adına atar, o da ardından -> simgesinin sağındaki yürütme ifadesinde kullanılabilir.Değişken desen tek başına herhangi bir girdiyle eşleşir ancak değişken desenler genellikle diğer desenlerle görünür, böylece değişkenlere ayrıştırılacak tanımlama grubu ve diziler gibi daha karmaşık yapıları etkinleştirebilir.

Aşağıdaki örnek, bir kayıt düzeni desen içinde değişken bir desen gösterir.

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)

Desen gibi

as deseni, kendisine eklenmiş bir as yan tümcesine sahip bir desendir.as yan tümcesi, eşleştirilen değeri bir match ifadesinin yürütme ifadesinde kullanılabilecek bir ada bağlar veya bu desenin bir let bağlamasında kullanıldığı durumlarda ad, yerel kapsama bir bağlama unsuru olarak eklenir.

Aşağıdaki örnek as deseni kullanır.

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

OR Deseni

OR deseni, giriş verilerinin birden çok desen eşleştiğinde ve sonuç olarak aynı kodu çalıştırmak istediğinizde kullanılır.VEYA deseninin her iki tarafının türleri uyumlu olmalıdır.

Aşağıdaki örnek OR desenini gösterir.

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)

AND Deseni

VE deseni girişin iki deseni eşleştirmesini gerektirir.VE deseninin her iki tarafının türleri uyumlu olmalıdır.

Aşağıdaki örnek bu konunun ileriki kısımlarında yer alan Kayıt Düzeni Deseni bölümünde gösterilen detectZeroTuple gibidir, ancak burada VE deseni kullanılarak hem var1 hem de var2 değer olarak alınır.

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)

Olumsuz Desen

Olumsuz desen, bir listeyi ilk öğeye (head), geri kalan öğeleri içeren bir listeyi ise tail öğesine ayırmak için kullanılır.

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

Liste Deseni

Liste deseni listelerin çeşitli öğelere ayrıştırılmasını sağlar.Liste deseninin kendisi yalnızca belirli sayıda öğelerin listesiyle eşleşebilir.

// 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 [ ] )

Dizi Deseni

Dizi deseni, liste desenine benzer ve belirli uzunlukta diziler ayırmak için kullanılabilir.

// 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 [| |] )

Parantezlenmiş Desen

Parantez, istenen birleşimi elde etmek için desenler etrafında gruplandırılabilir.Aşağıdaki örnekte, parantezler bir AND deseni ve dönüşüm deseni arasındaki ilişkiyi denetlemek için kullanılır.

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

Tanımlama Grubu Düzeni

Kayıt düzeni deseni kayıt düzeni formunda girişle eşleşir ve kayıt düzenindeki her konum için desen eşleştirme değişkenlerini kullanarak kayıt düzeninin bileşen öğelerine ayrılmasına olanak verir.

Aşağıdaki örnek, kayıt düzeni desenini gösterir ve ayrıca değişmez değer desenleri, değişken desenler ve joker karakter deseni kullanır.

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)

Kayıt Düzeni

Kayıt düzeni, alanların değerlerini ayıklamak üzere kayıtları ayırmak için kullanılır.Desen, kaydın tüm alanlarına başvurmak zorunda değildir; atlanan tüm alanlar eşleşmeye katılmaz ve ayıklanmaz.

// 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"

Joker Karakter Deseni

Joker karakter deseni alt çizgi (_) karakteriyle gösterilir ve tıpkı değişken desen gibi herhangi bir girişle eşleşir (girişin bir değişkene atanması yerine atılması durumu hariç).Joker karakter deseni genellikle, -> simgesinin sağındaki ifadede gerekmeyen değerler için yer tutucu olarak diğer desenler içinde kullanılır.Joker karakter deseni, eşleşmeyen herhangi bir girişi eşleştirmek için bir desen listesinin sonunda da sık sık kullanılır.Joker karakter deseni, bu konudaki pek çok kod örneğinde gösterilmiştir.Bir örnek için önceki koda bakınız.

Tür Ek Açıklamaları Olan Desenler

Desenlerin, tür ek açıklamaları olabilir.Bunlar diğer türden ek açıklamalar gibi davranır ve çıkarmaları diğer tür ek açıklamalar gibi yapar.Desenlerdeki tür ek açıklamaları etrafına parantez gereklidir.Aşağıdaki kod, bir tür ek açıklamasına sahip bir deseni gösterir.

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

Test Desenini Yaz

Tür sınama deseni, girişi bir türle eşleştirmek için kullanılır.Girdi türü desende belirtilen bir eşleşme (veya türetilmiş bir tür) ise, eşleşme başarılı olur.

Aşağıdaki örnek tür testi desenini gösterir.

open System.Windows.Forms

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

Null Desen

Null desen, null değere izin veren türlere çalışırken görünebilen null değerle eşleşmektedir.Null desenler, sık sık .NET Framework kodu ile birlikte çalışma sırasında kullanılır.Örneğin bir .NET API'nin deri dönen değeri bir match ifadesine giriş olabilir.Dönüş değerinin null olup olmadığını ve döndürülen değerin diğer özelliklerini de temel alan program akışını denetleyebilirsiniz.Null değerlerinin programınızın kalanına yayılmasını önlemek için null desenini kullanabilirsiniz.

Aşağıdaki örnek, boş desen ve değişken deseni kullanır.

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()

Ayrıca bkz.

Başvuru

Eşleşme İfadeleri (F#)

Etkin Desenler (F#)

Diğer Kaynaklar

F# Dili Başvurusu