【问题标题】:Scala alternative cases match syntax with different type of extracted valueScala 替代案例将语法与不同类型的提取值匹配
【发布时间】:2011-10-29 16:17:54
【问题描述】:
object NoSense {
   def main(args: Array[String]) {
      val value = "true" match {
         case value @ (IntValue(_) | BooleanValue(_)) => value
      }
      require(value == true)
   }
}

class Value[T](val regex: Regex, convent: String => T) {
   def unapply(value: String): Option[T] = value match {
      case regex(value, _*) => Some(convent(value))
      case _ => None
   }
}
object IntValue extends Value[Int]("[0-9]+".r, _.toInt)
object BooleanValue extends Value[Boolean]("((true)|(false))".r, _.toBoolean)

main 方法中的require 将失败。
不过这个没问题

def main(args: Array[String]) {
      val value = "true" match {
         case IntValue(value) => value
         case BooleanValue(value) => value
      }
      require(value == true)
   }

这是scala语言本身的限制还是我做错了

【问题讨论】:

    标签: scala pattern-matching extractor


    【解决方案1】:

    这是……两者兼而有之。

    您可以查看Scala specification §8.1.3 中模式绑定器的行为方式。上面写着x@p

    变量x的类型是模式p的静态类型T。

    在您的情况下,模式 pIntValue(_) | BooleanValue(_)。由于IntValueBooleanValue unapply-methods 都需要一个字符串,所以你的模式的静态类型是String,因此x 的类型是String

    在第二种情况下,值从 BooleanValue 中提取并具有正确的类型。

    不幸的是,scala 不支持提取器模式的替代方案,因此您必须坚持使用第二个版本。

    【讨论】:

    • 对于我的用例,有没有更好的解决方案?我觉得我使用提取器的方式不对?
    • 没有你在这里使用提取器是正确的。但你的比赛并不详尽。此外,推断的值类型是 Any,它可能不合适,具体取决于上下文。
    猜你喜欢
    • 2019-03-09
    • 2021-01-27
    • 2020-10-04
    • 1970-01-01
    • 2014-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-22
    相关资源
    最近更新 更多