F#基础教程 mutable关键字

      在第三章中,我们谈到如何使用关键字let绑定标识符到值,并指出在那些情况下可以重新定义和恢复之前的值,但是不能修改。如果你想定义一个标识符,其值可以随时间而改变(亦即随程序运行而改变),你可以使用mutable关键字,用于更新这些标识符的是一个特殊的操作符,左ASCII箭头(或只是左箭头),由一个小于号和破折号(-)组成。使用左箭头的更新操作具有unit类型,所以你可以链接多个操作。下一个例子演示如何定义一个字符串类型的mutable标识符,然后改变它的值。

#light
let mutable phrase = "How can I be sure, "
print_endline phrase
phrase <- "In a world that's constantly changing"
print_endline phrase
执行结果:
How can I be sure,
In a world that's constantly changing

    乍一看,这与重新定义一个标识符并没有明显的不同,但它有一对不同的关键字。当你使用左箭头更新一个mutable标识符时,你可以改变它的值,但不能改变它的类型,当你重新定义一个标识符时,你两者都可改变。如果你尝试更改mutable标识符的类型将产生一个编译错误,下面演示了这种情况。

#light
let mutable number = "one"
phrase <- 1
试图编译这段代码时,你会得到以下错误消息:
Prog.fs(9,10): error: FS0001: This expression has type
int
but is here used with type
string

     其它主要的区别是,这些变化一直可见。而当你重新定义一个标识符,改变的值仅在新标识符范围内可见,如果超出范围,标识符将恢复旧值。这些情况不同于mutable标识符,任何改变都是永久的,没有范围。下面的例子演示了这一点。

#light
let redefineX() =
    let x = "One"
    printfn "Redefining:\r\nx = %s" x
    if true then
        let x = "Two"
        printfn "x = %s" x
    else ()
    printfn "x = %s" x


let mutableX() =
    let mutable x = "One"
    printfn "Mutating:\r\nx = %s" x
    if true then
        x <- "Two"
        printfn "x = %s" x
    else ()
    printfn "x = %s" x

redefineX()
mutableX()
执行结果
Redefining:
x = One
x = Two
x = One
Mutating:
x = One
x = Two
x = Two

      mutable定义的标识符有些限制,它们不能在子函数中使用。你可以在下面的例子中看到。

#light
let mutableY() =
    let mutable y = "One"
    printfn "Mutating:\r\nx = %s" y
    let f() =
        y <- "Two"
        printfn "x = %s" y
    f()
    printfn "x = %s" y
编译和执行这个例子时的结果如下:
Prog.fs(35,16): error: The mutable variable 'y' has escaped its scope. Mutable
variables may not be used within an inner subroutine. You may need to use a heapallocated
mutable reference cell instead, see 'ref' and '!'.

     正如错误消息提示,你需要ref类型,一种特殊的记录类型,提供在几个函数之间共享的mutable变量,我们将在下一节讨论ref类型的可变记录。

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