前面写的Hello F#~似乎连主方法都没有(怎么运行起来的?)...那这次写个大的。
在Program.fs文件内粘贴上下面的代码:
open System [<EntryPoint>] let main (args : string[]) = if args.Length <> 2 then failwith "Error: Expected arguments <greeting> and <things>" let greeting, things = args.[0], args.[1] let timeOfDay = DateTime.Now.ToString("hh:mm tt") printfn "%s, %s at %s" greeting things timeOfDay // Program exit code 0
然后播放~
如果你在苹果电脑上执行的那一定是你自己的错,Windows上出错了那可能是我们代码写错了。
那无所谓,不管,权当我打脸。看看这些代码吧。
let greeting, things = args.[0], args.[1] let timeOfDay = DateTime.Now.ToString("hh:mm tt")
这儿我们引入了两个值(不是变量,当常量看吧!),let关键字将一个名称绑定到了一个值。这里值得指出的是,和大多数其他编程语言不同的是,在F#中的值默认是不可变的,意味着它们一旦被初始化便不能被修改。
当然要改也可以。
F#也是区分大小写的,所以任何两个值的名字只要大小写不同,那么就视为不同的值:
let number = 1 let Number = 2 let NUMBER = 3
老生常谈:一个值的名字可以由任意的字母、数字、下划线(_)和撇号(’)组成。不过,名字必须由字母和下划线开头。
操蛋的小技巧:你可以使用双定位点将字符包围起来作为值的名字,在这种情况下,名字可以包含除了标签和新行的任意字符。这允许你指向一个由其他.NET语言提供的可能与F#关键字冲突的值和函数: let ``this.Isn't %A% good value Name$!@#`` = 5
在前面说了,不能为了好看打空格,乱打空格会出事。我们可以看到吼,main方法的主体缩进了四个空格,而if语句的主体往后面继续缩进了四个空格。
let main (args : string[]) = if args.Length <> 2 then failwith "Error: Expected arguments <greeting> and <things>"
如果if语句的主体 failwith "…"
表达式被缩进了四个空格变得和if关键字统一层次,那么F#编译器将会产生一个警告。这是因为编译器不能确定failwith到底是if语句的内容还是main函数的内容,就像这样:
[<EntryPoint>] let main (args : string[]) = if args.Length <> 2 then failwith "Error: Expected arguments <greeting> and <things>" Warning FS0058: Possible incorrect indentation: this token is offside of context started at position (25:5). Try indenting this token further or using standard formatting conventions.
从mscorilib.dll程序集中调用System命名空间里的DateTime.Now属性:
open System // ... let timeOfDay = DateTime.Now.ToString("hh:mm tt")
.NET Framework包含了浩如烟海的库,囊括了从图形到数据库再到Web服务的一切。F#可以直接利用任意.NET库。同样,使用F#编写的代码也可以被其他.NET语言所调用。这也就意味着F#应用程序可以运行在任何支持.NET的平台上,所以你写的F#程序可以在你的手机上,在你的平板电脑上,在你的个人电脑上等等一系列平台上运行。
至于.NET库的内容建议去MSDN看。
F#允许为我们的代码编写注释。使用双斜杠(//)表示一个单行注释;在这之后一直截止到行尾的内容都会被编译器忽略:
// Program exit code
你可以使用(* 和 *)来表示大量的注释。在这两个标记之间的代码将会被忽略:
(* Comment spanning multiple lines *)
在Visual Studio中编写F#程序,有第三种注释办法——一个XML文档注释。如果一个放在标识上方的注释以三个斜杠(///)开始,那么当你鼠标徘徊在标识符号附近,Visual Studio将会显示注释文字(Xamarin也适用)。
每次都要使用“播放”才能运行程序似乎有点麻烦惹。所以M$提供了F# Interactive工具。 F# Interactive工具是一个REPL,是一个“读取,求值,输出”循环。它能够编译并执行F#代码,然后输出结果。这样允许你简单快速地使用F#测试而不需要创建一个新的工程或者重构一个完整的程序来测试一个代码片段的结果。
大多数Visual Studio启动F#人机交互窗口是Ctrl-Alt-F组合键。其他平台安装完环境后可以尝试在Terminal内输入 fsharpi
,一旦FSI窗口出现,它就可以接受F#代码直到你以;;或者换行结束输入。输入的代码将被编译执行,
如果你正在Visual Studio之外运行F#,你可以在找到fsc.exe的这个目录下找到F#人机交互的命令行版本,就是fsi.exe。
我们键入 let x = 100;;
然后按下回车键
该FSI窗口输入引入的任何新值以及他们的类型。图中的 val x : int = 100
,声明了一个名为x,值为100的的int类型的值。如果FSI窗口计算了一个没有被指定值的一个表达式,它将会把计算结果分配给 it
。
继续尝试更多的代码片段:
> 1 + 1;; val it : int = 2 > // Let's input more things let m = 0.001 let n = 99;; val m : float = 0.001 val n : int = 99 > int m + n;; val it : int = 99 > let calc x = x * x;; val calc : x:int -> int > calc 0;; val it : int = 0
FSI将会大大简化测试和调试应用程序,因为我们可以选中想测试的代码,然后按下Alt-Enter组合键从当前的工程把F#代码发送到FSI窗口,例如我们把我们写的大型Hello F#~程序发送到FSI:
> val main : args:string [] -> int
这意味着你可以在一个提供代码高亮和智能感知的Visual Studio/Xamarin中编写代码,在FSI中测试代码。我们可以从FSI中调用主方法来检查它的实现:
> main [|"Hello"; "F#~"|];; Hello, F#~ at 04:39 下午 val it : int = 0
当开始使用F#编程的时候,编写的大部分程序只能在FSI或者一个单独的代码文件中存留。但是我们的F#工程将会慢慢变大,然后可能因多个文件出现问题。
F#语言有一些独特的特点来帮助管理具有多个源文件的工程。在F#中,代码文件的顺序是很重要的。
我们只能调用在代码文件或者一个单独的在代码文件编译前面的代码文件中已经定义的函数和类。如果改变了源文件顺序,程序或许将无法构建!
其实主要是因为类型推断的缘故所以需要保持这个顺序。
Visual Studio缺失一种将一个F#工程的源代码组织进子文件夹的功能。虽然不是Visual Studio用户界面暴露出的问题,但是你可以直接编辑工程文档来达到这个目的。