Scala使用一个参数

时间:2017-09-03 08:26:04

标签: scala pattern-matching

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.我错过了什么或它的预期行为吗?

2 个答案:

答案 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