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

jco*_*lum 12 f#

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

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

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

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

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

Dan*_*iel 15

因为你不需要这个值.我常常使用它.它记录的事实值未被使用,节省变量命名unused,dummy如果你问我,等大特点.

  • 当你的元组中有8个值时,你可能已经超出了应该考虑不同数据结构的程度. (11认同)
  • @jcollum - 如果通过索引访问第8个元素是有意义的,那么可能所有内容都是相同的数据类型,并且数组或列表优于元组.相反,如果我们有8个或更多不同数据类型的元素,通过索引访问它们只会令人困惑,因此在F#中最好使用记录,因此可以通过名称访问不同类型的值. (3认同)

Chr*_*ett 10

let你给出的绑定是一个称为模式匹配的语言工具的例子,它可以用来构造许多类型,而不仅仅是元组.在模式匹配中,下划线是表达您不会引用值的惯用方式.

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

match x with
| (x, _, 20) -> x
| (_, y, _)  -> y
Run Code Online (Sandbox Code Playgroud)

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

match x with
| (x, y, 20) -> x
| (x, y, z)  -> y
Run Code Online (Sandbox Code Playgroud)

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


Jon*_*rop 10

有趣的问题.这里涉及许多权衡.

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

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

最后,我提到标准ML是一种与F#相关的编程语言,它确实提供了运算符调用#1等来提取具有任意数量元素的元组的第一个元素(见这里)所以这个想法已经实现并且丢弃了几十年前.我相信这是因为SML的#n符号在类型系统的约束内达到了难以理解的错误消息.例如,使用的函数#n不清楚元组的arity是什么,但函数不能通过元组arity通用,因此这必须导致错误消息,表明您必须提供更多类型信息,但许多用户发现混淆.使用CAML/OCaml/F#方法,没有这种混淆.