How to reference a variable when multiple cases ar

2019-08-09 04:49发布

问题:

Is there a way to give a reference name to a variable when multiple cases are combined using match in Scala?

Code:

Assume Gender enum has three possible values like male, female and other.

(nameOption, genderOption) match {
    case (Some(name), Some(Gender.Male)) | (Some(name), Some(Gender.FeMale))=> s"$name gender is either male or female"
    case (None, Some(Gender.Male)) | (None, Some(Gender.FeMale)) => //some print statement
    case (Some(name), Some(Gender.Other)) =>  //some print statement
    case _ => //some print statement
}

First case case (Some(name), Some(Gender.Male)) | (Some(name), Some(Gender.FeMale)) is complier error as name is already defined in scope.

If I don't combine cases in my actual code cyclomatic complexity increases.

回答1:

You can replace your first case to:

case (Some(name), Some(Gender.Male) |  Some(Gender.FeMale))=> s"$name gender is either male or female"

Update - even better - Thanks to @Astrid

case (Some(name), Some(Gender.Male | Gender.FeMale)) => s"$name gender is either male or female"


回答2:

you can try the following

(nameOption, genderOption) match {
    case (Some(name), Some(gender) if (gender == Gender.Male || gender == Gender.Female) => s"$name gender is either male or female"

}


回答3:

In addition to the answers already given, if you find yourself repeating the Gender.Male | Gender.FeMale match clause a lot in different parts of your code you might want to consider a custom extractor.

object BinaryGender {
  def unapply(gender: Gender.Gender) : Option[Gender.Gender] = {
    Some(gender).filter(_ != Gender.Other)
  }
}

(nameOption, genderOption) match {
  case (Some(name), Some(BinaryGender(_))) => s"$name gender is either male or female"
  case (None, Some(BinaryGender(_))) => //some print statement
  ...
}


标签: scala