Importdeklarationen: Das open
-Schlüsselwort
Eine Importdeklaration gibt ein Modul oder einen Namespace an, auf dessen Elemente Sie ohne Angabe eines vollqualifizierten Namens verweisen können.
Syntax
open module-or-namespace-name
open type type-name
Bemerkungen
Wenn Sie bei jedem Codeverweis den vollqualifizierten Namespace oder Modulpfad angeben, kann das die Übersichtlichkeit und Verwaltung des Codes beeinträchtigen. Stattdessen können Sie die open
-Schlüsselwort für häufig verwendete Module und Namespaces verwenden, durch das Sie beim Verweisen auf ein Element dieses Moduls oder Namespaces anstelle des vollqualifizierten Namens die Kurzform des Namens verwenden können. Diese Schlüsselwort ähnelt dem using
-Schlüsselwort in C#, using namespace
in Visual C++ und Imports
in Visual Basic.
Das angegebene Modul oder der angegebene Namespace muss sich im selben Projekt oder in einem Projekt oder einer Assembly befinden, auf das bzw. die verwiesen wird. Andernfalls können Sie einen Verweis auf das Projekt hinzufügen oder die Befehlszeilenoption -reference
(oder deren Kurzform -r
) verwenden. Weitere Informationen finden Sie unter Compileroptionen.
Die Importdeklaration stellt die Namen im Code zur Verfügung, der der Deklaration folgt, bis zum Ende des einschließenden Namespaces, Moduls oder der einschließenden Datei.
Wenn Sie mehrere Importdeklarationen verwenden, sollten diese sich in separaten Zeilen befinden.
Der folgende Code zeigt die Verwendung des open
-Schlüsselworts, um Code zu vereinfachen.
// Without the import declaration, you must include the full
// path to .NET Framework namespaces such as System.IO.
let writeToFile1 filename (text: string) =
let stream1 = new System.IO.FileStream(filename, System.IO.FileMode.Create)
let writer = new System.IO.StreamWriter(stream1)
writer.WriteLine(text)
// Open a .NET Framework namespace.
open System.IO
// Now you do not have to include the full paths.
let writeToFile2 filename (text: string) =
let stream1 = new FileStream(filename, FileMode.Create)
let writer = new StreamWriter(stream1)
writer.WriteLine(text)
writeToFile2 "file1.txt" "Testing..."
Der F#-Compiler gibt keinen Fehler und keine Warnung aus, wenn Mehrdeutigkeiten auftreten, weil derselbe Name in mehreren geöffneten Modulen oder Namespaces auftritt. Wenn Mehrdeutigkeiten auftreten, gibt F# dem zuletzt geöffneten Modul oder Namespace den Vorzug. Beispielsweise bedeutet empty
im folgenden Code Seq.empty
, obwohl empty
sich sowohl im Modul List
als auch im Modul Seq
befindet.
open List
open Seq
printfn %"{empty}"
Seien Sie daher vorsichtig, wenn Sie Module oder Namespaces wie List
oder Seq
öffnen, die Elemente mit identischen Namen enthalten. Erwägen Sie stattdessen die Verwendung der qualifizierten Namen. Sie sollten jede Situation vermeiden, in der der Code von der Reihenfolge der Importdeklarationen abhängig ist.
Offene Typdeklarationen
F# unterstützt open
für einen Typ wie folgt:
open type System.Math
PI
Dadurch werden alle statischen Felder und Member des Typs verfügbar gemacht.
Sie können open
auch für von F# definierte Datensatztypen und diskriminierte Union-Typen verwenden, um statische Member verfügbar zu machen. Bei diskriminierten Unions können Sie auch die Union-Fälle verfügbar machen. Dies kann hilfreich für den Zugriff auf Union-Fälle in einem Typ sein, der innerhalb eines Moduls deklariert ist, das Sie möglicherweise nicht öffnen möchten:
module M =
type DU = A | B | C
let someOtherFunction x = x + 1
// Open only the type inside the module
open type M.DU
printfn "%A" A
Öffnen vom Stammverzeichnis nur mit dem global
-Bezeichner
Geschachtelte Module wie
module A =
module B =
...
können geöffnet werden mit
open A // opens A
open B // opens A.B
Um nur vollqualifizierte Module oder Namespaces zu öffnen, stellen Sie ihnen den Bezeichner global
voran:
open global.A // works
open global.B // this now fails
open global.A.B // works
Standardmäßig offene Namespaces
Einige Namespaces werden so häufig in F#-Code verwendet, dass sie implizit offen sind, ohne dass eine explizite Importdeklaration erforderlich ist. In der folgenden Tabelle werden die Namespaces aufgeführt, die standardmäßig offen sind.
Namespace | BESCHREIBUNG |
---|---|
FSharp.Core |
Enthält grundlegende F#-Typdefinitionen für integrierte Typen wie int und float |
FSharp.Core.Operators |
Enthält grundlegende arithmetische Operationen wie + und * |
FSharp.Collections |
Enthält unveränderliche Collectionklassen wie List und Array |
FSharp.Control |
Enthält Typen für Steuerelementkonstrukte wie die verzögerte Auswertung und asynchrone Ausdrücke |
FSharp.Text |
Enthält Funktionen für formatierte E/A, z. B. die printf -Funktion |
AutoOpen-Attribut
Sie können das AutoOpen
-Attribut auf eine Assembly anwenden, wenn Sie einen Namespace oder ein Modul automatisch öffnen möchten, wenn auf die Assembly verwiesen wird. Sie können das AutoOpen
-Attribut auch auf ein Modul anwenden, um dieses Modul automatisch zu öffnen, wenn das übergeordnete Modul oder der übergeordnete Namespace geöffnet wird. Weitere Informationen finden Sie unter AutoOpenAttribute.
RequireQualifiedAccess-Attribut
Einige Module, Datensätze oder Union-Typen können das RequireQualifiedAccess
-Attribut angeben. Wenn Sie auf Elemente dieser Module, Datensätze oder Unions verweisen, müssen Sie einen qualifizierten Namen verwenden, unabhängig davon, ob Sie eine Importdeklaration einschließen. Wenn Sie dieses Attribut gezielt für Typen verwenden, die häufig verwendete Namen definieren, können Sie Namenskonflikte vermeiden und dadurch den Code resilienter gegenüber Änderungen in Bibliotheken machen. Weitere Informationen finden Sie unter RequireQualifiedAccessAttribute.