Esnek Türler

Esnek tür ek açıklaması, parametrenin, değişkenin veya değerin belirtilen türle uyumlu bir türe sahip olduğunu ve burada uyumluluğun nesne odaklı sınıf veya arabirim hiyerarşisindeki konuma göre belirlendiğini belirtir. Esnek türler, özellikle tür hiyerarşisindeki daha yüksek türlere otomatik dönüştürme gerçekleşmediğinde yararlıdır, ancak yine de işlevselliğinizin hiyerarşideki herhangi bir türle veya arabirim uygulayan herhangi bir türle çalışmasını sağlamak istediğinizde kullanışlıdır.

Sözdizimi

#type

Açıklamalar

Önceki söz diziminde, tür bir temel türü veya arabirimi temsil eder.

Esnek tür, izin verilen türleri temel veya arabirim türüyle uyumlu türlerle sınırlayan bir kısıtlaması olan genel bir türe eşdeğerdir. Yani, aşağıdaki iki kod satırı eşdeğerdir.

#SomeType

'T when 'T :> SomeType

Esnek türler çeşitli durumlarda kullanışlıdır. Örneğin, daha yüksek bir order işlevine (işlevi bağımsız değişken olarak alan bir işlev) sahip olduğunuzda, işlevin esnek bir tür döndürmesi genellikle yararlıdır. Aşağıdaki örnekte, içinde bir sıra bağımsız değişkeniyle iterate2 esnek bir tür kullanılması, daha yüksek sıralı işlevin diziler, diziler, listeler ve diğer numaralandırılabilir türler oluşturan işlevlerle çalışmasını sağlar.

Biri bir sıra, diğeri esnek bir tür döndüren aşağıdaki iki işlevi göz önünde bulundurun.

let iterate1 (f : unit -> seq<int>) =
    for e in f() do printfn "%d" e
let iterate2 (f : unit -> #seq<int>) =
    for e in f() do printfn "%d" e

// Passing a function that takes a list requires a cast.
iterate1 (fun () -> [1] :> seq<int>)

// Passing a function that takes a list to the version that specifies a
// flexible type as the return value is OK as is.
iterate2 (fun () -> [1])

Başka bir örnek olarak, Seq.concat library işlevini göz önünde bulundurun:

val concat: sequences:seq<#seq<'T>> -> seq<'T>

Aşağıdaki numaralandırılabilir dizilerden herhangi birini bu işleve geçirebilirsiniz:

  • Liste listesi
  • Dizilerin listesi
  • Liste dizisi
  • Dizi dizisi
  • Numaralandırılabilir dizilerin diğer birleşimleri

Aşağıdaki kod, esnek türleri kullanarak destekleyebileceğiniz senaryoları göstermek için kullanır Seq.concat .

let list1 = [1;2;3]
let list2 = [4;5;6]
let list3 = [7;8;9]

let concat1 = Seq.concat [ list1; list2; list3]
printfn "%A" concat1

let array1 = [|1;2;3|]
let array2 = [|4;5;6|]
let array3 = [|7;8;9|]

let concat2 = Seq.concat [ array1; array2; array3 ]
printfn "%A" concat2

let concat3 = Seq.concat [| list1; list2; list3 |]
printfn "%A" concat3

let concat4 = Seq.concat [| array1; array2; array3 |]
printfn "%A" concat4

let seq1 = { 1 .. 3 }
let seq2 = { 4 .. 6 }
let seq3 = { 7 .. 9 }

let concat5 = Seq.concat [| seq1; seq2; seq3 |]

printfn "%A" concat5

Çıktı aşağıdaki gibidir:

seq [1; 2; 3; 4; ...]
seq [1; 2; 3; 4; ...]
seq [1; 2; 3; 4; ...]
seq [1; 2; 3; 4; ...]
seq [1; 2; 3; 4; ...]

F# dilinde, diğer nesne odaklı dillerde olduğu gibi, arabirimleri uygulayan türetilmiş türlerin veya türlerin otomatik olarak bir temel türe veya arabirim türüne dönüştürüldüğü bağlamlar vardır. Bu otomatik dönüştürmeler doğrudan bağımsız değişkenlerde gerçekleşir, ancak tür bir alt konumdayken, işlev türünün dönüş türü veya tür bağımsız değişkeni gibi daha karmaşık bir türün parçası olarak gerçekleşmez. Bu nedenle, esnek tür gösterimi, uyguladığınız tür daha karmaşık bir türün parçası olduğunda öncelikli olarak yararlıdır.

Ayrıca bkz.