Подписи
В файле сигнатур содержатся сведения об открытых сигнатурах набора элементов программы на языке F#, таких как типы, пространства имен и модули. Файл сигнатур можно использовать для указания доступности этих элементов программы.
Замечания
Для каждого файла кода F# может иметься файл сигнатур— файл с тем же именем, что и файл кода, но с расширением FSI вместо FS. Файлы сигнатур также можно добавлять в командную строку компиляции, если командная строка используется напрямую. Для различения файлов кода и файлов сигнатур файлы кода иногда называют файлами реализации. В проекте файл сигнатур должен предшествовать связанному с ним файлу кода.
Файл сигнатур описывает пространства имен, модули, типы и члены в соответствующем файле реализации. Информацию в файле сигнатур можно использовать для указания того, к каким частям кода в соответствующем файле реализации возможен доступ из кода, находящегося за пределами файла реализации, и какие части являются внутренними по отношению к файлу реализации. Пространства имен, модули и типы, включаемые в файл сигнатур, должны представлять собой подмножество имен пространств, модулей и типов, включаемых в файл реализации. За некоторыми исключениями, рассмотренными ниже в этом разделе, языковые элементы, отсутствующие в файле сигнатур, считаются закрытыми по отношению к файлу реализации. Если в проекте или в командной строке не найден файл сигнатур, используется доступность по умолчанию.
Дополнительные сведения о специальных возможностях по умолчанию см. в контроль доступа.
В файле сигнатур не нужно повторять определение типов и реализаций для каждого метода или функции. Вместо этого для каждого метода и функции используется сигнатура, выступающая в качестве полной спецификации функциональности, реализуемой фрагментом модуля или пространства имен. Синтаксис сигнатуры типа идентичен используемому в объявлениях абстрактных методов в интерфейсах и абстрактных классах; он также отображается IntelliSense и интерпретатором языка F# (fsi.exe) при выводе правильно скомпилированных входных данных.
Если в сигнатуре типа недостаточно информации для определения того, является ли тип запечатанным или типом интерфейса, нужно добавить атрибут, по которому компилятор сможет определить природу типа. Используемые с этой целью атрибуты приведены в таблице ниже.
Атрибут | Description |
---|---|
[<Sealed>] |
Для типа, который не имеет абстрактных членов или не должен расширяться. |
[<Interface>] |
Для типа, являющегося интерфейсом. |
Компилятор выдает ошибку, если атрибуты в сигнатуре и в объявлении в файле реализации не соответствуют друг другу.
Для создания сигнатуры для значения или значения функции используется ключевое слово val
. Сигнатура типа предваряется ключевым словом type
.
Сформировать файл сигнатур можно с помощью параметра --sig
компилятора. Как правило, вручную FSI-файлы не пишутся. Вместо этого вы создаете FSI-файлы с помощью компилятора, добавляете их в проект (при работе с проектом) и редактируете их, удаляя методы и функции, которые не должны быть доступными.
В отношении сигнатур типов действует ряд правил.
Аббревиатуры типов в файле реализации не должны совпадать с полными названиями типов в файле сигнатур.
Записи и размеченные объединения должны предоставлять либо все свои поля и конструкторы, либо никакие из них, и порядок в сигнатуре должен совпадать с порядком в файле реализации. Классы могут открывать некоторые, все или никакие из своих полей и методов в сигнатуре.
Классы и структуры, имеющие конструкторы, должны предоставлять объявления своих базовых классов (объявление
inherits
). Кроме того, классы и структуры, имеющие конструкторы, должны предоставлять все свои абстрактные методы и объявления интерфейсов.Типы интерфейсов должны открывать все свои методы и интерфейсы.
К сигнатурам значений применяются приведенные ниже правила.
Модификаторы доступности (
public
,internal
и т. д.) и модификаторыinline
иmutable
в сигнатуре должны совпадать с модификаторами в реализации.Количество параметров универсального типа (неявно выведенных или явно объявленных) должно совпадать. Также должны совпадать типы и ограничения типов в параметрах универсального типа.
Если используется атрибут
Literal
, он должен присутствовать и в сигнатуре, и в реализации, и в обоих случая должно использоваться одно и то же литеральное значение.Шаблон параметров (также называемый арностью) сигнатур должен соответствовать шаблону параметров реализаций.
Если имена параметров в файле подписи отличаются от соответствующего файла реализации, вместо этого будет использоваться имя в файле подписи, что может привести к проблемам при отладке или профилировании. Если вы хотите получать уведомления о таких несоответствиях, включите предупреждение 3218 в файле проекта или при вызове компилятора (см. раздел
--warnon
" Параметры компилятора").
В приведенном ниже примере показан файл сигнатур, содержащий сигнатуры пространства имен, модуля, значения функции и типов вместе с соответствующими атрибутами. Показан также соответствующий файл реализации.
// 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
В приведенном ниже коде показан файл реализации.
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