今天阅读F#,我不清楚一件事:
来自:http://msdn.microsoft.com/en-us/library/dd233200.aspx
您只需要元组中的一个元素,通配符(下划线)可用于避免为您不需要的变量创建新名称
let(a,_)=(1,2)
我想不出我曾经遇到过这种情况的时间。为什么要避免创建变量名?
答案 0 :(得分:15)
因为您不需要该值。我常常使用它。它记录了一个值未使用的事实,并保存了命名变量unused
,dummy
等。如果你问我这个很棒的功能。
答案 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)
有时候一个方法会返回多个值,但是你编写的代码只对少数几个(或一个)感兴趣。您可以使用多个下划线基本上忽略您不需要的值,而不是在本地范围内放置一堆变量。