了解斯卡拉的下划线和星号魔法
我正在阅读和练习斯卡拉,我发现这个blog。了解斯卡拉的下划线和星号魔法
阅读有关创作谓词我看到这段代码的一部分
def complement[A](predicate: A => Boolean) = (a: A) => !predicate(a)
def any[A](predicates: (A => Boolean)*): A => Boolean =
a => predicates.exists(pred => pred(a))
def none[A](predicates: (A => Boolean)*) = complement(any(predicates: _*))
def every[A](predicates: (A => Boolean)*) = none(predicates.view.map(complement(_)): _*)
我有一个Python的背景和想了解下划线和星号的含义单独或一起使用时,这是相当奇怪的是有意义的,特别对于无和每的定义。
SomeExpression*
意味着
_
可以用“0个或多个元素的序列”指定
到none
的参数是“谓词的序列“我们并不需要命名的参数”包含0个或更多元素“,而”谓词“是一个函数,它需要A
并返回Boolean
。
到any
的参数是一个数组,所以传入的值必须被转换成一个阵列,其由_*
参数做every
是一个数组,其名称并不重要,因为只有一。它可以传递给complement
为_
def any[A](predicates: (A => Boolean)*)
产生相同的功能
def any[A](predicates: Seq[A => Boolean])
除了你可以这样调用它any(a, b, c)
代替any(List(a, b, c))
(编译变换调用点)。
鉴于any
是可变参数函数,调用any(a)
进入any
的主体与predicates = List(a)
。但如果a
已经是一个序列,这不是你想要的。这就是: _*
表示法:它告诉Scala编译器“将它视为可变参数的一系列参数”。
这大致相当于在Python编写,
def complement(predicate):
return lambda a: not predicate(a)
def any_(*predicates):
return lambda a: any(pred(a) for pred in predicates)
def none(*predicates):
return complement(any_(*predicates))
def every(*predicates):
return none(*map(complement, predicates))
'Seq',而不是'Array'。 –
@AlexeyRomanov对,我的错误。 Array可以通过'@ varargs'注释来实现Java的可比性,但是它对于普通的Scala代码来说是'Seq'。 – ephemient
** **每个**的定义在同一行中使用'_'和'_ *'是什么意思? ** complement **只接受一个谓词,但在这种情况下不是'_'是一个Seq,这就是为什么后面可以使用'_ *'?最后一行是最难理解的。 –
'_'一般是指“东西的名字我不关心”。你可能想要探索这个答案的所有可能的含义:http://*.com/a/8001065/3314107 – stefanobaghino