Сигнатуры (F#)

В файле сигнатур содержатся сведения об открытых сигнатурах ряда элементов программы на языке F#, таких как типы, пространства имен и модули.Файл сигнатур можно использовать для указания доступности этих элементов программы.

Заметки

Для каждого файла кода F# может иметься файл сигнатур — файл с тем же именем, что и файл кода, но с расширением FSI вместо FS.Файлы сигнатур также могут добавляться в командную строку компиляции, если используется непосредственно командная строка.Для различения файлов кода и файлов сигнатур файлы кода иногда называют файлами реализации.В проекте файл сигнатур должен предшествовать связанному с ним файлу кода.

Файл сигнатур описывает пространства имен, модули, типы и члены в соответствующем файле реализации.Информацию в файле сигнатур можно использовать для указания того, к каким частям кода в соответствующем файле реализации возможен доступ из кода, находящегося за пределами файла реализации, и какие части являются внутренними по отношению к файлу реализации (т. е. доступны только из него).Пространства имен, модули и типы, включаемые в файл сигнатур, должны представлять собой подмножество имен пространств, модулей и типов, включаемых в файл реализации.За некоторыми исключениями, рассмотренными ниже в этом разделе, языковые элементы, не присутствующие в файле сигнатур, считаются закрытыми по отношению к файлу реализации.Если в проекте или в командной строке не найден файл сигнатуры, используется доступность по умолчанию.

Дополнительные сведения о доступности по умолчанию см. в разделе Управление доступом (F#).

В файле сигнатур не нужно повторять определение типов и реализаций для каждого метода или функции.Вместо этого для каждого метода и функции используется сигнатура, выступающая в качестве полной спецификации функциональности, реализуемой фрагментом модуля или пространства имен.Синтаксис сигнатуры типа идентичен используемому в объявлениях абстрактных методов в интерфейсах и абстрактных классах; он также отображается IntelliSense и интерпретатором языка F# (fsi.exe) при выводе правильно скомпилированных входных данных.

Если в сигнатуре типа нет достаточной информации для определения того, является ли тип запечатанным или типом интерфейса, нужно добавить атрибут, по которому компилятор сможет определить природу типа.Используемые с этой целью атрибуты приведены в следующей таблице.

Атрибут

Описание

[<Sealed>]

Для типа, который не имеет абстрактных членов или не должен быть расширен.

[<Interface>]

Для типа, являющегося интерфейсом.

Компилятор выдает ошибку, если атрибуты в сигнатуре и в объявлении в файле реализации не соответствуют друг другу.

Для создания сигнатуры для значения или значения функции используется ключевое слово val.Сигнатура типа предваряется ключевым словом type.

Сформировать файл сигнатур можно с помощью параметра --sig компилятора.Как правило, вручную FSI-файлы не пишутся.Вместо этого разработчик формирует FSI-файлы с помощью компилятора, добавляет их в проект (при работе с проектом) и редактирует их, удаляя методы и функции, которые не должны быть доступными.

В отношении сигнатур типов существует несколько правил.

  • Аббревиатуры типов в файле реализации не должны совпадать с полными названиями типов в файле сигнатур.

  • Записи и размеченные объединения должны предоставлять либо все свои поля и конструкторы, либо никакие из них, и порядок в сигнатуре должен совпадать с порядком в файле реализации.Классы могут открывать некоторые, все или никакие из своих полей и методов в сигнатуре.

  • Классы и структуры, имеющие конструкторы, должны предоставлять объявления своих базовых классов (объявление inherits).Кроме того, классы и структуры, имеющие конструкторы, должны предоставлять все свои абстрактные методы и объявления интерфейсов.

  • Тип интерфейсов должны открывать все свои методы и интерфейсы.

К сигнатурам значений применяются следующие правила.

  • Модификаторы доступа (public, internal и т. д.) и модификаторы inline и mutable в сигнатуре должны совпадать с модификаторами в реализации.

  • Количество параметров универсального типа (неявно выведенных или явно объявленных) должно совпадать, и типы и ограничения типа в параметрах универсального типа должны совпадать.

  • Если используется атрибут Literal, он должен присутствовать и в сигнатуре, и в реализации, и в обоих случая должно использоваться одно и то же литеральное значение.

  • Шаблон параметров (также называемый арностью) сигнатур должен соответствовать шаблону параметров реализаций.

В следующем примере показан файл сигнатур, содержащий сигнатуры пространства имен, модуля, значения функции и типов вместе с соответствующими атрибутами.Показан также соответствующий файл реализации.

// 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 "test1.method1"
        member type1.method2() =
            printfn "test1.method2"


    [<Sealed>]
    type Type2() =
        member type2.method1() =
            printfn "test1.method1"
        member type1.method2() =
            printfn "test1.method2"

    [<Interface>]
    type InterfaceType1 =
        abstract member method1 : int -> int
        abstract member method2 : string -> unit

См. также

Основные понятия

Управление доступом (F#)

Другие ресурсы

Справочник по языку F#

Параметры компилятора (F#)