F#的下划线:为什么不创建一个变量名?

时间:2012-12-31 19:32:14

标签: f#

今天阅读F#,我不清楚一件事:

来自:http://msdn.microsoft.com/en-us/library/dd233200.aspx

  

您只需要元组中的一个元素,通配符(下划线)可用于避免为您不需要的变量创建新名称

     

let(a,_)=(1,2)

我想不出我曾经遇到过这种情况的时间。为什么要避免创建变量名?

4 个答案:

答案 0 :(得分:15)

因为您不需要该值。我常常使用它。它记录了一个值未使用的事实,并保存了命名变量unuseddummy等。如果你问我这个很棒的功能。

答案 1 :(得分:10)

let - 您给出的绑定是一个名为pattern matching的语言工具的示例,可用于解构许多类型,而不仅仅是元组。在模式匹配中,下划线是表达您不会引用某个值的惯用方式。

直接访问元组的元素可以更简洁,但它不那么通用。模式匹配允许您查看某些数据的结构并分发到适当的处理案例。

match x with
| (x, _, 20) -> x
| (_, y, _)  -> y

仅当第三个元素为x时,此模式匹配才会返回20中的第一个项目。否则返回第二个元素。一旦你超越了琐碎的案例,下划线就是一个重要的可读性辅助工具。将上述内容与以下内容进行比较:

match x with
| (x, y, 20) -> x
| (x, y, z)  -> y

在第一个代码示例中,更容易分辨出您在模式中关注哪些绑定。

答案 2 :(得分:9)

有趣的问题。这里涉及许多权衡因素。

您对Ruby编程语言进行了比较,因此您应该考虑的第一个权衡是静态类型。如果使用模式x, _, _,则F#知道您指的是三个元素的三元组中的第一个元素,并将在编译时强制执行此约束。 Ruby不能。 F#还检查模式的详尽性和冗余性。再一次,Ruby不能。

您的比较也只使用了平面图案。考虑模式_, (x, _)x, None | _, Some x[] | [_]等等。这些都不容易翻译。

最后,我提到标准ML是一种与F#相关的编程语言,它确实提供了名为#1等的运算符来提取具有任意数量元素的元组的第一个元素(参见{{ 3}})所以这个想法在几十年前实施并废弃了。我相信这是因为SML的#n符号在类型系统的约束内达到了难以理解的错误消息。例如,使用#n的函数不清楚元组的arity是什么,但是函数不能在元组arity上是通用的,所以这必须导致一个错误消息,说你必须提供更多的类型信息,但很多用户发现令人困惑。使用CAML / OCaml / F#方法没有这种混淆。

答案 3 :(得分:2)

有时候一个方法会返回多个值,但是你编写的代码只对少数几个(或一个)感兴趣。您可以使用多个下划线基本上忽略您不需要的值,而不是在本地范围内放置一堆变量。