Ber*_*dei 3 f# design-patterns symbols matching
我是F#的新手并且正在摆弄它.得到的是我:
let rec fact n =
match n with
| dummy when n < 2 -> 1
| _ -> n * fact (n - 1)
let x = 6
printfn "%d! = %d" x (fact x)
Run Code Online (Sandbox Code Playgroud)
为什么F#需要在管道之间和何时使用这个虚拟占位符?Dummy甚至整个时间都是未定义的,编译器似乎在某种程度上需要并同时忽略它,就像需要的鬼符号一样.
提前致谢.
kvb*_*kvb 10
符号不必是虚拟符号,可以出现在when子句中.例如,您的函数可以重写:
let rec fact = function
| n when n < 2 -> 1
| n -> n * fact (n - 1)
Run Code Online (Sandbox Code Playgroud)
在这里,因为我们使用的是匿名模式匹配function而不是match ... with,所以标识符实际上很重要.
通常你会使用更复杂的模式,比如
match p with
| i,j when i < j -> true
| _ -> false
Run Code Online (Sandbox Code Playgroud)
因为即使存在when子句,匹配的模式几乎总是很重要,所以没有一种允许when没有任何模式的子句的特殊形式.
当然,如果你真的希望它是一个虚拟的,你可以使用这个模式,_这样你就不需要提出一个新的标识符名称:
let rec fact n =
match n with
| _ when n < 2 -> 1
| _ -> n * fact (n - 1)
Run Code Online (Sandbox Code Playgroud)
正如其他人已经解释的那样,dummy您的示例中的值可以替换为忽略模式(写为_)以使代码更简洁.match当您需要分解某个值时,该构造是最强大的,在这种情况下,您需要能够在模式匹配中定义新符号.
但是,在您的示例中,您并没有真正分解该值,因此我更喜欢简单的if ... then表达式而不是更复杂的match:
let rec fact n =
if n < 2 then 1
else n * fact (n - 1)
Run Code Online (Sandbox Code Playgroud)
我认为这是一种更易读的原始函数编写方式(与其他版本一样功能 - match在处理比整数更复杂的类型时更合适).