Файлы подписи и модификаторы доступа в F#

Недавно я пытался изучить объектно-ориентированные аспекты F#, и мне стало любопытно, как ограничить доступ к типам/модулям в языке.

В частности, я хочу знать разницу между написанием этого:

Пример.fsi

module Stack =
    val foo : string

Пример.fs

module Stack =
    let foo = "foo"
    let bar = "bar"

и альтернативно это:

module Stack =
    let foo = "foo"
    let private bar = "bar"

Разве они не достигают в конце концов одного и того же? Исходя из фона C #, я очень склонен просто использовать модификаторы доступа для файлов подписи (FSI). Они кажутся более универсальными (например, могут применяться к модулям/типам в пространствах имен), тогда как я не вижу ситуаций, в которых файлы сигнатур предлагают что-то, чего нет в модификаторах доступа.


person Noldorin    schedule 06.10.2009    source источник
comment
Ваш пример все равно не должен работать ;-) (пусть foo _ = bar)   -  person Dario    schedule 06.10.2009
comment
Почему это не должно работать? Пример компилируется нормально для меня.   -  person Noldorin    schedule 06.10.2009
comment
.fsi объявляет foo как функцию, но затем .fs определяет ее как значение.   -  person Brian    schedule 06.10.2009


Ответы (1)


Они выполняют почти одно и то же. (Обратите внимание, что вы также можете использовать файл .fsi для типов в пространствах имен, я не был уверен, что означает ваш комментарий по этому поводу.)

Файл подписи имеет несколько преимуществ:

  • Вы можете создавать сущности public на время файла, но затем private на последующие файлы проекта.
  • В файле сигнатуры может быть только ваша краткая сводка, поэтому общедоступный интерфейс легко читать без необходимости сканировать тонны кода.

С первой пулей не стоит шутить — инкапсуляция внутри сборки, подобная этой, на самом деле является довольно важной функцией для очень больших проектов. Возможность определить несколько типов, которые являются общедоступными друг для друга в File1.fs, но затем сделать общедоступными только подмножество этих типов/методов для остальных (File2.fs, File3.fs и т. д.), весьма полезна ( немного похоже на «друг» в C++).

person Brian    schedule 06.10.2009
comment
@ Брайан: Спасибо за ответ. Я имел в виду нижнюю часть этой страницы - en.wikibooks.org/wiki/F_Sharp_Programming/ - невозможность использования FSI в пространствах имен. Не могли бы вы пояснить, что вы имеете в виду под продолжением проекта? - person Noldorin; 06.10.2009
comment
Я вижу, этот документ неправильный; @ Джульетта, если ты это читаешь, ты бы обновила? Обратите внимание, что вы можете использовать fsc --sig в ​​файле .fs, содержащем пространства имен, чтобы увидеть синтаксис кода .fsi для пространств имен. - person Brian; 06.10.2009
comment
@ Брайан: Ах, тогда достаточно честно. Полезная маленькая команда. Спасибо и за разъяснение. - person Noldorin; 06.10.2009
comment
Вы можете сделать объекты общедоступными на время существования файла, но затем приватными для последующих файлов проекта. На самом деле вам не нужны файлы подписи для такой инкапсуляции. Гораздо более простой подход — использовать инкапсуляцию группы объявлений пространства имен, т. е. определить новое подпространство имен и объявить в нем соответствующие типы как частные. - person Marc Sigrist; 01.11.2012
comment
В файле сигнатуры может быть только ваша краткая сводка, поэтому общедоступный интерфейс легко читать без необходимости сканировать тонны кода. Это правда, но анализировать/отлаживать код тем более сложно, потому что в Visual Studio переход к определению приведет к переходу к файлу подписи вместо файла реализации, и тогда вам придется искать вручную для реализации... что может быть настоящей головной болью в сложных проектах. - person Marc Sigrist; 01.11.2012
comment
Файлы подписи поощряют написание файлов реализации со многими типами и модулями внутри. Это настоятельно не рекомендуется в большинстве отделов разработки, где часто рекомендуется использовать один файл для каждого типа. Что еще хуже, в VS 2012 по-прежнему отсутствует хорошая поддержка просмотра кода для F#: нет окна просмотра классов, нет поддержки обозревателя объектов для проектов F# (только для скомпилированных библиотек) и т. д. Единственный способ немного упростить просмотр кода — распределить пространства имен. , типы и/или модули в отдельные файлы с понятными именами, что, опять же, противоречит использованию файлов сигнатур. - person Marc Sigrist; 01.11.2012