Module (F#)
Im Kontext der Programmiersprache F# ist ein Modul eine Gruppierung von F#-Code, z. B. Werte, Typen und Funktionswerte, in einem F#-Programm. Durch das Gruppieren von Code in Modulen kann zugehöriger Code zusammengehalten werden, und Namenskonflikte im Programm lassen sich leichter vermeiden.
// Top-level module declaration.
module [accessibility-modifier] [qualified-namespace.]module-name
declarations
// Local module declaration.
module [accessibility-modifier] module-name =
declarations
Hinweise
Ein F#-Modul ist eine Gruppierung von F#-Codekonstrukten, z. B. Typen, Werte, Funktionswerte und Code in do-Bindungen. Es wird als CLR (Common Language Runtime)-Klasse implementiert, die über ausschließlich statische Member verfügt. Es gibt zwei Typen von Moduldeklarationen, deren Verwendung davon abhängt, ob die gesamte Datei im Modul enthalten ist: Moduldeklaration der obersten Ebene und lokale Moduldeklaration. Mit einer Moduldeklaration der obersten Ebene wird die gesamte Datei in das Modul eingeschlossen. Eine Moduldeklaration der obersten Ebene muss als erste Deklaration in einer Datei enthalten sein.
In der Syntax für die Moduldeklaration der obersten Ebene ist der optionale qualified-namespace die Sequenz geschachtelter Namespacenamen, die das Modul enthält. Der qualifizierte Namespace muss nicht zuvor deklariert werden.
Für Moduldeklarationen der obersten Ebene ist kein Zeileneinzug erforderlich. In lokalen Modulen ist für alle Deklarationen ein Zeileneinzug erforderlich. In einer lokalen Moduldeklaration sind nur die Deklarationen mit Zeileneinzug unter einem Modul Teil dieses Moduls.
Wenn eine Codedatei nicht mit einer Moduldeklaration der obersten Ebene oder einer Namespacedeklaration beginnt, wird der gesamte Inhalt der Datei, einschließlich ggf. vorhandener lokaler Module, Teil eines implizit erstellten Moduls der obersten Ebene. Dieses verfügt über den gleichen Namen wie die Datei, jedoch ohne die Erweiterung, und der erste Buchstabe wird in einen Großbuchstaben konvertiert. Betrachten Sie beispielsweise die folgende Datei.
// In the file program.fs.
let x = 40
Diese Datei wird wie eine Datei kompiliert, die wie folgt geschrieben wurde:
module Program
let x = 40
Wenn eine Datei mehrere Module enthält, müssen Sie für jedes Modul eine lokale Moduldeklaration verwenden. Bei der Deklaration eines einschließenden Namespaces sind diese Module Teil des einschließenden Namespaces. Wenn kein einschließender Namespace deklariert ist, sind die Module Teil des implizit erstellten Moduls der obersten Ebene. Im folgenden Codebeispiel wird eine Codedatei veranschaulicht, die mehrere Module enthält. Der Compiler erstellt implizit ein Modul der obersten Ebene mit dem Namen Multiplemodules, und MyModule1 sowie MyModule2 werden in diesem Modul der obersten Ebene geschachtelt.
// 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)
Wenn mehrere Dateien in einem Projekt oder einer einzelnen Kompilierung vorhanden sind oder, wenn Sie eine Bibliothek erstellen, muss am Anfang der Datei eine Namespacedeklaration oder eine Moduldeklaration enthalten sein. Der F#-Compiler bestimmt einen Modulnamen nur dann implizit, wenn sich nur eine Datei in einem Projekt der einer Kompilierungsbefehlszeile befindet und Sie eine Anwendung erstellen.
Als accessibility-modifier kann einer der folgenden Modifizierer verwendet werden: public, private, internal. Weitere Informationen finden Sie unter Zugriffssteuerung (F#). Der Standard lautet public.
Verweisen auf Code in Modulen
Wenn Sie auf Funktionen, Typen und Werte aus einem anderen Modul verweisen, müssen Sie einen qualifizierten Namen verwenden oder das Modul öffnen. Wenn Sie einen qualifizierten Namen verwenden, müssen Sie die Namespaces, das Modul und den Bezeichner für das gewünschte Programmelement angeben. Die einzelnen Teile des qualifizierten Pfads werden wie folgt mit einem Punkt (.) getrennt.
Namespace1.Namespace2.ModuleName.Identifier
Sie können das Modul oder einen oder mehrere Namespaces öffnen, um den Code zu vereinfachen. Weitere Informationen zum Öffnen von Namespaces und Modulen finden Sie unter Importdeklarationen: Das open-Schlüsselwort (F#).
Das folgende Codebeispiel veranschaulicht ein Modul der obersten Ebene, das den gesamten Code bis zum Ende der Datei enthält.
module Arithmetic
let add x y =
x + y
let sub x y =
x - y
Wenn Sie diesen Code in einer anderen Datei des gleichen Projekts nutzen möchten, verwenden Sie qualifizierte Namen, oder Sie öffnen das Modul, bevor Sie die Funktionen verwenden, wie in den folgenden Beispielen gezeigt.
// Fully qualify the function name.
let result1 = Arithmetic.add 5 9
// Open the module.
open Arithmetic
let result2 = add 5 9
Geschachtelte Module
Module können geschachtelt werden. Innere Module müssen so weit wie äußere Moduldeklarationen eingezogen werden, um anzugeben, dass es sich um innere Module und nicht um neue Module handelt. Vergleichen Sie z. B. die folgenden beiden Beispiele. Im folgenden Code ist Modul Z ein inneres Modul.
module Y =
let x = 1
module Z =
let z = 5
Im folgenden Code ist Modul Z jedoch ein nebengeordnetes Element von Modul Y.
module Y =
let x = 1
module Z =
let z = 5
Im folgenden Code ist Modul Z ebenfalls ein nebengeordnetes Modul, da es nicht so weit eingezogen wie andere Deklarationen in Modul Y ist.
module Y =
let x = 1
module Z =
let z = 5
Wenn das äußere Modul über keine Deklarationen verfügt und eine andere Moduldeklaration direkt auf das Modul folgt, wird die neue Moduldeklaration als Deklaration eines inneren Moduls betrachtet. Jedoch gibt der Compiler eine Warnung aus, wenn die zweite Moduldefinition nicht weiter eingezogen ist als die erste Moduldeklaration.
// This code produces a warning, but treats Z as a inner module.
module Y =
module Z =
let z = 5
Ziehen Sie das innere Modul ein, um die Warnung zu vermeiden.
module Y =
module Z =
let z = 5
Wenn sich der gesamte Code in einer Datei in einem einzelnen äußeren Modul befinden soll und innere Module vorhanden sein sollen, ist für das äußere Modul kein Gleichheitszeichen erforderlich, und die Deklarationen, einschließlich aller Deklarationen innerer Module, die im äußeren Modul enthalten sein sollen, müssen nicht eingezogen werden. Deklarationen innerhalb der Deklarationen innerer Module müssen eingezogen werden. Dieser Fall wird im folgenden Code veranschaulicht.
// 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