我是否正确理解了流量?考虑以下代码
class Employee(val firstName: String, val middleName: Option[String], val lastName: String)
object Tokenizer {
def unapply(x: Employee) = Some(x.firstName, x.lastName)
}
val e = new Employee("Kurt", None, "Vonnegut")
val result = e match {
case Tokenizer(c, d) ⇒ "c: %s, d: %s".format(c, d)
case _ ⇒ "Not found"
}
我是否更正e
将Tokenizer.unapply(x:Employee)
传递给Some()
并将(c,d)
的结果分配给Tokenizer(c,d)
?从代码的外观来看,似乎我们正在调用apply
,但没有unapply
或Tokenizer(c,d)
方法定义为http://12.0.0.1:8000/whatever
的签名simialar
答案 0 :(得分:1)
是的,您已正确理解。 unapply
可能有点弯曲,因为当您在case
中看到它时,您会编写返回类型而不是参数类型。 Tokenizer.unapply
的签名是Employee => Some[(String, String)]
。与case Tokenizer(c, d)
对应的部分是返回类型。
然而,我有几个(非常小的)尼特选择。您应该为所有公共方法提供类型,因为您最终可能会推断出太具体的类型(通过推断Some
而不是Option
来显示),然后更改您的代码(在这种情况下,也许这样做Tokenizer.unapply
可能会失败并None
}更改其界面。但是,如果您希望赢得 更改Tokenizer
以便能够失败,则无需通过返回{{1}来承受拳击惩罚}。你可以改为
Option
最后一点:调用一个没有双重parens的元组的函数是不好的。别写// Don't worry if you don't understand this yet. You can ignore this trick and come back to it much later
// Also: I think this only works on Scala 2.12
final case class Box[+T](t: T) extends AnyVal {
def isEmpty = false
def get = t
}
object Tokenizer {
def unapply(e: Employee): Box[(String, String)] = Box((e.firstName, e.lastName))
}
// Incurs no boxing penalty, but now you can't change it to allow failure without changing the interface
;写Some(a, b)
。这有点难看,但第一个可能含糊不清,而且情况更糟。
答案 1 :(得分:0)
An object with an unapply
method is an extractor object. It does the inverse of the apply
method by extracting the individual values that were passed to apply
. So in the above example result
will contain the tuple ("Kurt", "Vonnegut")
.
Note that you could also use an assignment instead of pattern matching here:
$ val Tokenizer(emp) = e
emp: (String, String) = ("Kurt", "Vonnegut")