Moduli (F#)

Nel contesto del linguaggio F#, un modulo è un raggruppamento di codice F#, ad esempio valori, tipi e valori di funzione, in un programma F#. Il raggruppamento degli elementi di codice nei moduli consente di mantenere uniti gli elementi di codice correlati evitando conflitti di nomi nel programma.

// Top-level module declaration. 
module [accessibility-modifier] [qualified-namespace.]module-name
declarations
// Local module declaration.
module [accessibility-modifier] module-name =
   declarations

Note

Un modulo F# è un raggruppamento di costrutti di codice F#, ad esempio tipi, valori, valori di funzione e codice nelle associazioni do. Viene implementato come una classe CLR (Common Language Runtime) che dispone solo di membri statici. Vi sono due tipi di dichiarazioni di modulo, a seconda che l'intero file sia o meno incluso nel modulo: una dichiarazione di modulo di primo livello e una dichiarazione di modulo locale. Una dichiarazione di modulo di primo livello include l'intero file nel modulo. Una dichiarazione di modulo di primo livello può apparire solo come prima dichiarazione in un file.

Nella sintassi per la dichiarazione di modulo di primo livello, l'elemento qualified-namespace facoltativo è la sequenza di nomi di spazi dei nomi annidati in cui è contenuto il modulo. Lo spazio dei nomi qualificato non deve necessariamente essere dichiarato in precedenza.

Non è necessario impostare un rientro per le dichiarazioni in un modulo di primo livello. È necessario impostare un rientro per tutte le dichiarazioni nei moduli locali. In una dichiarazione di modulo locale solo le dichiarazioni per cui è impostato un rientro al di sotto della dichiarazione di modulo fanno parte del modulo.

Se un file di codice non inizia con una dichiarazione di spazio dei nomi o una dichiarazione di modulo di primo livello, l'intero contenuto del file, compresi eventuali moduli locali, diventa parte di un modulo di primo livello creato in modo implicito che ha lo stesso nome del file, senza l'estensione, con la prima lettera convertita in maiuscola. Si consideri, ad esempio, il file seguente.

// In the file program.fs.
let x = 40

Questo file verrebbe compilato come se fosse scritto nel modo seguente:

module Program
let x = 40

Se sono presenti più moduli in un file, è necessario utilizzare una dichiarazione di modulo locale per ogni modulo. Se viene dichiarato uno spazio dei nomi che include gli elementi, questi moduli fanno parte dello spazio dei nomi che li contiene. Se non viene dichiarato uno spazio dei nomi che include gli elementi, i moduli diventano parte del modulo di primo livello creato in modo implicito. Nell'esempio di codice seguente viene illustrato un file di codice che contiene più moduli. Tramite il compilatore viene creato in modo implicito un modulo di primo livello denominato Multiplemodules e MyModule1 e MyModule2 vengono annidati in tale modulo di primo livello.

// 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)

Se si dispone di più file in un progetto o in una sola compilazione oppure se si compila una libreria, è necessario includere una dichiarazione dello spazio dei nomi o una dichiarazione del modulo all'inizio del file. Il compilatore F# determina solo in modo implicito un nome del modulo nel caso in cui sia presente un solo file in una riga di comando di compilazione o progetto e si stia creando un'applicazione.

Il valore di accessibility-modifier può essere public, private o internal. Per ulteriori informazioni, vedere Controllo di accesso (F#). L'impostazione predefinita è public.

Riferimenti al codice nei moduli

Quando si fa riferimento a funzioni, tipi e valori da un altro modulo, è necessario utilizzare un nome completo o aprire il modulo. Se si utilizza un nome completo, è necessario specificare gli spazi dei nomi, il modulo e l'identificatore per l'elemento del programma desiderato. Ogni parte del percorso completo viene separata con un punto (.), come indicato di seguito.

Namespace1.Namespace2.ModuleName.Identifier

È possibile aprire il modulo o uno o più spazi dei nomi per semplificare il codice. Per ulteriori informazioni sull'apertura di spazi dei nomi e moduli, vedere Dichiarazioni di importazione: parola chiave open (F#).

Nell'esempio di codice seguente viene illustrato un modulo di primo livello contenente tutto il codice fino alla fine del file.

module Arithmetic

let add x y =
    x + y

let sub x y =
    x - y

Per utilizzare questo codice da un altro file nello stesso progetto, è possibile utilizzare nomi completi o aprire il modulo prima di utilizzare le funzioni, come illustrato negli esempi seguenti.

// Fully qualify the function name.
let result1 = Arithmetic.add 5 9
// Open the module.
open Arithmetic
let result2 = add 5 9

Moduli annidati

I moduli possono essere annidati. Per i moduli interni deve essere impostato un rientro fino alle dichiarazioni del modulo esterno, per indicare che si tratta di moduli interni e non di nuovi moduli. Confrontare, ad esempio, i due esempi seguenti. Il modulo Z è un modulo interno nel codice seguente.

module Y =
    let x = 1 

    module Z =
        let z = 5

Il modulo Z è tuttavia di pari livello rispetto al modulo Y nel codice seguente.

module Y =
    let x = 1 

module Z =
    let z = 5

Il modulo Z è un modulo di pari livello anche nel codice seguente, in quanto per il modulo non è stato impostato un rientro fino alle altre dichiarazioni nel modulo Y.

module Y =
        let x = 1

    module Z =
        let z = 5

Infine, se il modulo esterno non include dichiarazioni ed è seguito immediatamente da un'altra dichiarazione di modulo, si presuppone che la nuova dichiarazione di modulo costituisca un modulo interno, ma se per la seconda definizione di modulo non viene impostato un rientro maggiore rispetto alla prima, viene generato un avviso dal compilatore.

// This code produces a warning, but treats Z as a inner module.
module Y =
module Z =
    let z = 5

Per eliminare l'avviso, impostare un rientro per il modulo interno.

module Y =
    module Z =
        let z = 5

Se si desidera che tutto il codice in un file sia incluso in un singolo modulo esterno e si desidera disporre di moduli interni, il modulo esterno non richiede il segno di uguale e per le dichiarazioni, incluse eventuali dichiarazioni di moduli interni, da includere nel modulo esterno non è necessario impostare un rientro. Per le dichiarazioni all'interno di dichiarazioni di moduli interni deve essere impostato un rientro. Nel codice seguente è illustrata questa situazione.

// 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

Vedere anche

Riferimenti

Spazi dei nomi (F#)

Altre risorse

Riferimenti per il linguaggio F#