2016-01-07 3 views
1

У меня есть опция строки с именем failType. Согласно значениям этой Строки, я должен решить, какой тип объекта я хочу создать. Что-то вроде -Scala pattern matching option string

val failure: Option[FailureType] = failureType map (f => f.toLowerCase match { 
      case "build" => FailureType.BuildFailure 
      case "test" => FailureType.TestFailure 
      case "service timeout" => FailureType.ServiceTimeout 
      case "job timeout" => FailureType.JobTimeout 
      case "work item timeout" => FailureType.WorkItemTimeout 
     }) 

Моя проблема в том я получаю Match Ошибка, если я дам, кроме «строить», «тест», «тайм-аут службы», «задания тайм-аут» или «рабочего элемента тайм-аут» для failureType значения. Это имеет смысл, потому что я не делаю никаких попыток по умолчанию. Итак, моя проблема заключается в том, как сделать это по умолчанию? Если я

case _ => None 

В конце других заявлений случае, я хотел бы получить сообщение об ошибке, потому что я, конечно, внутри карты. Мой другой вариант, как представляется, не используя карту на всех и сразу делает матч -

val failure: Option[FailureType] = failureType match { 
      case Some("build") => FailureType.BuildFailure 
      case Some("test") => FailureType.TestFailure 
      case Some("service timeout") => FailureType.ServiceTimeout 
      case Some("job timeout") => FailureType.JobTimeout 
      case Some("work item timeout") => FailureType.WorkItemTimeout 
      case _ => None 
     } 

Но в этом случае я теряю способность делать без учета регистра соответствия.

+1

Либо вы можете '.filter'' Option', чтобы предотвратить неподдерживаемое значение перед сопоставлением, или '.flatMap [FailureType]' с 'case _ => None', или вы преобразовываете в другой тип, который может представлять собой проверку с предопределенным сбоем или неожиданным (возможно, 'Либо [Option [String], SuccessType]' в вашем случае). – cchantep

+1

В принципе, собирайте функцию, как и другие. Но почему бы не создать общий код ошибки? Вы уверены, что все в порядке, чтобы пропустить ошибки? Вы можете оказаться в неудачной системе, и вы даже не узнаете об этом. – mavarazy

ответ

2

Что вы ищете .collect:

val failure = failureType.map(_.toLowerCase).collect { 
    case "build" => FailureType.BuildFailure 
    case "test" => FailureType.TestFailure 
    case "service timeout" => FailureType.ServiceTimeout 
    case "job timeout" => FailureType.JobTimeout 
    case "work item timeout" => FailureType.WorkItemTimeout 
} 

.collect занимает PartialFunction и вернет результат его применения, если функция определена в аргументе или None в противном случае.

2

Я хотел бы использовать flatMap - есть падение, через случай возврата None, в то время как действительные случаи возврата Some(_relevant_failure_type):

val failure: Option[FailureType] = failureType flatMap (f => f.toLowerCase match { 
     case "build" => Some(FailureType.BuildFailure) 
     case "test" => Some(FailureType.TestFailure) 
     case "service timeout" => Some(FailureType.ServiceTimeout) 
     case "job timeout" => Some(FailureType.JobTimeout) 
     case "work item timeout" => Some(FailureType.WorkItemTimeout) 
     case _ => None 
    }) 
2

Часть трудности связана с попыткой складывания и совпадения в одно и то же время. Если вы используете map (_.toLowerCase) сложить случай первый, вы можете использовать collect делать именно то, что вы хотите:

val failure: Option[FailureType] = failureType map (_.toLowerCase) collect { 
    case "build" => FailureType.BuildFailure 
    case "test" => FailureType.TestFailure 
    case "service timeout" => FailureType.ServiceTimeout 
    case "job timeout" => FailureType.JobTimeout 
    case "work item timeout" => FailureType.WorkItemTimeout 
} 

Результат будет None для любой строки явно не совпало.