Пошаговое руководство. Использование Visual F# для создания, отладки и развертывания приложения
Данное пошаговое руководство позволяет ознакомиться с принципами использования языка F# в среде Visual Studio 2010 вместе с платформой .NET Framework 4.
С помощью данного руководства можно ознакомиться с принципами использования Visual Studio 2010 для создания приложений на F# на примере исторического анализа данных об учетной ставке казначейства США. Пример начинается с анализа данных с помощью интерактивного окна F#. Затем создается и тестируется код, анализирующий данные, после чего добавляется интерфейсная часть на C#, на примере которой будет рассмотрена интеграция кода на F# с другими языками платформы .NET.
Обязательные компоненты
Ниже приведены компоненты, необходимые для выполнения данного пошагового руководства.
- Visual Studio 2010
Примечание
На вашем компьютере названия некоторых элементов интерфейса пользователя Visual Studio или их расположение могут отличаться от указанных в нижеследующих инструкциях. Это зависит от имеющегося выпуска Visual Studio и используемых параметров. Дополнительные сведения см. в разделе Параметры Visual Studio.
Создание скрипта на F#
Сначала создадим скрипт на языке F#. В меню Файл выберите пункты Создать и Файл. В диалоговом окне Создание файла выберите пункт Скрипт в списке Установленные шаблоны, после чего выберите Файл скрипта F#. Нажмите кнопку Открыть, чтобы создать файл, а затем сохраните его под именем RateAnalysis.fsx.
Используйте API платформы .NET и F# для доступа к интернет-сайту Федеральной резервной системы США. Введите приведенный ниже код.
open System.Net open System.IO let url = sprintf "http://www.federalreserve.gov/releases/h15/data/business_day/H15_TCMNOM_Y10.txt" let req = WebRequest.Create(url, Timeout = 10000000) let resp = req.GetResponse() let stream = resp.GetResponseStream() let reader = new StreamReader(stream) let csv = reader.ReadToEnd()
Обратите внимание на следующее.
Строки и ключевые слова выделяются цветом.
После каждой точки (".") выводятся списки завершения.
Среда Visual Studio может дополнять имена методов и другие идентификаторы. Для этого достаточно нажать сочетание клавиш CTRL+ПРОБЕЛ или CTRL+J в процессе набора идентификатора. При использовании сочетания CTRL+J отображается список завершения.
При наведении указателя мыши на идентификатор в коде появится подсказка со сведениями об этом идентификаторе.
Если при нажатии клавиши F1 курсор находится внутри WebRequest, появится соответствующая документация.
Если при нажатии клавиши F1 курсор находится внутри let, появится соответствующая документация.
Ссылки на типы и пространства имен из библиотек mscorlib.dll, System.dll и System.Windows.Forms.dll присутствуют по умолчанию.
Задаваемое здесь значение Timeout является свойством, а не аргументом конструктора. F# позволяет задавать значения свойств подобным образом.
Если скопировать URL-адрес из примера в браузер, отобразится список значений с разделителями-запятыми, содержащий даты и значения учетной ставки, публикуемые Федеральной резервной системой США.
Теперь код следует запустить, используя F# Interactive. Выделите весь код (с помощью мыши или сочетания клавиш CTRL+A), щелкните его правой кнопкой мыши и выберите пункт Отправить в Interactive. (Также можно нажать сочетание клавиш ALT+ВВОД.)
Появится окно F# Interactive (если оно не было открыто до этого).
Код успешно выполняется.
В окне F# Interactive отображается следующее.
val url : string = "http://www.federalreserve.gov/releases/h15/data/business_day/"+[18 chars] val req : System.Net.WebRequest val resp : System.Net.WebResponse val stream : System.IO.Stream val reader : System.IO.StreamReader val csv : string = " ,Instrument,"U.S. government securities/Treasury constant m"+[224452 chars] >
Затем изучите данные с помощью F# Interactive. В командной строке F# Interactive введите команду csv;; и нажмите клавишу ВВОД. Введите команду csv.Length;; и нажмите клавишу ВВОД. Обратите внимание на следующее.
Данные отображаются по состоянию на текущий момент.
F# Interactive отображает значение и длину строки csv, как показано здесь.
07/10/2009, 3.32 07/13/2009, 3.38 07/14/2009, 3.50 07/15/2009, 3.63 " > csv.Length;; val it : int = 224513
На следующем рисунке показано окно F# Interactive.
Окно F# Interactive
Теперь создадим код F# для синтаксического анализа CSV-данных. CSV-файлы содержат значения с разделителями запятыми. В редакторе кода добавьте следующий код. Выбирая добавленный в этом разделе код по мере ввода строк, можно просматривать частичные результаты, нажимая сочетание клавиш ALT+ВВОД. Обратите внимание на следующее.
IntelliSense предоставляет полезные сведения после ввода точки даже в сложных вложенных выражениях.
Если код не завершен (или некорректен), красное волнистое подчеркивание указывает на имеющиеся в нем синтаксические и семантические ошибки.
Конвейеры создаются с помощью оператора конвейеризации (|>). Оператор принимает значение, возвращаемое одним выражением, и использует его в качестве аргумента функции, стоящей в следующей строке. Конвейеры и F# Interactive упрощают частичное выполнение кода обработки данных.
let interest = csv.Split([|'\n'|]) |> Seq.skip 8 |> Seq.map (fun line -> line.Trim()) |> Seq.filter (fun line -> not (line.EndsWith("ND"))) |> Seq.filter (fun line -> not (line.Length = 0)) |> Seq.map (fun line -> line.Split([|','|])) |> Seq.map ( fun values -> System.DateTime.Parse(values.[0]), float values.[1])
Теперь данной функциональности нужно присвоить имя. Замените 10 в определении url на %d, чтобы превратить литеральную строку в строку формата. Добавьте maturity после строки формата. Выделите весь код, кроме новой строки, и нажмите клавишу TAB. Перед блоком кода с отступом добавьте let loadRates maturity =. В конце блока кода с отступом добавьте interest. Обратите внимание на следующее.
Отступы в F# имеют особое значение. С их помощью задается уровень вложения.
Действие TAB практически аналогично Рефакторинг для извлечения метода (C#).
Код должен выглядеть примерно следующим образом.
open System.Net open System.IO let loadRates maturity = let url = sprintf "http://www.federalreserve.gov/releases/h15/data/business_day/H15_TCMNOM_Y%d.txt" maturity let req = WebRequest.Create(url, Timeout = 10000000) let resp = req.GetResponse() let stream = resp.GetResponseStream() let reader = new StreamReader(stream) let csv = reader.ReadToEnd() let interest = csv.Split([|'\n'|]) |> Seq.skip 8 |> Seq.map (fun line -> line.Trim()) |> Seq.filter (fun line -> not (line.EndsWith("ND"))) |> Seq.filter (fun line -> not (line.Length = 0)) |> Seq.map (fun line -> line.Split([|','|])) |> Seq.map ( fun values -> System.DateTime.Parse(values.[0]), float values.[1]) interest
Теперь данную функциональность следует использовать с новыми входными данными. Выделите весь код и нажмите сочетание клавиш ALT+ВВОД, чтобы выполнить его с помощью F# Interactive. В командной строке F# Interactive вызовите новую функцию loadRates применительно к новым годовым ставкам: 1, 2 и 5. Обратите внимание на следующее.
Прежние определения в F# Interactive не пропадают, но при этом также будут доступны новые.
Сложноструктурированные данные отображаются с помощью специальных функций вывода.
Разработка компонента с помощью F#
Создайте проект библиотеки для публикации созданной функциональности. В меню Файл выберите пункт Создать, а затем команду Проект. В диалоговом окне Создание проекта в списке Установленные шаблоны выберите пункты Visual F# и Библиотека F#, чтобы создать проект новой библиотеки. Назовите проект RateAnalysis. Скопируйте ранее созданный код из файла RateAnalysis.fsx и вставьте его в файл Module1.fs. Исправьте объявление модуля в файле Module1.fs с Module1 на RateLoader. В обозревателе решений переименуйте файл Module1.fs в RateLoader.fs. Обратите внимание на следующее.
- Шаблон библиотеки F# по умолчанию содержит файл кода с расширением .fs и скрипт с расширением .fsx. Скрипт можно использовать для интерактивного тестирования кода библиотеки.
На следующем рисунке показано диалоговое окно Создание проекта с несколькими вариантами для F#. Выбран шаблон проекта библиотеки F#.
Варианты шаблонов F#
Теперь следует создать класс F#, предоставляющий необходимую функциональность. В обозревателе решений щелкните правой кнопкой мыши проект, выберите команду Добавить, затем Новый элемент. В диалоговом окне Добавление нового элемента выберите пункт Исходный файл F#. Назовите файл Analyzer.fs. В обозревателе решений щелкните правой кнопкой мыши файл Script.fsx и выберите команду Вниз. (Также можно нажать сочетание клавиш ALT+СТРЕЛКА ВНИЗ.) Вставьте в файл Analyzer.fs следующий код:
module RateAnalysis.Analyzer open RateLoader /// Provides analysis of historical interest rate data. type Analyzer(ratesAndDates) = let rates = ratesAndDates |> Seq.map snd /// Construct Analyzer objects for each maturity category. static member GetAnalyzers(maturities) = maturities |> Seq.map loadRates |> Seq.map (fun ratesAndDates -> new Analyzer(ratesAndDates)) member sa.Min = let date, minRate = (Seq.minBy (fun (_, rate) -> rate) ratesAndDates) (minRate, date.ToString("d")) member sa.Max = let date, maxRate = (Seq.maxBy (fun (_, rate) -> rate) ratesAndDates) (maxRate, date.ToString("d")) member sa.Current = rates |> List.ofSeq |> List.rev |> List.head
Обратите внимание на следующее.
- F# поддерживает ряд понятий из объектно-ориентированного программирования. Дополнительные сведения см. в разделах Классы (F#), Наследование (F#), а также других статьях из справочника по языку F#.
Теперь нужно создать документирующие комментарии на XML. В обозревателе решений щелкните правой кнопкой мыши проект и выберите пункт Свойства. На вкладке Построение установите флажок XML-файл документации внизу страницы. Обратите внимание на следующее.
XML-документацию можно создать для любой сборки F#.
По умолчанию XML-документация сохраняется в каталоге вывода.
Чтобы построить проект, нажмите сочетание клавиш CTRL+SHIFT+B или клавишу F6. Обратите внимание на следующее.
Построение проекта выполняется успешно.
В окне "Список ошибок" отсутствуют ошибки.
В каталоге вывода появляются файлы .dll, .pdb и .xml.
В окне вывода отображается следующее:
------ Build started: Project: RateAnalysis, Configuration: Debug Any CPU ------ C:\Program Files (x86)\Microsoft F#\v4.0\fsc.exe -o:obj\Debug\RateAnalysis.exe -g --debug:full --noframework --define:DEBUG --define:TRACE --optimize- --tailcalls- -r:"C:\Program Files (x86)\Microsoft F#\v4.0\FSharp.Core.dll" -r:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\mscorlib.dll" -r:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Core.dll" -r:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.dll" --target:exe --warn:3 --warnaserror:76 --vserrors --utf8output --fullpaths --flaterrors Program.fs RateLoader.fs ValueAnalyzer.fs RateAnalysis -> C:\Users\ghogen\Documents\Visual Studio 10\Projects\RateAnalysis\RateAnalysis\bin\Debug\RateAnalysis.exe ========== Build: 1 succeeded or up-to-date, 0 failed, 0 skipped ==========
Чтобы добавить клиентское приложение на C#, щелкните правой кнопкой мыши узел решения, наведите указатель на пункт Добавить и выберите Новый проект. В диалоговом окне Добавить новый проект выберите пункт Visual C# в списке Установленные шаблоны, а затем выберите пункт Консольное приложение. Возможно, для этого потребуется раскрыть узел Другие языки. Назовите проект CSharpDriver. Щелкните правой кнопкой мыши узел Ссылки проекта, а затем выберите команду Добавить ссылку. На вкладке Проекты в диалоговом окне Добавить ссылку выберите RateAnalysis и нажмите кнопку ОК. Щелкните узел проекта CSharpDriver правой кнопкой мыши и выберите команду Назначить запускаемым проектом. Введите следующий код в теле метода Main в приложении C#. Обратите внимание на следующее.
Между C# и F# можно добавлять межпроектные ссылки.
Определенные в F# пространства имен и типы можно использовать в C# так же, как и любые другие типы.
Документирующие комментарии F# доступны в IntelliSense для C#.
C# имеет доступ к кортежным возвращаемым значениям из API F#. Кортежи — это значения типа Tuple в платформе .NET Framework 4.
var maturities = new[] { 1, 2, 5, 10 }; var analyzers = RateAnalysis.Analyzer.Analyzer.GetAnalyzers(maturities); foreach (var item in analyzers) { Console.WriteLine("Min = {0}, \t Max = {1}, \t Current = {2}", item.Min, item.Max, item.Current); } Console.WriteLine("Press Enter to exit."); Console.ReadLine();
Для отладки приложения нажмите клавишу F11, чтобы построить его, запустить в отладчике и перейти к первой строке выполняемого кода. Нажимайте клавишу F11, пока не будет достигнут код F# в теле члена GetAnalyzers. Обратите внимание на следующее.
Можно легко переходить из кода C# в код F#.
Каждое выражение F# представляет в отладчике отдельный шаг.
Значения maturities отображаются в окне "Локальные".
При последующих нажатиях клавиши F11 продолжается отладка оставшейся части приложения.
Такие команды отладчика, как Выполнить до курсора, Задать следующий оператор, Вставить точку останова, Добавить контрольное значение и К дизассемблированному коду, работают ожидаемым образом.
Чтобы развернуть приложение F#, выполните следующие действия:
На этом шаге следует переориентировать проект на другую версию платформы .NET Framework. В обозревателе решений щелкните правой кнопкой мыши проект RateAnalysis на F# и выберите пункт Свойства. Выберите платформу .NET Framework 3.5 в списке Целевая рабочая среда на вкладке Приложение. Обратите внимание на следующее.
F# позволяет указывать разные версии платформы .NET Framework в качестве требуемой версии .NET Framework.
Для изменения целевой версии .NET Framework необходимо перезагрузить проект.
После изменения целевой версии .NET Framework ссылки на некоторые сборки будут неактивны и недоступны в диалоговом окне Добавить ссылку.
В проекте C# следует добавить ссылку на версию сборки FSharp.Core, ориентированную на платформу .NET Framework 2.0, которая также должна использоваться в случае ориентации на платформу .NET Framework версии 3.0 или 3.5. Правой кнопкой мыши щелкните узел Ссылки в обозревателе решений, а затем выберите пункт Добавить ссылку. На вкладке .NET выберите сборку FSharp.Core версии 2.0.0.0, после чего нажмите кнопку ОК. Перестройте решение.
Чтобы задать необходимые компоненты, дважды щелкните узел Свойства в проекте CSharpDriver. На вкладке Публикация нажмите кнопку Необходимые компоненты, после чего в диалоговом окне Необходимые компоненты установите флажок Среда выполнения Microsoft Visual F# для .NET 2.0. Обратите внимание на следующее.
Язык F# имеет пакет среды выполнения, отдельный от платформы .NET Framework.
Этот пакет среды выполнения должен быть явно добавлен в список необходимых компонентов при развертывании приложений, в которых используется F#.
Существует два пакета среды выполнения: версия 2.0 для платформ .NET Framework версии 2.0, 3.0 и 3.5, а также версия 4.0 для платформы .NET Framework 4.
Разверните приложение C# с помощью ClickOnce. Щелкните правой кнопкой мыши проект CSharpDriver, а затем выберите команду Опубликовать. В мастере публикации нажмите кнопку Готово. Запустите получившееся приложение CSharpDriver. Обратите внимание на следующее.
Пакет среды выполнения Visual F# включается в состав приложения.
Запуск приложения приводит к установке пакета среды выполнения F#, после чего приложение успешно выполняется.
Следующие действия
Начать писать код на F# можно с прочтения статьи Пошаговое руководство. Создание первой программы на F# или знакомства с функциями F# в статье Функции как значения первого класса (F#). Изучить язык F# можно, прочитав Справочник по языку F#.