Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Um namespace permite organizar o código em áreas de funcionalidade relacionada, permitindo que você anexe um nome a um agrupamento de elementos do programa F#. Os namespaces normalmente são elementos de nível superior em arquivos F#.
Sintaxe
namespace [rec] [parent-namespaces.]identifier
Observações
Se você quiser colocar o código em um namespace, a primeira declaração no arquivo deverá declarar o namespace. O conteúdo de todo o arquivo se torna parte do namespace, desde que nenhuma outra declaração de namespaces exista mais no arquivo. Se esse for o caso, todo o código até a próxima declaração de namespace será considerado dentro do primeiro namespace.
Namespaces não podem conter diretamente valores e funções. Em vez disso, valores e funções devem ser incluídos em módulos e os módulos são incluídos em namespaces. Os namespaces podem conter tipos e módulos.
Os comentários do documento XML podem ser declarados acima de um namespace, mas eles são ignorados. As diretivas do compilador também podem ser declaradas acima de um namespace.
Os namespaces podem ser declarados explicitamente com a palavra-chave do namespace ou implicitamente ao declarar um módulo. Para declarar um namespace explicitamente, use a palavra-chave namespace seguida pelo nome do namespace. O exemplo a seguir mostra um arquivo de código que declara um namespace Widgets com um tipo e um módulo incluídos nesse namespace.
namespace Widgets
type MyWidget1 =
member this.WidgetName = "Widget1"
module WidgetsModule =
let widgetName = "Widget2"
Se todo o conteúdo do arquivo estiver em um módulo, você também poderá declarar namespaces implicitamente usando a module palavra-chave e fornecendo o novo nome do namespace no nome do módulo totalmente qualificado. O exemplo a seguir mostra um arquivo de código que declara um namespace Widgets e um módulo WidgetsModule, que contém uma função.
module Widgets.WidgetModule
let widgetFunction x y =
printfn "%A %A" x y
O código a seguir é equivalente ao código anterior, mas o módulo é uma declaração de módulo local. Nesse caso, o namespace deve aparecer em sua própria linha.
namespace Widgets
module WidgetModule =
let widgetFunction x y =
printfn "%A %A" x y
Se mais de um módulo for necessário no mesmo arquivo em um ou mais namespaces, você deverá usar declarações de módulo local. Ao usar declarações de módulo local, você não pode usar o namespace qualificado nas declarações do módulo. O código a seguir mostra um arquivo que tem uma declaração de namespace e duas declarações de módulo local. Nesse caso, os módulos estão contidos diretamente no namespace; não há nenhum módulo criado implicitamente que tenha o mesmo nome que o arquivo. Qualquer outro código no arquivo, como uma do associação, está no namespace, mas não nos módulos internos, portanto, você precisa qualificar o membro widgetFunction do módulo usando o nome do módulo.
namespace Widgets
module WidgetModule1 =
let widgetFunction x y =
printfn "Module1 %A %A" x y
module WidgetModule2 =
let widgetFunction x y =
printfn "Module2 %A %A" x y
module useWidgets =
do
WidgetModule1.widgetFunction 10 20
WidgetModule2.widgetFunction 5 6
A saída deste exemplo é a seguinte.
Module1 10 20
Module2 5 6
Para obter mais informações, consulte Modules.
Namespaces aninhados
Ao criar um namespace aninhado, você deve qualificá-lo totalmente. Caso contrário, você criará um novo namespace de nível superior. O recuo é ignorado em declarações de namespace.
O exemplo a seguir mostra como declarar um namespace aninhado.
namespace Outer
// Full name: Outer.MyClass
type MyClass() =
member this.X(x) = x + 1
// Fully qualify any nested namespaces.
namespace Outer.Inner
// Full name: Outer.Inner.MyClass
type MyClass() =
member this.Prop1 = "X"
Namespaces em arquivos e assemblies
Os namespaces podem abranger vários arquivos em um único projeto ou compilação. O fragmento de namespace de termo descreve a parte de um namespace incluído em um arquivo. Namespaces também podem abranger vários assemblies. Por exemplo, o System namespace inclui todo o .NET Framework, que abrange muitos assemblies e contém muitos namespaces aninhados.
Global Namespace
Use o namespace global predefinido para colocar nomes no namespace de nível superior do .NET.
namespace global
type SomeType() =
member this.SomeMember = 0
Você também pode usar o global para fazer referência ao namespace .NET de nível superior, por exemplo, para resolver conflitos de nome com outros namespaces.
global.System.Console.WriteLine("Hello World!")
Namespaces recursivos
Os namespaces também podem ser declarados como recursivos para permitir que todo o código contido seja mutuamente recursivo. Isso é feito por meio de namespace rec. O uso pode namespace rec aliviar algumas dores ao não conseguir escrever código mutuamente referencial entre tipos e módulos. Veja a seguir um exemplo disso:
namespace rec MutualReferences
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 (banana: Banana) =
let flip (banana: Banana) =
match banana.Orientation with
| Up ->
banana.Orientation <- Down
banana
| Down -> banana
// Update the peel state for all sides of the banana.
let peelSides (banana: Banana) =
banana.Sides
|> List.map (function
| Unpeeled -> Peeled
| Peeled -> Peeled)
// Apply the flipping and peeling logic based on the orientation.
match banana.Orientation with
| Up -> banana |> flip |> peelSides
| Down -> banana |> peelSides
Observe que a exceção DontSqueezeTheBananaException e a classe Banana se referem umas às outras. Além disso, o módulo BananaHelpers e a classe Banana também se referem um ao outro. Isso não seria possível expressar em F# se você removesse a rec palavra-chave do MutualReferences namespace.
Esse recurso também está disponível para módulos de nível superior.