Genel Türler
F# işlevi değerleri, yöntemleri, özellikleri ve sınıflar, kayıtlar ve ayrımcı birleşimler gibi toplama türleri genel olabilir. Genel yapılar, genellikle genel yapı kullanıcısı tarafından sağlanan en az bir tür parametresi içerir. Genel işlevler ve türler, her tür için kodu yinelemeden çeşitli türlerle çalışan kod yazmanızı sağlar. Kodunuzun genellikle derleyicinin tür çıkarımı ve otomatik genelleştirme mekanizmaları tarafından örtük olarak genel olduğu algılandığından kodunuzun genel hale getirilmesi F# dilinde basit olabilir.
Syntax
// Explicitly generic function.
let function-name<type-parameters> parameter-list =
function-body
// Explicitly generic method.
[ static ] member object-identifier.method-name<type-parameters> parameter-list [ return-type ] =
method-body
// Explicitly generic class, record, interface, structure,
// or discriminated union.
type type-name<type-parameters> type-definition
Açıklamalar
Açıkça genel bir işlevin veya türün bildirimi, işlev veya tür adından sonraki açılı ayraçlarda tür parametrelerinin belirtimi (ve kullanımı) dışında, genel olmayan bir işlev veya türün bildirimine çok benzer.
Bildirimler genellikle örtük olarak geneldir. Bir işlev veya tür oluşturmak için kullanılan her parametrenin türünü tam olarak belirtmezseniz, derleyici yazdığınız koddan her parametrenin, değerin ve değişkenin türünü çıkarsamaya çalışır. Daha fazla bilgi için bkz . Tür Çıkarımı. Türünüzün veya işlevinizin kodu parametre türlerini başka bir şekilde kısıtlamıyorsa, işlev veya tür örtük olarak geneldir. Bu işleme otomatik genelleştirme adı verilmiştir. Otomatik genelleştirmenin bazı sınırları vardır. Örneğin, F# derleyicisi genel bir yapı için türleri çıkaramıyorsa, derleyici değer kısıtlaması adlı bir kısıtlamaya başvuran bir hata bildirir. Bu durumda, bazı tür ek açıklamaları eklemeniz gerekebilir. Otomatik genelleştirme ve değer kısıtlaması hakkında daha fazla bilgi ve sorunu çözmek için kodunuzu değiştirme hakkında daha fazla bilgi için bkz. Otomatik Genelleştirme.
Önceki söz diziminde type-parameters , bilinmeyen türleri temsil eden ve her biri tek tırnak işaretiyle başlayan ve isteğe bağlı olarak bu tür parametresi için hangi türlerin kullanılabileceğini sınırlayan bir kısıtlama yan tümcesiyle virgülle ayrılmış bir parametre listesidir. Çeşitli türlerdeki kısıtlama yan tümcelerinin söz dizimi ve kısıtlamalar hakkında diğer bilgiler için bkz. Kısıtlamalar.
Söz dizimindeki tür tanımı , genel olmayan bir türün tür tanımıyla aynıdır. Sınıf türü için oluşturucu parametrelerini, isteğe bağlı as
yan tümcesini, eşittir simgesini, kayıt alanlarını, yan tümcesini, inherit
ayrımcı let
birleşim seçeneklerini ve do
bağlamaları, üye tanımlarını ve genel olmayan bir tür tanımında izin verilen diğer her şeyi içerir.
Diğer söz dizimi öğeleri, genel olmayan işlevler ve türler için kullanılanlarla aynıdır. Örneğin, object-identifier , içeren nesnenin kendisini temsil eden bir tanımlayıcıdır.
Özellikler, alanlar ve oluşturucular kapsayan türden daha genel olamaz. Ayrıca, bir modüldeki değerler genel olamaz.
Örtük Genel Yapılar
F# derleyicisi kodunuzdaki türleri çıkarsadığında, genel olabilecek tüm işlevleri otomatik olarak işler. Parametre türü gibi bir türü açıkça belirtirseniz, otomatik genelleştirmeyi engellersiniz.
Aşağıdaki kod örneğinde, makeList
ne genel ne de parametreleri açıkça genel olarak bildirilmez olsa da geneldir.
let makeList a b =
[a; b]
işlevinin imzası olarak çıkarsanır 'a -> 'a -> 'a list
. Bu örnekte ve b
değerlerinin a
aynı türe sahip olduğunu unutmayın. Bunun nedeni, bunların bir listeye birlikte eklenmesi ve listenin tüm öğelerinin aynı türde olmasıdır.
Ayrıca, bir parametre türünün genel tür parametresi olduğunu belirtmek için tür ek açıklamasında tek tırnak işareti söz dizimini kullanarak işlevi genel hale getirebilirsiniz. Aşağıdaki kodda, function1
parametreleri tür parametreleri olarak bu şekilde bildirildiğinden geneldir.
let function1 (x: 'a) (y: 'a) =
printfn "%A %A" x y
Açıkça Genel Yapılar
Ayrıca, bir işlevin tür parametrelerini açılı ayraçlarda (<type-parameter>
) açıkça bildirerek de genel hale getirebilirsiniz. Aşağıdaki kodda bu gösterilir.
let function2<'T> (x: 'T) (y: 'T) =
printfn "%A, %A" x y
Genel Yapıları Kullanma
Genel işlevleri veya yöntemleri kullandığınızda, tür bağımsız değişkenlerini belirtmeniz gerekmeyebilir. Derleyici, uygun tür bağımsız değişkenlerini çıkarsamak için tür çıkarımı kullanır. Hala bir belirsizlik varsa, birden çok tür bağımsız değişkenini virgülle ayırarak, tür bağımsız değişkenlerini açılı ayraçlar halinde sağlayabilirsiniz.
Aşağıdaki kod, önceki bölümlerde tanımlanan işlevlerin kullanımını gösterir.
// In this case, the type argument is inferred to be int.
function1 10 20
// In this case, the type argument is float.
function1 10.0 20.0
// Type arguments can be specified, but should only be specified
// if the type parameters are declared explicitly. If specified,
// they have an effect on type inference, so in this example,
// a and b are inferred to have type int.
let function3 a b =
// The compiler reports a warning:
function1<int> a b
// No warning.
function2<int> a b
Not
Genel türe ada göre başvurmanın iki yolu vardır. Örneğin, list<int>
tek int list
tür bağımsız değişkeni int
olan genel bir türe list
başvurmanın iki yolu vardır. İkinci form geleneksel olarak yalnızca ve option
gibi list
yerleşik F# türleriyle kullanılır. Birden çok tür bağımsız değişkeni varsa, normalde söz dizimini Dictionary<int, string>
kullanırsınız, ancak söz dizimini (int, string) Dictionary
de kullanabilirsiniz.
Tür Bağımsız Değişkenleri Olarak Joker Karakterler
Bir tür bağımsız değişkeninin derleyici tarafından çıkarılacağını belirtmek için, adlandırılmış tür bağımsız değişkeni yerine alt çizgi veya joker karakter simgesini ()_
kullanabilirsiniz. Bu, aşağıdaki kodda gösterilmiştir.
let printSequence (sequence1: Collections.seq<_>) =
Seq.iter (fun elem -> printf "%s " (elem.ToString())) sequence1
Genel Tür ve İşlevlerdeki Kısıtlamalar
Genel bir tür veya işlev tanımında, yalnızca genel tür parametresinde kullanılabilir olduğu bilinen yapıları kullanabilirsiniz. Derleme zamanında işlev ve yöntem çağrılarının doğrulanmasını etkinleştirmek için bu gereklidir. Tür parametrelerinizi açıkça bildirirseniz, derleyiciye belirli yöntemlerin ve işlevlerin kullanılabilir olduğunu bildirmek için genel tür parametresine açık bir kısıtlama uygulayabilirsiniz. Ancak, F# derleyicisinin genel parametre türlerinizi çıkarmasına izin verirseniz, sizin için uygun kısıtlamaları belirler. Daha fazla bilgi için bkz. Kısıtlamalar.
Statik Olarak Çözümlenmiş Tür Parametreleri
F# programlarında kullanılabilecek iki tür parametre türü vardır. birincisi, önceki bölümlerde açıklanan türdeki genel tür parametreleridir. Bu ilk tür parametresi türü, Visual Basic ve C# gibi dillerde kullanılan genel tür parametrelerine eşdeğerdir. Başka bir tür parametresi F# değerine özgüdür ve statik olarak çözümlenmiş tür parametresi olarak adlandırılır. Bu yapılar hakkında bilgi için bkz. Statik Olarak Çözümlenen Tür Parametreleri.
Örnekler
// A generic function.
// In this example, the generic type parameter 'a makes function3 generic.
let function3 (x : 'a) (y : 'a) =
printf "%A %A" x y
// A generic record, with the type parameter in angle brackets.
type GR<'a> =
{
Field1: 'a;
Field2: 'a;
}
// A generic class.
type C<'a>(a : 'a, b : 'a) =
let z = a
let y = b
member this.GenericMethod(x : 'a) =
printfn "%A %A %A" x y z
// A generic discriminated union.
type U<'a> =
| Choice1 of 'a
| Choice2 of 'a * 'a
type Test() =
// A generic member
member this.Function1<'a>(x, y) =
printfn "%A, %A" x y
// A generic abstract method.
abstract abstractMethod<'a, 'b> : 'a * 'b -> unit
override this.abstractMethod<'a, 'b>(x:'a, y:'b) =
printfn "%A, %A" x y