Declarações de Importação: a palavra-chave open
Uma declaração de importação especifica um módulo ou namespace cujos elementos você pode referenciar sem usar um nome totalmente qualificado.
Sintaxe
open module-or-namespace-name
open type type-name
Comentários
Fazer referência ao código usando o namespace totalmente qualificado ou o caminho do módulo sempre pode criar um código difícil de escrever, ler e manter. Em vez disso, você pode usar a palavra-chave open
para módulos e namespaces usados com frequência para que, ao fazer referência a um membro desse módulo ou namespace, você possa usar a forma abreviada do nome em vez do nome totalmente qualificado. Essa palavra-chave é semelhante à palavra-chave using
em C#, using namespace
no Visual C++ e Imports
no Visual Basic.
O módulo ou namespace fornecido deve estar no mesmo projeto ou em um projeto ou assembly referenciado. Se não estiver, você poderá adicionar uma referência ao projeto ou usar a opção de linha de comando -reference
(ou sua abreviação, -r
). Para obter mais informações, consulte Opções do compilador.
A declaração de importação disponibiliza os nomes no código que segue a declaração, até o final do namespace, módulo ou arquivo delimitador.
Quando você usa várias declarações de importação, elas devem aparecer em linhas separadas.
O código a seguir mostra o uso da palavra-chave open
para simplificar o código.
// 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..."
O compilador F# não emite um erro ou aviso se acontecerem ambiguidades quando o mesmo nome ocorre em mais de um módulo ou namespace aberto. Quando ocorrem ambiguidades, o F# dá preferência ao módulo ou namespace aberto mais recentemente. Por exemplo, no código a seguir, empty
significa Seq.empty
, embora empty
esteja localizado nos módulos List
e Seq
.
open List
open Seq
printfn %"{empty}"
Portanto, tenha cuidado ao abrir módulos ou namespaces como List
ou Seq
que contêm membros com nomes idênticos; em vez disso, considere usar os nomes qualificados. Você deve evitar qualquer situação em que o código dependa da ordem das declarações de importação.
Declarações de tipo aberto
F# dá suporte a open
em um tipo assim:
open type System.Math
PI
Isso vai expor todos os campos e membros estáticos acessíveis no tipo.
Você também pode open
tipos de registro e união discriminada definidos em F# para expor membros estáticos. No caso de uniões discriminadas, você também pode expor os casos de união. Isso pode ser útil para acessar casos de união em um tipo declarado dentro de um módulo que você pode não querer abrir, assim:
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
Abrir do caminho raiz somente com o especificador global
Módulos aninhados como
module A =
module B =
...
pode ser aberto por meio de
open A // opens A
open B // opens A.B
Para abrir apenas módulos ou namespaces totalmente qualificados, prefixe-os com o especificador global
:
open global.A // works
open global.B // this now fails
open global.A.B // works
Namespaces que são abertos por padrão
Alguns namespaces são usados com tanta frequência no código F# que são abertos implicitamente sem a necessidade de uma declaração de importação explícita. A tabela a seguir mostra os namespaces abertos por padrão.
Namespace | Descrição |
---|---|
FSharp.Core |
Contém definições básicas de tipo F# para tipos internos, como int e float . |
FSharp.Core.Operators |
Contém operações aritméticas básicas, como + e * . |
FSharp.Collections |
Contém classes de coleção imutáveis, como List e Array . |
FSharp.Control |
Contém tipos para construções de controle, como avaliação lenta e expressões assíncronas. |
FSharp.Text |
Contém funções para E/S formatada, como a função printf . |
Atributo AutoOpen
Você pode aplicar o atributo AutoOpen
a um assembly se quiser abrir automaticamente um namespace ou módulo quando o assembly for referenciado. Você também pode aplicar o atributo AutoOpen
a um módulo para abrir esse módulo automaticamente quando o módulo pai ou o namespace for aberto. Para obter mais informações, consulte AutoOpenAttribute.
Atributo RequireQualifiedAccess
Alguns módulos, registros ou tipos de união podem especificar o atributo RequireQualifiedAccess
. Ao fazer referência a elementos desses módulos, registros ou uniões, você deve usar um nome qualificado, independentemente de incluir uma declaração de importação. Se usar esse atributo estrategicamente em tipos que definem nomes comumente usados, você ajudará a evitar colisões de nomes e, assim, tornará o código mais resiliente a alterações nas bibliotecas. Para obter mais informações, consulte RequireQualifiedAccessAttribute.