Совместное использование файлов F #.fsx
Есть ли способ совместного использования типов файлов fsx?
При использовании #load для загрузки того же файла, содержащего тип из нескольких файлов FSX, они кажутся префиксами в другое пространство имен FS_00xx каждый раз, что означает, что вы не можете их пропустить.
Есть ли способы обойти это поведение, не прибегая к компиляции в сборку?
Ответы
Ответ 1
Что касается
http://msdn.microsoft.com/en-us/library/dd233169.aspx
[. fsx файлы] используются для включения неформального кода тестирования в F # без добавления тестового кода в ваше приложение и без создания для него отдельного проекта. По умолчанию файлы script не включены в сборку проекта, даже если они являются частью проекта.
Это означает, что если у вас есть проект с достаточной структурой, чтобы иметь такие проблемы с зависимостью, вы не должны использовать файлы .fsx
, вместо этого пишите модули/пространства имен, используя файлы .fs
. То есть, вы действительно должны скомпилировать их типы в сборку.
Интерактивный интерпретатор f # генерирует сборку для каждого загруженного файла. Если вы дважды загружаете файл, байт-код генерируется дважды, а типы разные, даже если они имеют одинаковое определение и одно и то же имя. Это означает, что вы не можете делиться типами между двумя файлами .fsx, если только один из них не содержит другого.
Когда вы #load
файл, который имеет те же типы, что и те, которые уже присутствуют в вашей среде, интерактивный интерпретатор f # может использовать две разные стратегии:
- отказывается загружать файл, если возникают конфликты с существующими именами (жалуюсь, что некоторые вещи уже определены)
- введите имена в пространство имен
FS_00xx
(так, чтобы они были фактически разными типами из тех, которые вы уже загрузили), в конечном итоге open
введите результирующее пространство имен, чтобы имена были доступны из интерактивного сеанса.
Поскольку файлы fsx предполагается использовать в качестве неофициального теста, более удобно использовать второй подход (есть также техническая причина, по которой используется второй подход, в основном зависящий от системы типа t25 > VM, и тот факт, что существующие типы не могут быть изменены во время выполнения).
Ответ 2
[ Примечание: Это более конкретный ответ на более конкретный вопрос, который является дубликатом этого.]
Я не думаю, что для этого есть приятное и легкое решение. Единственное решение, которое я использовал в некоторых проектах (например, веб-сайт F # snippets), должен иметь только один файл верхнего уровня fsx
который загружает несколько файлов fs
. Например, см. app.fsx.
Итак, у вас будут common.fs
, intMapper.fs
и stringMapper.fs
, которые будут загружены из caller.fsx
следующим образом:
#load "common.fs"
#load "stringMapper.fs"
#load "intMapper.fs"
open Common
Внутри stringMapper.fs
и intMapper.fs
вы не загружаете common.fs
. Обычные типы будут загружены caller.fsx
раньше, поэтому все будет работать.
Единственная проблема заключается в том, что intMapper.fs
теперь не является автономным файлом script - и если вы хотите получить автозаполнение в редакторе, вам нужно добавить файл fsproj
, который задает порядок файлов. В проекте F # snippets есть файл проекта, который определяет порядок, в котором редактор должен видеть и загружать файлы.
Ответ 3
У вас есть все директивы #load
и #open
в файле, который вы фактически запускаете из fsi.exe(C в примере ниже), и убедитесь, что сами загруженные файлы не имеют #load
своих собственных зависимостей:
Файлы A.fsx, B.fsx, C.fsx. B зависит от A. C зависит от B и A.
B содержит
//adding the code below would cause the types defined in A to be loaded twice
//#load "A.fsx"
//#open A
C содержит
#load "A.fsx"
#open A
#load "B.fsx"
#open B
К сожалению, это приводит к тому, что все файлы трудно редактировать из Visual Studio - редактор не знает об их зависимостях и показывает всевозможные ошибки.
Поэтому это немного взломать, и рекомендуемый способ состоит в том, чтобы иметь один файл .fsx и скомпилировать все остальное в .dll:
// file1.fsx
#r "MyAssembly.dll"
https://msdn.microsoft.com/en-us/library/dd233175.aspx