与参数匹配的 F# 模式

标签 f# pattern-matching

这可能很简单,但有人可以解释为什么以下模式匹配不明智吗?它说其他规则,例如1, 0, _ 永远不会匹配。

let matchTest(n : int) = 
    let ran = new Random()
    let i = ran.Next(0, 2)
    match i with
    | n -> printfn "%i" n
    | 1 -> printfn "1"
    | 0 -> printfn "0"
    | _ -> printfn "impossible"

同样的事情:
let matchTest(n : int) = 
    let ran = new Random()
    let i = ran.Next(0, 2)
    let m = n
    match i with
    | m -> printfn "%i" m
    | 1 -> printfn "1"
    | 0 -> printfn "0"
    | _ -> printfn "impossible"

那为什么不能匹配nm直接在这里?

最佳答案

n在第一个示例中是一个占位符符号,如果匹配成功,则会填充该符号。和写法一样:

let matchTest(n : int) = 
    let ran = new Random()
    let i = ran.Next(0, 2)
    match i with
    | x -> printfn "%i" x
    | 1 -> printfn "1"
    | 0 -> printfn "0"
    | _ -> printfn "impossible"

符号 xi 的值填充如果匹配成功,则可以在 -> 的右侧使用.这个匹配总是成功的,这就解释了为什么其余的匹配案例是不可达的。

在您的情况下,恰好您将匹配变量命名为 n ,与输入参数同名。

但是,这不是相同的值。相反,会发生一个新值,也称为 n正在创建,之前的 n不再可访问。

这是一个名为 的语言功能。阴影 .

您还可以在模式匹配之外看到它:
let foo n =
    let n = 1
    n

示例用法:
> foo 42;;
val it : int = 1
> foo 1337;;
val it : int = 1

如您所见,let-bound n遮蔽输入参数 n .

OP 中的第二个示例,在 n 上匹配是第一个的变体,所以同样的解释也适用。

关于与参数匹配的 F# 模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34876655/

相关文章:

c# - F# 指针成员访问器

f# - 如何在没有 "let rec"的情况下定义 y-combinator ?

c++ - std::search 使用什么算法?

regex - 有没有办法有效地索引包含正则表达式模式的文本列?

r - F#:程序集引用 RDotNet.dll 未找到或无效

f# - 是否可以将 F# 代码转换为 C# 代码?

syntax - F# 构造函数语法 - 覆盖和扩充 new

java - 无法将 [ 替换为 {

python - 使用正则表达式匹配单词 (Python 3)

regex - 高级 Lua 模式匹配