Scala命名提取器示例:
class Foo1(n: Int) {
def isEmpty: Boolean =
false
def get: Foo1 =
this
def _1: Int = n
}
object Foo1 {
def unapply(arg: Foo1) = arg
}
class Foo2(n: Int, nn: Int) {
def isEmpty: Boolean =
false
def get: Foo2 =
this
def _1: Int = n
def _2: Int = nn
}
object Foo2 {
def unapply(arg: Foo2) = arg
}
object Main extends App {
new Foo1(1) match {
case Foo1(n) if n > 0 ⇒ println(n)
}
//Error: value > is not a member of Foo1
//case Foo1(n) if n > 0 ⇒ println(n)
new Foo2(1, 2) match {
case Foo2(n, nn) if n > 0 ⇒ println(s"$n -> $nn")
}
// 1 -> 2
}
我很好奇为什么Scala为一个参数(Foo1)提取类实例,但是如果它们的数字>提取参数(Foo2(n,nn))。 1.我错过了什么或它的预期行为吗?
答案 0 :(得分:0)
我认为,引入基于命名的提取器的主要原因是可以使用值类(扩展AnyVal)来提取单个值而不是.canvaschesspgn > * {
text-align: left;
。这样,您可以避免额外def unapply(arg: Foo1): Options[Foo1]
的实例化,从而避免垃圾回收。通常,这用于提取符合特定标准的值。
示例:
Option
看来,元组getter(class PositiveNonZeroInteger(private val n: Int) extends AnyVal {
def isEmpty: Boolean = n <= 0
def get: Int = n
}
object PositiveNonZeroInteger {
def unapply(arg: Int) = new PositiveNonZeroInteger(arg)
}
1 match {
case PositiveNonZeroInteger(pos) => "yay"
case _ => "nay"
} // => "yay"
0 match {
case PositiveNonZeroInteger(pos) => "yay"
case _ => "nay"
} // => "nay"
)可能只有编译器解析,如果它们中至少有两个存在。
因此,如果您将第一个foo重写为:
_1, _2
您的代码可以使用,但这不是基于名称的提取器的用途。
希望这有帮助。
答案 1 :(得分:0)
Scala语言规范将提取器模式中的0,1或多个参数区分开来:
http://scala-lang.org/files/archive/spec/2.12/08-pattern-matching.html#extractor-patterns
对于1个参数,它需要匹配类型的Option,即Option[Int]
的{{1}}和多个参数的元组的Foo1
。
在您的示例中,如果您想从Option
方法返回实例本身,则可以通过实施
unapply
预期Option[Int]
。
Foo1