F#基础教程 ref类型

 

     ref类型是在一个程序里使用可变状态的一种简单的方式,也就是说,可以随时间改变的值。ref类型仅仅是一个纪录类型的单一可变字段,在F#库中。访问和更新字段的一些操作符的定义都很简单。F#的ref类型定义使用类型参数,在上一章介绍过这个概念,所以尽管ref类型的值可以是任何类型,一旦您已创建了一个实例的值,你将不能改变值的类型。

     创建一个ref类型的实例很简单,你可以使用关键字ref后跟代表任何项目的ref值。下面的例子是编译器的输出(显示phrase的类型是 string ref,意思是一个仅包含字符串的引用类型)

let phrase = ref "Inconsistency"
val phrase : string ref

     这种语法类似于定义一个联合类型的构造函数。ref类型有两个内置的操作符来访问它;感叹号(!)用于访问引用类型的值,一个冒号加等号组成的操作符用于更新它。!操作符总是返回一个内容类型的值的引用类型。:=操作符具有类型unit,因为它不返回任何值。

     下面的例子演示了如何使用一个ref类型统计一个数据的内容。在totalArray的第三行,可以看到ref类型的创建。在本例中,它被创始化为0,在第5行,可以看到ref类型的访问与更新,首先,!用于访问ref类型的值,然后把它与数组当前的值相加,通过使用:=操作符来更新ref类型的值。代码输出如下。

#light
let totalArray () =
     let a = [| 1; 2; 3 |]
     let x = ref 0
     for n in a do
          x := !x + n
     print_int !x
     print_newline()


totalArray()
执行结果:
6

注意:如果你使用过C系列的编程语言,你应该要小心。在阅读F#代码时,很容易误解ref类型的!操作符,为布尔运算的“not”操作符。

     在几个函数之间共享mutable值,是ref类型一个非常有用的方式。一个标识符可以绑定一个ref类型,定义的范围包括所有想共同使用标识符值的函数;然后函数可以使用标识符定义的值,更改它或仅读取它。因为在F#里的函数可传递外围的值,如何函数中包括值的使用。在函数外的任何位置,通过函数可访问到值(原文搞不清什么意思,大意和闭包的说法一样)。这个过程被称为捕获本地或创建一个闭包。下一个例子演示了定义三个函数,inc, dec, 和 show,都有一个共同的ref类型指向一个整数。函数inc, dec, 和 show都有其私有的范围定义,最后返回到顶层时组成一个元组,以方便它们随处可见。注意为何不返回n,它仍然是私有的,但inc, dec, 和 show仍然能够访问n。这是一种很有用的技巧,控制那些地方可以操作mutable数据。

#light
let inc, dec, show =
     let n = ref 0
     let inc () =
          n := !n + 1
     let dec () =
          n := !n - 1
     let show () =
          print_int !n
     inc, dec, show


inc()
inc()
dec()
show()
执行结果:
1

posted @ 2011-12-08 21:16  银河系漫游指南  阅读(1117)  评论(0编辑  收藏  举报