假设我有这段代码:
val parsedMessage: JsResult[Message] = Json.fromJson(Json.parse(msg))
val message: Message = parsedMessage.getOrElse {
log.warning("Invalid json: {}", msg)
RejectedMessageEvent(msg)
}
val newMessageEvent: NewMessageEvent = NewMessageEvent (userId, message.to, message.text)
messagePersistentActor ! message
显然,这在编译时失败,因为getOrElse
不返回类型为Message
的对象。但是,让我们说,出于某种原因,parsedMessage
失败了,我进入getOrElse
的'else'部分。在这里,我想要停止进程(在Java中它将是return
)或返回RejectedMessageEvent
- 这会产生预期的编译错误。
作为一名典型的Java开发人员,我热衷于使用:
if(parsedMessage.isError) {
log.warning("Invalid json: {}", msg)
messagePersistentActor ! RejectedMessageEvent(msg)
}
else {
val newMessageEvent: NewMessageEvent = NewMessageEvent (userId, message.to, message.text, UUID.randomUUID().toString, DateTime.now.getMillis)
messagePersistentActor ! message
}
但我觉得这不是Scala的最佳做法。
如果我想要在getOrElse
内停止进程,或者返回与该变量声明的对象类型不同的对象类型,您将如何解决这种情况?
我知道我可以在val message: Message = parsedMessage.getOrElse
省略消息类型声明并简单地val message = parsedMessage.getOrElse
,但是我将无法在message.to
和message.text
上执行此操作NewMessageEvent
案例类构造函数,因为message
可以是Message
或RejectedMessageEvent
的类型。
我正在使用案例类,我可以使用继承(RejectedMessageEvent
和NewMessageEvent
扩展Message
),但我正在尝试避免这种解决方案并寻求更多实用的。
答案 0 :(得分:2)
在scala中使用此模式if (someOptValue.isDefined) ... else ...
替换someOptValue.map(value => ...).getOrElse(...)
非常常见:
messagePersistentActor ! parsedMessage.map {msg =>
NewMessageEvent (userId, msg.to, msg.text)
}.getOrElse {
log.warning("Invalid json: {}", msg)
RejectedMessageEvent(msg)
}
答案 1 :(得分:2)
您可以改为使用asOpt
,并为您的邮件获取Option
值:
val parsedMessage: JsResult[Message] = Json.fromJson(Json.parse(msg))
val message: Option[Message] = parsedMessage.asOpt
message match {
case Some(m: Message) => messagePersistentActor ! m
case None => {
// Log and handle error
}
}