Aracılığıyla paylaş


Otomatik genelleştirmesi (F#)

F# tür kesmesi, işlevleri ve deyimleri türleri değerlendirmek için kullanır. Bu konuda, mümkün olduğunda birden çok türleri ile çalışırlar böylece nasıl F# otomatik olarak bağımsız değişkenleri ve işlevleri türleri generalizes açıklanmaktadır.

Otomatik genelleştirmesi

Tür kesmesi bir işlevi gerçekleştirdiğinde F# derleyicisi, belirli bir parametreyi genel olup olamayacağını belirler. Derleyici her parametre inceler ve işlevi bu parametrenin belirli türüne bağımlı olup olmadığını belirler. Yoksa, türü genel olarak algılanır.

Aşağıdaki kod örneği, genel olarak derleyici yorumlar işlevini göstermektedir.

let max a b = if a > b then a else b

Türü olarak algılanır 'a -> 'a -> 'a.

Türü bilinmeyen aynı türden iki baðýmsýz deðiþken alýr ve aynı türde bir değer döndüren bir işlev olduğunu gösterir. Önceki işlevi olabilir nedenlerinden biri genel, büyük-operatörüne (>) kendisini geneldir. Büyük-imza işleci olan 'a -> 'a -> bool. Bütün işleçler genel olan ve kod, bir işlev parametre türü ile birlikte genel olmayan işlev veya işleç kullanıyorsa, bu parametre türü Genelleştirilmiş olamaz.

Çünkü max olan genel, türleriyle gibi kullanılmadan int, float, vb., aşağıdaki örneklerde gösterildiği gibi.

let biggestFloat = max 2.0 3.0
let biggestInt = max 2 3

Ancak, iki bağımsız değişken aynı türde olması gerekir. İmza 'a -> 'a -> 'ayerine 'a -> 'b -> 'a. Bu nedenle, türleri eşleşmediğinden aşağıdaki kod bir hata üretir.

// Error: type mismatch.
let biggestIntFloat = max 2.0 3

max İşlevi de büyük destekleyen herhangi bir türü ile çalışır-operatörüne. Bu nedenle de, bir dize aşağıdaki kodda gösterildiği gibi kullanabilirsiniz.

let testString = max "cab" "cat"

Değer kısıtlaması

Derleyici otomatik genelleştirmesi açýk baðýmsýz deðiþkeni olan tam işlev tanımları ve basit sabit değerler gerçekleştirir.

Buna göre yeteri kadar belirli bir tür olması zorunlu değildir, ancak aynı zamanda generalizable değil kodu derleyin denerseniz, derleyici bir hata verir. Bu kısıtlama değerleri otomatik genelleştirmesi üzerinde hata iletisi bu sorun için başvurduğu değer kısıtlaması.

Genellikle, bir yapı genel olmasını istediğiniz halde derleyici onu generalize için yeterli bilgi yok veya içinde bulunuyorlar yapısında yeterli türü bilgileri istemeden atladığınızda değer kısıtlaması hata oluşur. Değer kısıtlaması hata çözümü türü kesmesi sorun aşağıdaki yollardan biriyle daha tam olarak sınırlamak için daha kesin bilgiler sağlamaktır:

  • Bir tür açık tür ek bir değer veya parametre ekleyerek içinde bulunuyorlar olacak şekilde sınırlamak.

  • Sorun nongeneralizable yapı işlev kompozisyon gibi genel bir işlev tanımlamak için kullandığı veya curried fonksiyon bağımsız değişkenleri eksik olarak uygulanan, normal işlev tanımı işlevi yeniden deneyin.

  • Sorun Genelleştirilmiş için çok karmaşık bir deyim ise, ilave, kullanılmayan parametresini ekleyerek bir işlevdeki olun.

  • Açık genel tür parametreleri ekleyin. Bu seçenek nadiren kullanılır.

  • Aşağıdaki kod örnekleri aşağıdaki senaryolardan her biri görülmektedir.

Durum 1: Bir ifade çok karmaşık. Bu örnekte, liste counter olması amaçlanmıştır int option ref, ancak basit bir sabit değer tanımlı değil.

let counter = ref None
// Adding a type annotation fixes the problem:
let counter : int option ref = ref None

Durum 2: Genel işlevini tanımlamak için bir nongeneralizable yapı kullanma. Fonksiyon bağımsız değişkenleri kısmi uygulama hattınızda Bu örnekte, nongeneralizable yapısıdır.

let maxhash = max << hash
// The following is acceptable because the argument for maxhash is explicit:
let maxhash obj = (max << hash) obj

Durum 3: ilave, kullanılmayan bir parametre ekleme. Bu ifade genelleştirmesi için yeteri kadar basit olmadığı için derleyici değer kısıtlaması hata verir.

let emptyList10 = Array.create 10 []
// Adding an extra (unused) parameter makes it a function, which is generalizable.
let emptyList10 () = Array.create 10 []

Durum 4: Tür parametreleri ekleme.

let arrayOf10Lists = Array.create 10 []
// Adding a type parameter and type annotation lets you write a generic value.
let arrayOf10Lists<'T> = Array.create 10 ([]:'T list)

Son durumda, değer gibi pek çok farklı tipin değerlerini örnek oluşturmak için kullanılabilir bir tür işlev olur:

let intLists = arrayOf10Lists<int>
let floatLists = arrayOf10Lists<float>

Ayrıca bkz.

Başvuru

Tür kesmesi (F#)

Generics (F#)

Tür parametreleri (F#) statik olarak çözüldü

Kısıtlamaları (F#)