ZetCode

F# 变量

最后修改于 2025 年 5 月 3 日

在本文中,我们将探讨如何在 F# 中有效地使用变量。变量是任何编程语言的基本构建块。

一个 变量 是一个命名的存储位置,用于保存一个值。在 F# 中,变量默认是不可变的,这意味着它们的值在初始化后不能被更改。但是,可以使用 mutable 关键字创建可变变量。F# 使用类型推断来确定变量类型,但也支持显式类型声明。

F# 不可变变量

不可变变量是 F# 的默认设置。一旦赋值,它们的值就不能更改。

immutable.fsx
let x = 5
let name = "John Doe"
let active = true

printfn "%d" x
printfn "%s" name
printfn "%b" active

该程序定义了三个不同类型的不可变变量:整数、字符串和布尔值。然后我们打印它们的值。

let x = 5

这会创建一个值为 5 的不可变整数变量 x。let 关键字用于变量声明。

λ dotnet fsi immutable.fsx
5
John Doe
true

F# 可变变量

可变变量在初始化后可以更改其值。

mutable.fsx
let mutable counter = 0
printfn "Initial value: %d" counter

counter <- counter + 1
printfn "After increment: %d" counter

counter <- counter + 1
printfn "After second increment: %d" counter

我们创建一个可变的计数器变量,将其递增两次,并在每个步骤打印其值。

let mutable counter = 0

mutable 关键字使变量可更改。如果没有它,这将是一个编译错误。

counter <- counter + 1

<- 运算符用于为可变变量赋新值。

λ dotnet fsi mutable.fsx
Initial value: 0
After increment: 1
After second increment: 2

F# 变量类型注解

F# 支持变量的显式类型注解。

typed.fsx
let age: int = 34
let name: string = "Roger Roe"
let height: float = 172.5

printfn "%s is %d years old and %.1f cm tall" name age height

我们声明三个带有显式类型注解的变量并打印它们。

let age: int = 34

冒号后面跟着类型,明确指定了变量的类型。

λ dotnet fsi typed.fsx
Roger Roe is 34 years old and 172.5 cm tall

F# 变量作用域

F# 中的变量具有块作用域,仅在其定义的块内可见。

scope.fsx
let outer = "I'm outside"

if true then
    let inner = "I'm inside"
    printfn "%s" inner
    printfn "%s" outer

// printfn "%s" inner // This would cause an error
printfn "%s" outer

该示例演示了 F# 中的变量作用域。内部变量只能在 if 块内访问。

let inner = "I'm inside"

此变量仅在其定义的 if 块内可见。

λ dotnet fsi scope.fsx
I'm inside
I'm outside
I'm outside

F# 变量遮蔽

F# 允许遮蔽 - 在更窄的作用域中用相同的名称声明一个新变量。

shadowing.fsx
let x = 10
printfn "Outer x: %d" x

let innerFunction () =
    let x = 20
    printfn "Inner x: %d" x

innerFunction()
printfn "Outer x again: %d" x

我们通过在函数内创建新的 x 来演示变量遮蔽。

let x = 20

这会在函数的作用域内创建一个新的 x,该 x 遮蔽了外部的 x。

λ dotnet fsi shadowing.fsx
Outer x: 10
Inner x: 20
Outer x again: 10

F# 元组变量

元组允许将多个值分组到一个变量中。

tuples.fsx
let person = ("John Doe", 34, "gardener")
printfn "Full tuple: %A" person

let name, age, occupation = person
printfn "Name: %s, Age: %d, Occupation: %s" name age occupation

let first, _, _ = person
printfn "Just the name: %s" first

我们创建一个元组变量并演示访问其值的不同方法。

let person = ("John Doe", 34, "gardener")

这会创建一个包含三个不同类型值的元组。

let name, age, occupation = person

这会将元组解构为单独的变量。

λ dotnet fsi tuples.fsx
Full tuple: ("John Doe", 34, "gardener")
Name: John Doe, Age: 34, Occupation: gardener
Just the name: John Doe

F# 引用单元

引用单元提供了一种处理可变状态的替代方法。

refcells.fsx
let counter = ref 0
printfn "Initial value: %d" !counter

counter := !counter + 1
printfn "After increment: %d" !counter

counter := !counter + 1
printfn "After second increment: %d" !counter

我们创建一个引用单元,然后修改和访问其内容。

let counter = ref 0

创建一个初始化值为 0 的引用单元。

!counter

! 运算符对引用单元进行解引用以访问其值。

counter := !counter + 1

:= 运算符更新引用单元的值。

λ dotnet fsi refcells.fsx
Initial value: 0
After increment: 1
After second increment: 2

F# 变量命名约定

F# 遵循某些变量命名约定。

naming.fsx
let camelCaseVariable = "camelCase"
let PascalCaseVariable = "PascalCase"
let snake_case_variable = "snake_case"
let ``variable with spaces`` = "works with backticks"

printfn "%s" camelCaseVariable
printfn "%s" PascalCaseVariable
printfn "%s" snake_case_variable
printfn "%s" ``variable with spaces``

该示例展示了 F# 支持的不同命名风格。

let ``variable with spaces`` = "works with backticks"

反引号允许在变量名中使用空格和其他特殊字符。

λ dotnet fsi naming.fsx
camelCase
PascalCase
snake_case
works with backticks

在本文中,我们已在 F# 中处理了变量。

作者

我的名字是 Jan Bodnar,我是一名热情的程序员,拥有丰富的编程经验。我自 2007 年以来一直在撰写编程文章。至今,我已撰写了 1400 多篇文章和 8 本电子书。我在编程教学方面有十多年的经验。