模式匹配给出返回类型为Any

时间:2017-09-06 13:48:37

标签: scala

我正在尝试对常量进行模式匹配。  我的返回类型c3Any,但我希望它返回Option

如果我不使用isDefined,可能会在None

上抛出错误
 object Currency {

    sealed trait Currency {def name: String}

    case object EUR extends Currency {val name = "EUR"}

    //etc.
    case object INR extends Currency {val name = "INR"}

    //etc.

    val list = Seq(EUR, INR)

    def currency(name: String): Option[Currency] = list.find(_.name == name)
  }

  val c1=Currency.currency("INR")
  val c3=if(c1.isDefined)c1.get match {
    case Currency.INR => Currency.EUR
    case Currency.EUR=> Currency.INR
  }

1 个答案:

答案 0 :(得分:1)

如果要返回选项

,则在if语句中缺少else案例
val c3=if(c1.isDefined){
      c1.get match {
        case Currency.INR => Some(Currency.EUR)
        case Currency.EUR=> Some(Currency.INR)
    }
  else None

然而,这是对Option的不良使用。检查存在,提取值然后将其打包回来是你永远不应该做的事情。在这种情况下,您想要的是map

val c3 = c1.map{
    case Currency.INR => Currency.EUR
    case Currency.EUR => Currency.INR 
    }

将根据您的映射返回包含更新值的Option[Currency],如果选项为none,则返回None

请注意,如果内容是未包含在匹配大小写中的货币,则会引发匹配异常。在这种情况下,它不是一个问题,因为你使用密封特性使其成为一个详尽的匹配。

如果需要,您可以包含一个默认案例来涵盖该场景,

val c3 = c1.map{
    case Currency.INR => Currency.EUR
    case Currency.EUR => Currency.INR
    case _ => Currency.INR //catch-all.  Anything not covered in previous
                             cases will default to Currency.INR
    }

以上回报Some(Currency.EUR)是c1是Some(Currency.INR)Some(Currency.INR)是C1包含任何其他SomeNone是C1是None

或使用collect代替map,以便在没有案例匹配时返回None

val c3 = c1.collect{
    case Currency.INR => Currency.EUR
    case Currency.EUR => Currency.INR
    }

如果c1不是NoneSome(Currency.INR)

,则上述内容会返回Some(Currency.EUR)