逐步解說:使用 Visual F# 建立、偵錯和部署應用程式
這個逐步解說簡介在 Visual Studio 2010 中搭配使用 F# 和 .NET Framework 4 的經驗。
在這個逐步解說中,您將學習如何透過美國財政部利率資料的歷史分析範例,開始使用 Visual Studio 2010 撰寫 F# 應用程式。 您將從使用 F# Interactive 視窗進行一些資料快速分析著手,然後撰寫及測試一些程式碼來分析資料,接著加入 C# 前端以探索 F# 程式碼和其他 .NET 語言的整合情況。
必要條件
您需要下列元件才能完成此逐步解說:
- Visual Studio 2010
注意事項 |
---|
您的電腦可能會在下列說明中,以不同名稱或位置顯示某些 Visual Studio 使用者介面項目。 您所擁有的 Visual Studio 版本以及使用的設定會決定這些項目。 如需詳細資訊,請參閱 Visual Studio 設定。 |
若要建立 F# 指令碼
首先,建立 F# 指令碼。 在 [檔案] 功能表上指向 [新增],然後按一下 [檔案]。 在 [新增檔案] 對話方塊中,選取 [已安裝的範本] 清單中的 [指令碼],然後選取 [F# 指令碼檔案]。 按一下 [開啟] 以建立檔案,然後將檔案儲存為 [RateAnalysis.fsx]。
使用 .NET 和 F# API 從美國聯邦準備理事會的網際網路網站存取資料。 輸入以下程式碼。
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()
請注意以下幾點:
會以顏色標示字串和關鍵字。
在您輸入每一個句號 (.) 之後,完成清單隨即出現。
您可以在識別項的中間使用按鍵盤快速鍵 CTRL+SPACE 或 CTRL+J,以取得 Visual Studio 完整方法名稱和其他識別項。 當您使用 CTRL+J 時,完成清單隨即出現。
當您將滑鼠指標停留在程式碼中的任何識別項時,您會看見一個包含該識別項相關資訊的工具提示。
如果您在游標位於 WebRequest 時按 F1,則會顯示預期的文件。
如果您在游標位於 let 時按 F1,則會顯示預期的文件。
預設會參考 mscorlib.dll、System.dll 和 System.Windows.Forms.dll 的中類型和命名空間。
此處所設定的 Timeout 值是屬性,而非建構函式引數。 F# 可讓您以這種方式設定屬性值。
如果將範例中的 URL 複製到瀏覽器中,則會取得一份以逗號分隔的值清單,內含美國聯邦準備理事會所宣佈的日期和利率。
您現在將使用 F# Interactive 執行程式碼。 選取所有程式碼 (使用滑鼠或按下 CTRL+A) 並且按一下滑鼠右鍵,然後按一下 [傳送到 Interactive] (或者,按下 ALT+ENTER)。
如果尚未出現,則會顯示 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;;,然後按 ENTER 鍵。 輸入 csv.Length;;,然後按 ENTER 鍵。 請注意以下幾點:
這是目前的資料。
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+ENTER,以查看部分結果。 請注意以下幾點:
即使在複雜巢狀運算式的中間,在您輸入句號之後,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])
您現在將為這項功能命名。 從 url 的定義中移除 10 並以 %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+ENTER,以使用 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
請注意以下幾點:
您現在將產生 XML 文件註解。 以滑鼠右鍵按一下 [方案總管] 中的專案,然後按一下 [屬性]。 在 [建置] 索引標籤上,選取頁面下方的 [XML 文件檔案] 核取方塊。 請注意以下幾點:
您可以產生任何 F# 組件的 XML 文件。
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] 專案節點,然後按一下 [設定為啟始專案]。 在 C# 應用程式的 Main 方法主體中輸入下列程式碼。 請注意以下幾點:
您可以在 C# 和 F# 之間加入專案對專案間參考。
就像任何其他類型一樣,可以從 C# 使用 F# 定義的命名空間和類型。
在 C# IntelliSense 中可以使用 F# 文件註解。
C# 可以從 F# API 存取 Tuple 傳回值。 Tuple 就是 .NET Framework 4 Tuple 值。
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 數次,直到您逐步執行至 GetAnalyzers 成員主體中的 F# 程式碼。 請注意以下幾點:
您可以輕易地從 C# 程式碼逐步執行至 F# 程式碼。
F# 中的每一個運算式都是偵錯工具中的一個步驟。
[區域變數] 視窗會顯示 maturities 的值。
繼續按 F11 逐步完成其餘的應用程式評估。
[執行至游標處]、[設定下一個陳述式]、[插入中斷點]、[加入監看式] 和 [移至反組譯碼] 等偵錯工具命令全都如預期運作。
若要部署 F# 應用程式:
在這個步驟中,您會將專案設定為以不同版本的 .NET Framework 為目標。 在 [方案總管] 中,以滑鼠右鍵按一下 F# RateAnalysis 專案,然後按一下 [屬性]。 在 [應用程式] 索引標籤上,將 [目標 Framework] 設定變更為 [.NET Framework 3.5]。 請注意以下幾點:
F# 允許您以不同版本的 .NET Framework 為目標。
變更目標 Framework 時需要重新載入專案。
變更目標 Framework 之後,某些組件參考便無法在 [加入參考] 對話方塊中啟用,而且無法再使用。
在 C# 專案中,您必須加入以 .NET Framework 2.0 為目標之 FSharp.Core 組件版本的參考,而當您以 .NET Framework 3.0 和 3.5 版為目標時也應該使用該參考。 在 [方案總管] 中,以滑鼠右鍵按一下 [參考] 節點,然後按一下 [加入參考]。 在 [.NET] 索引標籤上,選取 FSharp.Core 2.0.0.0 版,然後按一下 [確定]。 重建方案。
若要設定必要條件,請按兩下 CSharpDriver 中的 [屬性] 節點。 按一下 [發行] 索引標籤上的 [必要條件] 按鈕,然後在 [必要條件] 對話方塊中,選取 [適用於 .NET 2.0 的 Microsoft Visual F# Runtime] 的核取方塊。 請注意以下幾點:
F# 與 .NET Framework 的執行階段套件不同。
當您部署使用 F# 的應用程式時,必須將這個執行階段套件明確加入為必要條件。
可用的執行階段套件有兩個:2.0 版 (適用於 .NET Framework 2.0、3.0 和 3.5 版) 與 4.0 版 (適用於 .NET Framework 4)。
使用 ClickOnce 部署 C# 應用程式。 以滑鼠右鍵按一下 CSharpDriver 專案,然後按一下 [發行]。 在 [發行精靈] 中,按一下 [完成]。 執行產生的 CSharpDriver.application。 請注意以下幾點:
應用程式隨附 Visual F# 執行階段套件。
執行應用程式時會安裝 F# 執行階段套件,並且可成功執行應用程式。
後續步驟
請閱讀 逐步解說:您的第一個 F# 程式以便開始撰寫 F# 程式碼,或是閱讀當做優先使用值的函式 (F#)以了解 F# 中的函式。 您可以閱讀 F# 語言參考以探索 F# 語言。