共用方式為


逐步解說:使用 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# 指令碼

  1. 首先,建立 F# 指令碼。 在 [檔案] 功能表上指向 [新增],然後按一下 [檔案]。 在 [新增檔案] 對話方塊中,選取 [已安裝的範本] 清單中的 [指令碼],然後選取 [F# 指令碼檔案]。 按一下 [開啟] 以建立檔案,然後將檔案儲存為 [RateAnalysis.fsx]。

  2. 使用 .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 複製到瀏覽器中,則會取得一份以逗號分隔的值清單,內含美國聯邦準備理事會所宣佈的日期和利率。

  3. 您現在將使用 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]
      
      >
      
  4. 接下來,使用 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# Interactive 視窗

  5. 您現在將撰寫 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])
    
  6. 您現在將為這項功能命名。 從 url 的定義中移除 10 並以 %d 取代,讓字串常值變成格式字串。 在格式字串之後加入 maturity。 選取這一行新的程式碼以外的所有程式碼。然後按 TAB 鍵。 在縮排的程式碼區塊之上,加入 let loadRates maturity =。 在縮排的區塊結尾,加入 interest。 請注意以下幾點:

    此程式碼現在與下列程式碼相似:

    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
    
  7. 您現在將在新的輸入上使用這項功能。 選取所有程式碼並且按 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# 程式庫]

  1. 您現在將建立 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#) 和其他相關主題。
  2. 您現在將產生 XML 文件註解。 以滑鼠右鍵按一下 [方案總管] 中的專案,然後按一下 [屬性]。 在 [建置] 索引標籤上,選取頁面下方的 [XML 文件檔案] 核取方塊。 請注意以下幾點:

    • 您可以產生任何 F# 組件的 XML 文件。

    • XML 文件預設會產生至輸出路徑中。

  3. 若要建置專案,請按 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 ==========
      
  4. 若要加入 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();
    
  5. 若要對應用程式進行偵錯,請按 F11 以建置應用程式,在偵錯工具中啟動應用程式,然後逐步執行至已執行程式碼的第一行。 按 F11 數次,直到您逐步執行至 GetAnalyzers 成員主體中的 F# 程式碼。 請注意以下幾點:

    • 您可以輕易地從 C# 程式碼逐步執行至 F# 程式碼。

    • F# 中的每一個運算式都是偵錯工具中的一個步驟。

    • [區域變數] 視窗會顯示 maturities 的值。

    • 繼續按 F11 逐步完成其餘的應用程式評估。

    • [執行至游標處]、[設定下一個陳述式]、[插入中斷點]、[加入監看式] 和 [移至反組譯碼] 等偵錯工具命令全都如預期運作。

若要部署 F# 應用程式:

  1. 在這個步驟中,您會將專案設定為以不同版本的 .NET Framework 為目標。 在 [方案總管] 中,以滑鼠右鍵按一下 F# RateAnalysis 專案,然後按一下 [屬性]。 在 [應用程式] 索引標籤上,將 [目標 Framework] 設定變更為 [.NET Framework 3.5]。 請注意以下幾點:

    • F# 允許您以不同版本的 .NET Framework 為目標。

    • 變更目標 Framework 時需要重新載入專案。

    • 變更目標 Framework 之後,某些組件參考便無法在 [加入參考] 對話方塊中啟用,而且無法再使用。

  2. 在 C# 專案中,您必須加入以 .NET Framework 2.0 為目標之 FSharp.Core 組件版本的參考,而當您以 .NET Framework 3.0 和 3.5 版為目標時也應該使用該參考。 在 [方案總管] 中,以滑鼠右鍵按一下 [參考] 節點,然後按一下 [加入參考]。 在 [.NET] 索引標籤上,選取 FSharp.Core 2.0.0.0 版,然後按一下 [確定]。 重建方案。

  3. 若要設定必要條件,請按兩下 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)。

  4. 使用 ClickOnce 部署 C# 應用程式。 以滑鼠右鍵按一下 CSharpDriver 專案,然後按一下 [發行]。 在 [發行精靈] 中,按一下 [完成]。 執行產生的 CSharpDriver.application。 請注意以下幾點:

    • 應用程式隨附 Visual F# 執行階段套件。

    • 執行應用程式時會安裝 F# 執行階段套件,並且可成功執行應用程式。

後續步驟

請閱讀 逐步解說:您的第一個 F# 程式以便開始撰寫 F# 程式碼,或是閱讀當做優先使用值的函式 (F#)以了解 F# 中的函式。 您可以閱讀 F# 語言參考以探索 F# 語言。

請參閱

其他資源

Visual F# 逐步解說

範例與逐步解說 (F#)