我自学Scala(来自多年的Java),我遇到了以下代码,我无法完全理解:
case class Email(subject: String, text: String, sender: String, recipient: String)
type EmailFilter = Email => Boolean
def newMailsForUser(mails: Seq[Email], f: EmailFilter) = mails.filter(f)
val sentByOneOf: Set[String] => EmailFilter =
senders => email => senders.contains(email.sender)
val notSentByAnyOf: Set[String] => EmailFilter =
senders => email => !senders.contains(email.sender)
val minimumSize: Int => EmailFilter = n => email => email.text.size >= n
val maximumSize: Int => EmailFilter = n => email => email.text.size <= n
我觉得难以理解的部分是缺少类型定义的val:
val sentByOneOf: Set[String] => EmailFilter =
senders => email => senders.contains(email.sender)
我使用def
创建了相同的函数,我可以理解:
def sentByOne(senders: Set[String], email: Email): (Set[String] => EmailFilter) = {
senders => email => senders.contains(email.sender)
}
该版本的类型来自哪里?另外,后一版本更受欢迎吗?
答案 0 :(得分:4)
简短的回答,在这个定义中:
val sentByOneOf: Set[String] => EmailFilter =
senders => email => senders.contains(email.sender)
扩展为:
val sentByOneOf: Set[String] => Email => Boolean =
senders => email => senders.contains(email.sender)
类型在:
后定义为Set[String] => EmailFilter
。因此传递给sentByOneOf
的第一个值是Set[String]
,第二个值是EmailFilter
类型,它是Email => Boolean
的别名。
更长的版本:
作为Scala中的所有变量/值,可以在冒号后指定类型,就像在此示例中一样,或者可以从它所引用的表达式中输入。所以在这里:
val sentByOneOf = (senders: Set[String]) => (email: Email) =>
senders.contains(email.sender)
sentByOneOf
的{{1}}类型也会被sentByOneOf: Set[String] => (Email => Boolean)
所感染,其中Email => Boolean
的别名定义为EmailFilter
在scala function values
中,这实际上就是你所拥有的,实际上是FunctioN
类的实例,其中N是变量的数量。所以你的函数sentByOneOf
实际上是这样的:
val sentByOneOf = new Function2[Set[String], Email, Boolean] {
def apply(senders: Set[String], email: Email, pred: => Boolean): Boolean = senders.contains(email.sender)
}
顺便说一句,你选择了很多系列的文章,但是第一次使用Scala却很困难:)