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 arquivo de assinatura contém informações sobre as assinaturas públicas de um conjunto de elementos do programa F#, como tipos, namespaces e módulos. Ele pode ser usado para especificar a acessibilidade desses elementos de programa.
Observações
Para cada arquivo de código F#, você pode ter um arquivo de assinatura, que é um arquivo que tem o mesmo nome do arquivo de código, mas com a extensão .fsi em vez de .fs. Os arquivos de assinatura também poderão ser adicionados à linha de comando de compilação se você estiver usando a linha de comando diretamente. Para distinguir entre arquivos de código e arquivos de assinatura, os arquivos de código às vezes são chamados de arquivos de implementação. Em um projeto, o arquivo de assinatura deve preceder o arquivo de código associado.
Um arquivo de assinatura descreve os namespaces, módulos, tipos e membros no arquivo de implementação correspondente. Use as informações em um arquivo de assinatura para especificar quais partes do código no arquivo de implementação correspondente podem ser acessadas do código fora do arquivo de implementação e quais partes são internas para o arquivo de implementação. Os namespaces, módulos e tipos incluídos no arquivo de assinatura devem ser um subconjunto dos namespaces, módulos e tipos incluídos no arquivo de implementação. Com algumas exceções observadas posteriormente neste tópico, esses elementos de linguagem que não estão listados no arquivo de assinatura são considerados privados para o arquivo de implementação. Se nenhum arquivo de assinatura for encontrado no projeto ou na linha de comando, a acessibilidade padrão será usada.
Para obter mais informações sobre a acessibilidade padrão, consulte o Controle de Acesso.
Em um arquivo de assinatura, você não repete a definição dos tipos e as implementações de cada método ou função. Em vez disso, você usa a assinatura para cada método e função, que atua como uma especificação completa da funcionalidade que é implementada por um módulo ou fragmento de namespace. A sintaxe de uma assinatura de tipo é a mesma usada em declarações de método abstrato em interfaces e classes abstratas, e também é mostrada pelo IntelliSense e pelo interpretador F# fsi.exe quando exibe a entrada compilada corretamente.
Se não houver informações suficientes na assinatura de tipo para indicar se um tipo está lacrado ou se é um tipo de interface, você deve adicionar um atributo que indique a natureza do tipo ao compilador. Os atributos usados para essa finalidade são descritos na tabela a seguir.
| Atributo | Descrição |
|---|---|
[<Sealed>] |
Para um tipo que não tem membros abstratos ou que não deve ser estendido. |
[<Interface>] |
Para um tipo que é uma interface. |
O compilador produzirá um erro se os atributos não forem consistentes entre a assinatura e a declaração no arquivo de implementação.
Use a palavra-chave val para criar uma assinatura para um valor ou valor de função. A palavra-chave type apresenta uma assinatura de tipo.
Você pode gerar um arquivo de assinatura usando a opção do --sig compilador. Em geral, você não grava arquivos .fsi manualmente. Em vez disso, você gera arquivos .fsi usando o compilador, adiciona-os ao seu projeto, se tiver um, e edita-os removendo métodos e funções que você não deseja que sejam acessíveis.
Há várias regras para assinaturas de tipo:
As abreviações de tipo em um arquivo de implementação não devem corresponder a um tipo sem uma abreviação em um arquivo de assinatura.
Registros e uniões discriminadas devem expor todos ou nenhum de seus campos e construtores, e a ordem na assinatura deve corresponder à ordem no arquivo de implementação. As classes podem revelar alguns, todos ou nenhum de seus campos e métodos na assinatura.
Classes e estruturas que têm construtores devem expor as declarações de suas classes base (a
inheritsdeclaração). Além disso, classes e estruturas que têm construtores devem expor todos os seus métodos abstratos e declarações de interface.Os tipos de interface devem revelar todos os seus métodos e interfaces.
As regras para assinaturas de valor são as seguintes:
Modificadores de acessibilidade (
publicinternale assim por diante) e osinlinemodificadores namutableassinatura devem corresponder aos da implementação.O número de parâmetros de tipo genérico (implicitamente inferidos ou explicitamente declarados) deve corresponder e os tipos e restrições de tipo em parâmetros de tipo genérico devem corresponder.
Se o
Literalatributo for usado, ele deverá aparecer na assinatura e na implementação e o mesmo valor literal deverá ser usado para ambos.O padrão de parâmetros (também conhecido como aridade) de assinaturas e implementações deve ser consistente.
Se os nomes de parâmetro em um arquivo de assinatura forem diferentes do arquivo de implementação correspondente, o nome no arquivo de assinatura será usado, o que poderá causar problemas ao depurar ou criar perfil. Se você quiser ser notificado sobre essas incompatibilidades, habilite o aviso 3218 no arquivo de projeto ou ao invocar o compilador (consulte
--warnonem Opções do Compilador).
O exemplo de código a seguir mostra um exemplo de um arquivo de assinatura que tem namespace, módulo, valor da função e assinaturas de tipo junto com os atributos apropriados. Ele também mostra o arquivo de implementação correspondente.
// Module1.fsi
namespace Library1
module Module1 =
val function1 : int -> int
type Type1 =
new : unit -> Type1
member method1 : unit -> unit
member method2 : unit -> unit
[<Sealed>]
type Type2 =
new : unit -> Type2
member method1 : unit -> unit
member method2 : unit -> unit
[<Interface>]
type InterfaceType1 =
abstract member method1 : int -> int
abstract member method2 : string -> unit
O código a seguir mostra o arquivo de implementação.
namespace Library1
module Module1 =
let function1 x = x + 1
type Type1() =
member type1.method1() =
printfn "type1.method1"
member type1.method2() =
printfn "type1.method2"
[<Sealed>]
type Type2() =
member type2.method1() =
printfn "type2.method1"
member type2.method2() =
printfn "type2.method2"
[<Interface>]
type InterfaceType1 =
abstract member method1 : int -> int
abstract member method2 : string -> unit
Consulte também
- Referência da Linguagem F#
- Controle de acesso
- Opções do compilador