F#标识符

常量(Literal)

值和函数

标识符的作用域

使用use

F#标识符
F#标识符就是给值命名。使用let关键字和一个等号,再跟一个表达式。表达式是任何代码,可以返回一个值。入下面的给标识符赋值。
let x = 42
很程序员,一眼看到这个代码就觉得这个是变量赋值嘛,这虽相似,但是却不同。在纯粹的函数式编程中,一旦值赋给标识符,就不再改变。这就是为什么称作标示符而不是变量的原因。(在某些场合下,这个标识符的值也是可以改变的。)
常量(Literal)
Literal表示常量值,F#有很多常量。
F#字符常量可以包含换行符,正则表达式常量可以包含标准转义符。可以加上合适的前缀和后缀,用16进制或者8进制方式定义整型。可以看一下面的代码,(注意,缩进是必须的,后面会讲到)。%A表示一种格式模式。
#light
let
 message
 
=
 
"Hello
World\r\n\t!"
let
 dir
 
=
 @"c:\projects"
let
 bytes
 
=
 
"bytesbytesbytes"B
let
 xA
 
=
 0xFFy
let
 xB
 
=
 0o7777un
let
 xC
 
=
 0b10010UL
let
 print x
 
=
 printfn
 
"%A"
 x
let
 main
(
)
 
=
    print message
;
    print dir
;
    print bytes
;
    print xA
;
    print xB
;
    print xC
main
(
)
运行结果如下:
值和函数
F#中,值和函数是不区分的,因为函数就是值,F#语法处理起来都很相似。比如下面的代码。第一行,10赋给了标识符n。第二行,函数add,定义为把2个参数相加。两种的语法很相似,不同点就是函数名字后面有参数。表达式a+b也是add函数的值。注意,就像在命令行语言中那样,函数不需要显式的返回值。
#light
let n = 10
let add a b = a + b
let addFour = add 4
let result = addFour n
printfn "result = %i" result
F#支持函数的部分应用(也称作curried functions,柯里函数)Currying是为了纪念美帝数学家Haskell Brooks Curry而命名的。
在计算机科学中,柯里化(Currying),又称部分求值(Partial Evaluation),是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。
柯里函数详见:
http://en.wikipedia.org/wiki/Currying
http://learnyouahaskell.com/higher-order-functions#curried-functions
柯里函数意味着不需要吧所有的参数传给函数。如上述第三行代码。
#light
大部分的F#文件以”#light”开头(译者注:在当前的Dev10版本中已经把”#light”设置为默认打开,所以当前的F#文件不需要再显示的调用”#light”)
#light
这个是用来打开”轻量级语法(lightweight syntax)”选项的.我在这里不会讨论和” 轻量级语法”对应的选项是什么,因为人们总是使用”轻量级语法”这个选项.而且在下一个F#版本中”” 轻量级语法”将成为默认选项(译者注:当前的F#版本已经这样做了). 现在还是要确保”#light”总是出现在F#代码文件的开头.
标识符的作用域
F#中,不需要显式的返回值,值自动的与标识符绑定。如何在F#中使用中间值呢?F#中,由空格控制。每个缩进都表示一个新的作用域。最后一个缩进表示作用域的终结。缩进意味着let绑定的值是一个中间值,在外部的作用域是看不到的。下面的例子演示了作用域
// function to calculate a midpoint
let halfWay a b =
let dif = b - a
let mid = dif / 2
mid + a
// call the function and print the results
printfn "(halfWay 5 11) = %i" (halfWay 5 11)
printfn "(halfWay 11 5) = %i" (halfWay 11 5)
#light
let printMessage() =
    let message = "Help me"
    printfn "%s" message
printfn "%s" message
let changeType () =
    let x = 1 // bind x to an integer
    let x = "change me" // rebind x to a string
    printfn "%s" x
changeType ()
let changeType () =
    let x = 1 // bind x to an integer
    let x = "change me" // rebind x to a string
    let x = x + 1 // attempt to rebind to itself plus an integer
    printfn "%s" x
changeType ()
在函数中的标识符和最外层才标识符是些不同的。函数定义中的标识符可以重复绑定值,这样你就不需要为创造新的标识符名而头痛。最外层的标识符是不能够重复绑定的,只可以定义一次。
let x=5
let x=x+3
printfn "%i" x
使用use
use和let相似,可以指定标识符的值。但是不同点在于使用use的话,一旦代码运行到作用域之外,该标识符会自动处理dispose。这对于某些操作,比如网络套接字,文件读写,数据库连接等很有必要。在.NET中,这种对象都实现了IDisposable接口,这个use类似c#中的using语句,主要的作用是释放资源。
open
 System.
IO
// function to read first line from a file
let
 readFirstLine filename
 
=
// open file using a "use" binding
  
 
use
 file
 
=
 File.
OpenText
 filename
    file.
ReadLine
(
)
// call function and print the result
printfn
 
"First line was: %s"
 
(readFirstLine
 
"mytext.txt"
)
任何只要实现了IDisposable接口的对象都可以使用use绑定。
use只能在函数内部使用,不能在最外层使用,因为,最外层的标识符作用域是全局的,不会失去活性,因此得不到释放。