Modül
F# bağlamında modül, F# programında değerler, türler ve işlev değerleri gibi bir F# kodu gruplandırmasıdır. Kodları modüllerde gruplandırmak, ilgili kodu bir arada tutmaya yardımcı olur ve programınızdaki ad çakışmalarını önlemeye yardımcı olur.
Sözdizimi
// Top-level module declaration.
module [accessibility-modifier] [qualified-namespace.]module-name
declarations
// Local module declaration.
module [accessibility-modifier] module-name =
declarations
Açıklamalar
F# modülü, bağlamalardaki do
türler, değerler, işlev değerleri ve kod gibi F# kod yapılarının bir gruplandırmasıdır. Yalnızca statik üyeleri olan bir ortak dil çalışma zamanı (CLR) sınıfı olarak uygulanır. Dosyanın tamamının modüle eklenip eklenmediğine bağlı olarak iki tür modül bildirimi vardır: en üst düzey modül bildirimi ve yerel modül bildirimi. Üst düzey modül bildirimi, modüldeki dosyanın tamamını içerir. Üst düzey modül bildirimi yalnızca dosyadaki ilk bildirim olarak görünebilir.
Üst düzey modül bildiriminin söz diziminde isteğe bağlı nitelikli ad alanı , modülü içeren iç içe ad alanı adları dizisidir. Nitelenmiş ad alanının daha önce bildirilmesi gerekmez.
En üst düzey modülde bildirimleri girintili yapmanız gerekmez. Yerel modüllerdeki tüm bildirimleri girintili yapmanız gerekir. Yerel modül bildiriminde, modülün yalnızca bu modül bildirimi altında girintili bildirimler yer alır.
Kod dosyası en üst düzey modül bildirimi veya ad alanı bildirimiyle başlamazsa, yerel modüller de dahil olmak üzere dosyanın tüm içeriği, uzantı olmadan dosyayla aynı ada sahip örtük olarak oluşturulmuş bir üst düzey modülün parçası olur ve ilk harf büyük harfe dönüştürülür. Örneğin, aşağıdaki dosyayı göz önünde bulundurun.
// In the file program.fs.
let x = 40
Bu dosya şu şekilde yazılmış gibi derlenebilir:
module Program
let x = 40
Bir dosyada birden çok modül varsa, her modül için yerel bir modül bildirimi kullanmanız gerekir. Kapsayan bir ad alanı bildirilirse, bu modüller kapsayan ad alanının bir parçasıdır. Kapsayan bir ad alanı bildirilmezse, modüller örtük olarak oluşturulan üst düzey modülün parçası olur. Aşağıdaki kod örneği, birden çok modül içeren bir kod dosyasını gösterir. Derleyici örtük olarak ve MyModule1
adlı Multiplemodules
bir üst düzey modül oluşturur ve MyModule2
bu üst düzey modülde iç içe yerleştirilmiştir.
// In the file multiplemodules.fs.
// MyModule1
module MyModule1 =
// Indent all program elements within modules that are declared with an equal sign.
let module1Value = 100
let module1Function x =
x + 10
// MyModule2
module MyModule2 =
let module2Value = 121
// Use a qualified name to access the function.
// from MyModule1.
let module2Function x =
x * (MyModule1.module1Function module2Value)
Bir projede veya tek bir derlemede birden çok dosyanız varsa veya kitaplık oluşturuyorsanız, dosyanın en üstüne bir ad alanı bildirimi veya modül bildirimi eklemeniz gerekir. F# derleyicisi, bir proje veya derleme komut satırında yalnızca bir dosya olduğunda ve bir uygulama oluştururken yalnızca bir modül adını örtük olarak belirler.
Erişilebilirlik değiştirici aşağıdakilerden biri olabilir: public
, private
, internal
. Daha fazla bilgi için bkz. Erişim Denetimi. Varsayılan değer geneldir.
Modüllerde Koda Başvurma
Başka bir modüldeki işlevlere, türlere ve değerlere başvururken, tam adı kullanmanız veya modülü açmanız gerekir. Nitelenmiş bir ad kullanırsanız, istediğiniz program öğesinin ad alanlarını, modülünü ve tanımlayıcısını belirtmeniz gerekir. Uygun yolun her bir bölümünü aşağıda gösterildiği gibi bir noktayla (.) ayırırsınız.
Namespace1.Namespace2.ModuleName.Identifier
Kodu basitleştirmek için modülü veya bir veya daha fazla ad alanını açabilirsiniz. Ad alanlarını ve modülleri açma hakkında daha fazla bilgi için bkz . İçeri Aktarma Bildirimleri: Anahtar open
Sözcük.
Aşağıdaki kod örneği, dosyanın sonuna kadar olan tüm kodu içeren bir üst düzey modülü gösterir.
module Arithmetic
let add x y =
x + y
let sub x y =
x - y
Bu kodu aynı projedeki başka bir dosyadan kullanmak için, nitelenmiş adlar kullanırsınız veya aşağıdaki örneklerde gösterildiği gibi işlevleri kullanmadan önce modülü açarsınız.
// Fully qualify the function name.
let result1 = Arithmetic.add 5 9
// Open the module.
open Arithmetic
let result2 = add 5 9
İç İçe Modüller
Modüller iç içe yerleştirilebilir. İç modüllerin, yeni modüller değil iç modüller olduğunu belirtmek için dış modül bildirimlerine kadar girintili olması gerekir. Örneğin, aşağıdaki iki örneği karşılaştırın. Modül Z
, aşağıdaki kodda yer alan bir iç modüldür.
module Y =
let x = 1
module Z =
let z = 5
Ancak modül Z
, aşağıdaki kodda modüle Y
eşdüzeydir.
module Y =
let x = 1
module Z =
let z = 5
Modül Z
, modüldeki diğer bildirimlere kadar girintilenmediğinden aşağıdaki kodda eşdüzey bir modüldür Y
.
module Y =
let x = 1
module Z =
let z = 5
Son olarak, dış modülün bildirimi yoksa ve hemen ardından başka bir modül bildirimi gelirse, yeni modül bildiriminin bir iç modül olduğu varsayılır, ancak ikinci modül tanımı ilkinden daha girintili değilse derleyici sizi uyarır.
// This code produces a warning, but treats Z as a inner module.
module Y =
module Z =
let z = 5
Uyarıyı ortadan kaldırmak için iç modülü girintileyin.
module Y =
module Z =
let z = 5
Bir dosyadaki tüm kodun tek bir dış modülde olmasını ve iç modüllerin olmasını istiyorsanız, dış modülde eşittir işareti gerekmez ve dış modülde yer alacak iç modül bildirimleri de dahil olmak üzere bildirimlerin girintili olması gerekmez. İç modül bildirimleri içindeki bildirimlerin girintili olması gerekir. Aşağıdaki kodda bu durum gösterilmektedir.
// The top-level module declaration can be omitted if the file is named
// TopLevel.fs or topLevel.fs, and the file is the only file in an
// application.
module TopLevel
let topLevelX = 5
module Inner1 =
let inner1X = 1
module Inner2 =
let inner2X = 5
Özyinelemeli modüller
F# 4.1, tüm kapsanan kodların karşılıklı olarak özyinelemeli olmasını sağlayan modüller için bir yaklaşım sunar. Bu işlem aracılığıyla module rec
yapılır. kullanımı module rec
, türler ve modüller arasında karşılıklı bilgi kodu yazamamayla ilgili bazı sorunları hafifletebilir. Bunun bir örneği aşağıda verilmiştir:
module rec RecursiveModule =
type Orientation = Up | Down
type PeelState = Peeled | Unpeeled
// This exception depends on the type below.
exception DontSqueezeTheBananaException of Banana
type Banana(orientation : Orientation) =
member val Orientation = orientation with get, set
member val Sides: PeelState list = [ Unpeeled; Unpeeled; Unpeeled; Unpeeled ] with get, set
member self.IsPeeled =
self.Sides |> List.forall ((=) Peeled)
member self.Peel() =
BananaHelpers.peel self
|> fun peeledSides -> self.Sides <- peeledSides
member self.SqueezeJuiceOut() =
raise (DontSqueezeTheBananaException self)
module BananaHelpers =
let peel (banana: Banana) =
let flip (banana: Banana) =
match banana.Orientation with
| Up ->
banana.Orientation <- Down
banana
| Down -> banana
let peelSides (banana: Banana) =
banana.Sides
|> List.map (function
| Unpeeled -> Peeled
| Peeled -> Peeled)
banana |> flip |> peelSides
Özel durumun DontSqueezeTheBananaException
ve sınıfın Banana
her ikisinin de birbirine başvurduğunu unutmayın. Ayrıca modül BananaHelpers
ve sınıfı Banana
da birbirine başvurur. Anahtar sözcüğünü modülden RecursiveModule
kaldırdıysanız rec
F# ile ifade etmek mümkün olmaz.
Bu özellik F# 4.1 ile Ad Alanları'nda da mümkündür.