F#第一章试译

第一章 

F#简介

 

 

 

 

 

F#是一门优秀函数式编程语言。这章将简单的介绍F#的核心——F#的编译器,工具,以及他在Visual Studio 2010中的一些相关内容。

 

在这章中,您将学会数个F#应用程序的例子,与此同时,我会指出,如何使用Visual Studio来做F#的开发。我并不会涉及太多的Visual Studio,因此我鼓励您去用自己的方式去探究IDE中更多关于Visual Studio中的技巧。当然,您也可以通过在线文档来学习:http://msdn.microsoft.com/en-us/vstudio/default.aspx

 

如果您已经对Visual Studio很熟悉了,您也应该大致浏览本章。创建和调试一个F#工程项目和创建调试一个C#或者是VB.NET项目并没有太大区别。但是,F#在创建一个多文件项目时拥有一个独一无二的特点。并且,F#支持一个名为交互式输入的新玩意(F# Interactive),它将大大改善您的工作效率。千万不要忽视他。

 

 

 

开始了解F#

不管是什么编程书籍,通常都是先介绍如何书写一个hello world程序,我也不打算脱离这个传统。打开您的记事本或者是其他您喜欢的文本编辑器并创建一个名为HelloWorld.fs的新文件,写入以下内容:

 

    // HelloWorld.fs

    printfn “Hello, World”

 

恭喜您!您刚刚已经完成了您第一个F#应用程序。您可以通过F#的编译器fsc.exe来编译这个应用程序。他位于Program Files\Microsoft F#\v4.0 folder下。(当然,您也可以使用Mono,任意一个您安装F#的地方。)接下来的内容,将给您展示,如何通过在命令提示符下使用F#的编译器来编译并运行您的应用程序:

 

C:\Program Files\Microsoft F#\v4.0>fscHelloWorld.fs

Microsoft F# Compiler, (c) MicrosoftCorporation, All Rights Reserved

F# Version 1.9.8.0, compiling for .NETFramework Version v4.0.21017

C:\Program Files\MicrosoftF#\v4.0>HelloWorld.exe

Hello, World!

 

 

 

Visual Studio 2010

工具是任何一门编程语言的生命之源,F#当然也不在此之外。当您能够成功的在您最喜欢的文本编辑器上写下F# 代码但是却只能通过命令提示符来编译他时,您肯定会期待更加有效率的工具的出现。同C# 和 VB.NET 一样,虽然F# 是 Visual Studio中的新成员,但F#在Visual Studio 中拥有所有你期待拥有的功能,包括调试器,项目模板等等。

 

 

打开您的Visual Studio IDE并且选择菜单栏中的File->New Project来打开New Project对话框,在这里,您可以创建您的第一个F#工程,如图1-1所示。在左边的窗口中选择 Visual F#,然后在右边的窗口中选择F#应用程序,再点击OK。

 

 图1-1。选择F# Application来建立您第一个F#工程。

 

当您在New Project对话框中点击了OK按钮以后,您将会看到有一个空的编辑模板来给您书写您那优雅的F#代码。

在开始这一切之前,让我们复习一下我们的Hello , World程序。在编辑器中写下如下的代码:

         printfn “Hello, World”

现在,按下Ctrl+F5来运行您的程序。当您的程序开始运行时,一个控制台窗口将出现在您面前,并且展示出如图1-2的样貌。

 

图1-2。F#的Hello, World

 

 

 

您的第二个F#程序

看起来,程序的运行并不需要一个明确显示的Main方法。您可以在第二章中了解到为什么F#允许这样做,但是现在,让我们先完成一个更加有实际意义的Hello World,他会带大家体会F的#典型语法特征。

示例1-1中的代码将演示一个接受2个控制台参数并将他们打印到控制台下输出的程序。特别的,他将打印当前的时间。

 

Example 1-1.Mega Hello World

(*

MegaHello World

Take TwoCommand line parameter and then print

themalong with the current time to the console.

*)

 

openSystem

 

[<EntryPoint>]

let main(args : string[]) =

    if args.Length <> 2 then

       failwith "Erro: Expected arguments<greeting> and <thing>"

    let greeting, thing = args.[0], args.[1]

    let timeOfDay = DateTime.Now.ToString("hh:mmtt")

 

printfn "%s,%s at %s" greetingthing timeOfDay

 

// Program exit code

0

 

现在,您有了真正意义上的F#代码了,希望您能对接下来的都感兴趣。

让我们一行接一行的分析这个程序到底是如何工作的。

 

 

 

变量

Example1-1 介绍了3个变量 greeting, thing 和 timeOfDay :

    let greeting, thing = args.[0], args.[1]

    let timeOfDay = DateTime.Now.ToString(“hh:mmtt”)

 

其中的核心部分是关键字let,他让一个变量名捆绑了一个变量。需要指出的是,和绝大部分的语言不同,在F#中,一个变量在通常情况下是不可变的(immutable),这意味着,他们一旦初始化以后就能再改变。我们将在第三章讲述为什么变量不能被改变,但是现在我们仅需知道他足以进行函数式编程。

F#是很敏感的,因此任何2个变量的名字哪怕仅有一点点不同,也会被认为是不同的:

    let number = 1

    let Number = 2

    let NUMBER = 3

一个合法的变量名必须是以字母或者下划线开头的,任意的字母,数字,下划线,或者是单引号的组合。

您可以把一个变量名放置在2个单引号之间,这样可以让变量名包含除了制表符(tab)和换行符以外的所有字符。这样就允许你在其他场合引用变量或者是函数。.NET下其他语言的关键字也许会和F#的关键字产生冲突:

       let ``this.Isn't %A% good valueName$!@#`` = 5

 

 

 

空白符的那些事

很多其他的语言,像C#,使用分号或者是大括号来指出一个居于或者是一个代码块的结束。但是,程序员们通常会使用特别的缩进来维护代码的可读性,因此,这些额外的符号在程序中往往只会变成是让语法变得更加丑陋。

在F#中,空白符中的空格和回车是有特殊意义的。F#的编译器允许你使用空白符来区分不同的代码块。例如,任何在if语句里面内缩进的代码都被当作是if的内部代码块。因为tab字符能够代表未知数量的字符,因此他们在F#中被禁止使用。

您可以在Visual Studio编辑器菜单栏的Tools->Options->TextEditor->F#来修改配置来设置tab自动缩进的的等效空白字符数。

 

下面,让我们复习Example 1-1 ,从中发现main方法的代码块都缩进了4个空白字符,而且if的代码块还额外的缩进了4个空白字符。

 

let main (args : string[]) =

        ifargs.Length <> 2 then

           failwith"Erro: Expected arguments <greeting> and <thing>"

        letgreeting, thing = args.[0], args.[1]

        lettimeOfDay = DateTime.Now.ToString("hh:mm tt")

 

printfn "%s,%s at %s"greeting thing timeOfDay

 

// Program exit code

0

 

如果if代码块中的failwith,没有缩进4个字符,也就是说,他和if关键字并排,那么F#的编译器会给出一个警告。这是因为编译器不能确定failwith是属于if代码块中的内容。

 

         [<EntryPoint>]

    let main (args : string[]) =

 

       if args.Length <> 2 then

           failwith “Error: Expected arguments<greeting> and <thing>”

 

    Waring FS0058: possible incorrectindentation: this token is offside of

    context started at position (25:5). Tryindenting this token further or

    using standard formatting conventions

 

一般来说,任何一个方法或者是语句的内部代码块都必须相对上一行的第一个关键字进行缩进。因此在Example 1-1中,所有属于main方法的内部代码偶相对于main方法的的let有缩进,并且在if的内部代码块中,在if后面的每一行都相对于if有缩进。当您有了更多基于F#的编程或者是阅读F#代码的经验时,你会发现,没有逗号和括号是那么的美好,他使得我们更加轻松的去书写和阅读。

 

.NETInterop

Example1-1 同样演示了F#是如何访问已经存在的.NET类库的:

    open System

 

    // …

 

    let timeOfDay = DateTime.Now.ToString(“hh:mmtt”)

 

.NET平台包含了很多类库,这些类库囊括了从图形到数据库到网络服务的几乎所有东西。F#通过调用相关类库来使用.NET的所有类库。在Example 1-1中,DateTime.Now是属于System命名空间中部分,他从属于mscorlib.dll这个二进制文件。同样,任何用F#编写的代码同样可以被.NET平台上的其他语言所使用。

 

如果您需要了解更多关于.NET类库的资料,您可以通过浏览本书的附录来做一个快速的导读判断哪些是可行的。

 

 

 

注释

和其他语言一样,F#允许您注释您的代码。使用双反斜杠来注释一行代码,任何在他们之后的该行代码将被编译器所忽略:

    // Program exit code

 

如果您需要一次注释多行代码,您可以使用多行注释,编译器将忽略在(*和*)之间的所有东西。

    (*

    Mega Hello World:

    Take tow command line parameters and thenprint

    Them along with the current time to console.

    *)

 

对于在Visual Studio上编写的F#代码,还有第三种注释风格:XML文档注释。如果一段注释把3个反斜杠///放置在一个标识符前面,在您调用他的时候(hover over it),Visual Studio会打印这些注释内容。

 

 

 

F#的交互模式

到目前为止,您已经写过并执行过一些F#代码了,并且在本书接下来内容中(and the rest of the book),您将会接触到新的工程,并且尝试那些例子。(While you could leave a wake ofnew projects while working through this book and trying out the samples),Visual Studio提供了一个叫做F#交互模式的工具,我们也把他称作是FSI。通过使用FSI窗口,您不仅可以更加容易的尝试书中的示例代码,而且可以帮助您编码应用程序。

 

 

Figure1-3. XML文档注释

 

F#交互模式是一种动态语言的工具,是一种典型的输入即输出的典范。他可以接纳F#代码,编译并执行代码,然后打印出结果。这可以让您轻松便捷的在建立工程或者是书写完整的F#应用程序以外体验F#代码,观看一些短的代码片段的执行结果。(see the result of afive-line snippet)

 

在C#和VB.NET中,您必须编译并执行您的代码才能看到结果。毫无疑问,这是一种很繁琐方式来体验一些简短的代码。甚至您使用Visual Studio的即时窗口进行调试的时候,您也被限制在只能使用表达式,而不能真正的编写程序,比如,定义一些新的函数或者是类。

 

在Visual Studio中,通常使用组合键Ctrl+Alt+F来打开FSI窗口。当FSI窗口被激活时,他能接纳以;;或者是换行结尾的F#代码。这些代码输入以后将如同Figure1-4一样被编译并且执行。

 

在一段段代码被输入进FSI后,每当有一个变量名输入时,您当会看到 val<name>这样的字样。如果是一个没有名字的表达式被输入的时,他们都有一个共同的默认名字——it。在这个标识符的后面,还会有一个冒号和这段代码的值出现。例如,在Figure 1-4中,变量x被输入,他的类型是int,他的值是42。

 

    如果您没有在Visual Studio中使用F#,您可以在同一个目录下找到找到一个名为fsi.exe控制台版本的F#交互模式作为替代品。

 

试试在FSI中运行简短的代码。记住,任何代码段都必须以;;结束。

> 2 + 2;;

> val it : int = 4

> // Introduce two values

let x = 1

let y = 2.3

 

val x : int

val y : float

 

       > float x + y;;

       val it : float = 3.3

       > let cube x = x * x *x;;

 

       val cube : int -> int

 

       > cube 4;;

       val it : int = 64

 

FSI同样可以大大简化您的测试和调试程序的过程。因为您可以在在Visual Studio中选中F#代码以后按下Alt+Enter来把您当前的代码输入到FSI中去。

 

Figure1-4. The F# Interactive window

 

在代码编辑器中选中了Example 1-1 所有代码并按下Alt+Enter以后,您会在FSI窗口中发现如下情况:

    >

 

    val main : string array -> int

 

这可以让您在Visual Studio编辑器中书写有语法高亮的代码的同时拥有在FSI这个交互模式下测试您的代码的功能。您可以通过如下的调用测试您输入到FSI中去的main方法:

    > main [|”Hello”; “World”|];;

    Hello World at 10:52 AM

    val it : int = 0

 

    本书的绝大部分例子都讲使用FSI的模式。我鼓励您继续使用FSI,并且在FSI中体验F#的语法规则。

 

 

 

管理F#源文件

当您刚刚开始F#编程时,您编写的绝大部分程序往往只存在与FSI或者是单一的源文件中。随着您编程经验的增长,您的工程将飞速膨胀,很快就能扩展到多文件甚至是多工程。

F#有不同寻常的特点来管理多文件工程。在F#中,哪些写有代码文件将被编译是很有讲究的。(the order in which codefiles are compiled is significant)

 

您只能调用在文件中已经定义过或者是在指定文件中已经编译过的函数或者是类。如果您重新组织您的源文件顺序,您的工程将不能被编译。

 

    这样做的理由是F#中的类型推倒,这将在接下来的一章进行讲解。

 

F#源文件将按照他们在Visual Studio解决方案管理器中从上到下的排列顺序来编译。当您在工程中添加一个文件的时候,这个文件会自动的加到列表的最下面,如果您想重新排列源文件,您和Figure 1-5所示的那样可以右击一个文件并且选择Move Up或者是Move Down。对应的整理工程文件顺序的键盘快捷键是Alt+Up和Alt+Down。

 

现在,您已经对如何编译F#应用程序有了一个初步的认识,在本书接下来的内容中,将更加深入的探讨F#的语法和语义。

 

 

    Figure 1-5. Reordering files within an F#project

posted @ 2010-11-28 12:04  Dickhead  阅读(325)  评论(0编辑  收藏  举报