Modül
F # bağlamında, bir Modül f # programında değerler, türler ve işlev değerleri gibi f # kodu gruplandırmasıdır. Modüllerde kod gruplandırma, ilgili kodu birlikte tutmaya yardımcı olur ve programınızda ad çakışmalarını önlemeye yardımcı olur.
Syntax
// 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ü türler, değerler, işlev değerleri ve bağlamalardaki kod gibi F # kod yapılarının bir gruplandırmasıdır do . Yalnızca statik üyelere sahip ortak dil çalışma zamanı (CLR) sınıfı olarak uygulanır. Tüm dosyanın modüle dahil edilip edilmeyeceğini bağlı olarak iki tür modül bildirimi vardır: en üst düzey modül bildirimi ve yerel bir modül bildirimi. Üst düzey modül bildirimi, modülün tüm dosyasını içerir. En üst düzey modül bildirimi, yalnızca bir dosyadaki ilk bildirim olarak görünebilir.
Üst düzey modül bildiriminin sözdiziminde, isteğe bağlı nitelikli ad alanı , modülünü içeren iç içe ad alanı adlarının sırasıdır. Nitelenmiş ad alanının önceden bildirilmesine izin yoktur.
Üst düzey modüldeki bildirimleri girintilemek zorunda değilsiniz. Yerel modüllerdeki tüm bildirimlerin girintisini almanız gerekir. Yerel bir modül bildiriminde, yalnızca söz konusu modül bildiriminde girintili olan bildirimler modülün bir parçasıdır.
Bir kod dosyası en üst düzey bir modül bildirimiyle veya bir ad alanı bildirimiyle başlamamışsa, dosyanın tamamı tüm yerel modüller dahil olmak üzere, uzantısı olmadan dosya ile aynı ada sahip örtük olarak oluşturulmuş bir en üst düzey modülün bir parçası haline gelir ve ilk harfi 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 bu şekilde yazılmış gibi derlenir:
module Program
let x = 40
Bir dosyada birden çok modülünüz 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ı bildirilmemiş ise, modüller örtük olarak oluşturulan en üst düzey modülün bir parçası haline gelir. Aşağıdaki kod örneği, birden çok modül içeren bir kod dosyası gösterir. Derleyici örtük olarak adlı bir üst düzey modül oluşturur ve Multiplemodules MyModule1 MyModule2 Bu üst düzey modülde iç içe geçmiş.
// 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 dosya varsa veya bir kitaplık oluşturuyorsanız, dosyanın üst kısmına bir ad alanı bildirimi veya modül bildirimi eklemeniz gerekir. F # derleyicisi yalnızca bir proje veya derleme komut satırında yalnızca bir dosya olduğunda ve bir uygulama oluşturuyorsanız bir modül adını yalnızca örtülü 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ülden işlevlere, türlere ve değerlere başvuru yaptığınızda tam adı kullanmanız veya modülünü açmanız gerekir. Nitelikli bir ad kullanırsanız, istediğiniz program öğesi için ad alanlarını, modülü ve tanımlayıcıyı belirtmeniz gerekir. Tam yolun her bölümünü aşağıdaki gibi bir nokta (.) ile ayırın.
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. Içeri aktarma bildirimleri: open anahtar sözcüğü.
Aşağıdaki kod örneğinde, dosyanın sonuna kadar olan tüm kodu içeren bir üst düzey modül gösterilmektedir.
module Arithmetic
let add x y =
x + y
let sub x y =
x - y
Aynı projedeki başka bir dosyadan bu kodu kullanmak için, aşağıdaki örneklerde gösterildiği gibi, işlevleri kullanmadan önce nitelikli adları kullanırsınız veya 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
İç içe modüller
Modüller iç içe olabilir. İç modüller, yeni modüller değil, iç modüller olduğunu göstermek için dış modül bildirimlerinin en çok olarak girintilenmelidir. Örneğin, aşağıdaki iki örneği karşılaştırın. Modül, Z aşağıdaki kodda yer aldığı bir iç modüldür.
module Y =
let x = 1
module Z =
let z = 5
Ancak modül Z aşağıdaki kodda bir eşdüzey modüldür Y .
module Y =
let x = 1
module Z =
let z = 5
Modül, Z modüldeki diğer bildirimlerde olduğu kadar girintili olmadığından, aşağıdaki kodda bir eşdüzey modüldür Y .
module Y =
let x = 1
module Z =
let z = 5
Son olarak, dış modülün bildirimi yoksa ve daha sonra başka bir modül bildirimi tarafından hemen ardından, yeni modül bildiriminin bir iç modül olduğu varsayılır, ancak ikinci modül tanımı birinciden daha uzağa girintilenmez 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ün girintisini artırın.
module Y =
module Z =
let z = 5
Bir dosyadaki tüm kodun tek bir dış modülde olmasını ve iç modüller olmasını istiyorsanız, dıştaki modül eşittir işaretine gerek yoktur ve dış modülün içindeki tüm iç modül bildirimleri de dahil olmak üzere, bu bildirimlerin girintileneceği bir girinti olması gerekmez. İç modül bildirimlerinin içindeki bildirimlerin girintili olması gerekir. Aşağıdaki kod bu durumu gösterir.
// 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, içerilen tüm kodların birbirini karşılıklı olarak özyinelemeli olmasını sağlayan modüller kavramını sunar. Bu, aracılığıyla yapılır module rec . Kullanımı, module rec ve modülleri arasında karşılıklı başvuru kodu yazamayacak bazı paıns 'leri hafifme edebilir. Aşağıda buna bir örnek 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 IsPeeled = false with get, set
member val Orientation = orientation with get, set
member val Sides: PeelState list = [ Unpeeled; Unpeeled; Unpeeled; Unpeeled] with get, set
member self.Peel() = BananaHelpers.peel self // Note the dependency on the BananaHelpers module.
member self.SqueezeJuiceOut() = raise (DontSqueezeTheBananaException self) // This member depends on the exception above.
module BananaHelpers =
let peel (b: 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)
match b.Orientation with
| Up -> b |> flip |> peelSides
| Down -> b |> peelSides
Özel durumun DontSqueezeTheBananaException ve sınıfın her Banana ikisi de birbirine başvurmadığını unutmayın. Ayrıca, modülü BananaHelpers ve sınıfı Banana birbirini da ifade eder. Anahtar sözcüğünü modülden kaldırdıysanız, bu, F # ' ta Express gerçekleştirilemez rec RecursiveModule .
Bu özellik, F # 4,1 ile ad alanlarında da mümkündür.