如何在 for-yield 块中记录 None 错误
How to log None errors in a for-yield block
我的 Scala 代码结构类似于以下内容
for {
item1 <- findItem1
item2 <- item1.get("item2_info")
} yield {
val item3 = createItem3(item2)
if (logic_using_item3) {
do something here
}
}
我的理解是在这段代码中,如果 item1
或 item2
解析为 None
,那么整个执行链将停止并且不会执行 yield 块。你可以看到 item3
依赖于 item2
而不是 None,它本身依赖于 item1
而不是 None.
我想包括错误报告,但在保留 for-yield 块的同时我能想到的最好的是以下内容(注意:我对 Scala 和函数式编程相当陌生,但意识到以下内容不是“好斯卡拉”):
val x = for {
item1 <- findItem1
item2 <- item1.get("item2_info")
} yield {
val item3 = createItem3(item2)
if (logic_using_item3) {
do something here
}
}
if (x == None) {
logger.error("Something went wrong")
}
什么是正确的“Scala 方式”以在此代码中包含错误日志记录以反映出错的地方,例如 "Item1 was not found"
或 "Item2 was empty"
。您可以在 for-yield 块中执行此操作,还是添加错误日志记录需要重构代码以不使用 for-yield 块?
恕我直言,最好的方法是使用 Either 而不是 Option 来保留错误消息。
val result = for {
item1 <- findItem1.toRight(left = "Item1 was not found")
item2 <- item1.get("item2_info").toRight(left = "Item2 was not empty")
item3 = createItem3(item2)
if (logic_using_item3)
} yield foo
result match {
case Right(data) => ???
case Left(error) => logger.error(error)
}
我的 Scala 代码结构类似于以下内容
for {
item1 <- findItem1
item2 <- item1.get("item2_info")
} yield {
val item3 = createItem3(item2)
if (logic_using_item3) {
do something here
}
}
我的理解是在这段代码中,如果 item1
或 item2
解析为 None
,那么整个执行链将停止并且不会执行 yield 块。你可以看到 item3
依赖于 item2
而不是 None,它本身依赖于 item1
而不是 None.
我想包括错误报告,但在保留 for-yield 块的同时我能想到的最好的是以下内容(注意:我对 Scala 和函数式编程相当陌生,但意识到以下内容不是“好斯卡拉”):
val x = for {
item1 <- findItem1
item2 <- item1.get("item2_info")
} yield {
val item3 = createItem3(item2)
if (logic_using_item3) {
do something here
}
}
if (x == None) {
logger.error("Something went wrong")
}
什么是正确的“Scala 方式”以在此代码中包含错误日志记录以反映出错的地方,例如 "Item1 was not found"
或 "Item2 was empty"
。您可以在 for-yield 块中执行此操作,还是添加错误日志记录需要重构代码以不使用 for-yield 块?
恕我直言,最好的方法是使用 Either 而不是 Option 来保留错误消息。
val result = for {
item1 <- findItem1.toRight(left = "Item1 was not found")
item2 <- item1.get("item2_info").toRight(left = "Item2 was not empty")
item3 = createItem3(item2)
if (logic_using_item3)
} yield foo
result match {
case Right(data) => ???
case Left(error) => logger.error(error)
}