在阅读Scala文档时,我对一些函数签名感到困惑:
def corresponds[B](that: GenSeq[B])(p: (T, B) ⇒ Boolean): Boolean
那么,究竟是什么意思呢?
(p: (T, B) ⇒ Boolean)
答案 0 :(得分:3)
这意味着p
是一个函数,它接受T
和B
类型的两个参数并返回Boolean
。
答案 1 :(得分:2)
在(that: GenSeq[B])
中,that
是参数的名称,GenSeq[B]
是其类型。
在(p: (T, B) ⇒ Boolean)
中,p
是参数的名称,(T, B) ⇒ Boolean)
是其类型。
答案 2 :(得分:0)
这里有两件事情,这可能让你感到困惑。我将在下面分析这个声明:
def corresponds
[B] // Type parameter
(that: GenSeq[B]) // FIRST parameter list
(p: (T, B) ⇒ Boolean) // SECOND parameter list
: Boolean // return type
因此,可能会让您失望的第一件事是Scala接受多个参数列表。这样做有很多好处:
(1 to 10).foldLeft(0) { case (a, b) => a + b }
; 在下面的函数中,前两个原因很可能是使用两个参数列表的原因。假设你有类似的东西:
correponds(Gen.alphaStr)(_ != _)
类型B
将被推断为String
,因此后面的函数中的类型都将是已知的。不,如果它只是一个参数列表,就像这样:
corresponds(Gen.alphaStr, _ != _)
然后不会推断类型B
,因为它还取决于函数的类型。例如,这里:
corresponds(Gen.alphaStr, (a: T, b: Any) => a != b)
B
的类型为Any
而不是String
。现在,因为它无法在第一种情况下推断出类型,所以编译将失败。拆分两个参数列表会强制编译仅依赖于推理的第一个参数,这消除了歧义。
然后,还有语法糖,例如:
corresponds(Gen.alphaStr) {
case (x, "positive") => x > 0
case (x, "negative") => x < 0
case _ => x == 0
}
与此之间差别不大:
corresponds(Gen.alphaStr, {
case (x, "positive") => x > 0
case (x, "negative") => x < 0
case _ => x == 0
})
但是可读性是由像这样的小事做成的。
现在,第二个因素是函数类型的语法。 b: (T, B) => Boolean
表示名为b
的参数的类型为(T, B) => Boolean
,这意味着一个函数采用两个参数,第一个类型为T
,第二个类型为B
,并返回Boolean
类型的值。
请参阅上面的各种示例,了解作为参数传递的函数。