如果您坚持使用提取器,可以使用
from this answer 的想法。
object && {
def unapply[A](a: A): Option[(A, A)] = Some((a, a))
}
并且为每个成员变量定义一个单独的提取器:
case class Abc(a: Int, b: Int, c: Int)
object Abc {
object A { def unapply(x: Abc): Option[Int] = Some(x.a) }
object B { def unapply(x: Abc): Option[Int] = Some(x.b) }
object C { def unapply(x: Abc): Option[Int] = Some(x.c) }
}
现在你可以像这样在模式匹配中使用它:
val z = Abc(42, 100, 58)
import Abc._
val A(a) && B(b) = z
println(s"a = $a , b = $b")
这个例子的输出为:
a = 42 , b = 100
请注意,它可以与任意数量的提取器连接在一起使用,例如:
&&
。
case class Abc(a1: Int, a2: Int, a3: Int, a4: Int, a5: Int, a6: Int, a7: Int, a8: Int)
object Abc {
object A1 { def unapply(x: Abc): Option[Int] = Some(x.a1) }
object A2 { def unapply(x: Abc): Option[Int] = Some(x.a2) }
object A3 { def unapply(x: Abc): Option[Int] = Some(x.a3) }
object A4 { def unapply(x: Abc): Option[Int] = Some(x.a4) }
object A5 { def unapply(x: Abc): Option[Int] = Some(x.a5) }
object A6 { def unapply(x: Abc): Option[Int] = Some(x.a6) }
object A7 { def unapply(x: Abc): Option[Int] = Some(x.a7) }
object A8 { def unapply(x: Abc): Option[Int] = Some(x.a8) }
}
object && {
def unapply[A](a: A): Option[(A, A)] = Some((a, a))
}
val z = Abc(1, 2, 3, 4, 5, 6, 7, 8)
import Abc._
val A3(a3) && A5(a5) && A7(a7) = z
println(s"$a3 $a5 $a7")
输出
3 5 7
如预期的那样。如果您经常需要使用这样笨重的对象,建议考虑为样板代码生成代码。
unapply
方法在许多地方都被使用,比如match
case
模式,但这并不能回答我的问题,即如何根据属性名称而不是位置从一个case类中提取属性。 - andykais