如果我将案例类定义如下
case class Calculator(brand: String, model: String)
它的伴随对象的unapply方法看起来如何?需要什么类型的论据?
我无法通过定义一个类来模拟它,然后我自己就是它的伴随对象。
class abc (age:Int, name:String) {
}
object abc {
def apply(age:Int, name:String) = new abc(age, name)
def unapply(obj:abc) = Some("test")
}
abc(1, "aaaa")
res6: abc = abc@269f4bad
res6 match {
| case abc(1, "aaaa") => println("found")
| }
error: too many patterns for object abc offering String: expected 1, found 2
case abc(1, "aaaa") => println("found")
^
<console>:14: error: type mismatch;
found : Int(1)
required: String
case abc(1, "aaaa") => println("found")
答案 0 :(得分:3)
您需要让班级的age
和name
成员在构建后可以访问它们(可以通过制作val
s)来完成,然后使用它们在unapply
:
class abc (val age:Int, val name:String)
object abc {
def apply(age:Int, name:String) = new abc(age, name)
def unapply(candidate: abc) = Some((candidate.age, candidate.name))
}
哪个会正确匹配:
scala> new abc(2, "bbbb") match {
| case abc(1, "aaaa") => println("found 1")
| case abc(2, "bbbb") => println("found 2")
| case _ => println("not found")
| }
found 2
答案 1 :(得分:2)
如果您要创建一个具有unapply
方法的自定义类,并希望将Extractor Pattern与the following rules should apply一起使用,{{3}}:
unapply
的返回类型应按如下方式选择:
- 如果只是测试,请返回
Boolean
。例如case even()
- 如果它返回
T
类型的单个子值,则返回Option[T]
- 如果要返回多个子值
T1,...,Tn,
,请将它们分组为可选项 元组Option[(T1,...,Tn)]
。
通常,这意味着对于您而言,需要使用unapply
方法完成的所有操作都是第三个选项,它返回一个值元组。接下来,与自动为您创建不可变字段的案例类不同,您需要将val
注释添加到类声明中。
class abc (val age: Int, val name: String)
和
def unapply(obj: abc): Option[(Int, String)] = Some((obj.age, obj.name))
答案 2 :(得分:2)
Tzach打败了我..
你的错误信息btw。是因为你的unapply返回的选项(包含一个字符串)和你的case语句中的匹配(想要匹配一对)之间的不匹配。
您可以包含一个空检查以确保(编译器对于案例类伴随对象):
class Abc(val age: Int, val name: String)
object Abc {
def unapply(obj: Abc): Option[(Int, String)] =
if (obj == null)
None
else
Some((obj.age, obj.name))
}
无耻的自我推销:如果您对模式匹配的更多细节感兴趣,您可能会发现我的小文章"Everything you always wanted to know about pattern matching"很有用。