gpt4 book ai didi

scala - 在条件成立时在 Scala 中链接多个函数

转载 作者:行者123 更新时间:2023-12-05 00:10:51 25 4
gpt4 key购买 nike

假设我们有 3 个方法,它们都返回 Option

import scala.util.Try

def divideSafe(d: Int): Option[Int] = Try(42 / d).toOption
def sqrtSafe(x: Double): Option[Double] = if(!math.sqrt(x).isNaN) Some(math.sqrt(x)) else None
def convertSafe(s: String): Option[Int] = Try(s.toInt).toOption

现在我想在条件成立时将它们链接起来。就我而言,如果定义了前一个方法的结果,则应该转到下一个方法。并且只要条件为假,则停止操作并返回一个默认值。

我可以使用嵌套的 if-else 语句获得所需的结果:

def superSafe(d: Int, x: Double, s: String): Unit = {
if (divideSafe(d).isDefined) {
println(divideSafe(d).get.toString)
if (sqrtSafe(x).isDefined) {
println(sqrtSafe(x).toString)
if (convertSafe(s).isDefined) {
println(convertSafe(s).get.toString)
} else {
println("Converting failed")
}
} else {
println("Sqrt failed")
}
} else {
println("Dividing failed")
}
}

所以:
superSafe(1, -1, "5")将打印 42 并且 Sqrt 失败 superSafe(0, 4, "cat")会打印分频失败 superSafe(42, 4, 1)会打印 1,2,1

但是,我想避免嵌套的 if-else 语句,并且我很感兴趣 Scala 中是否有一种函数式方法来解决此类问题。

我想要类似 orElse 的东西声明,但反过来。

可以像这样使用所需的功能:

divideSafe(42) ifThen("Dividing failed") sqrtSafe(-4) ifThen("Sqrt failed") convertSafe("cat") ifThen("Converting failed")

最佳答案

您正在使用 Option这不是最适合您的用例。我相信 Either在你的例子中会更好,因为它可以保存关于失败( Left )或关于成功( Right )的信息。如果您重写函数以使用 Either它可能看起来像:

def divideSafe(d: Int): Either[String, Int] = Try(42 / d).toOption.toRight("Divide failed")
def sqrtSafe(x: Double): Either[String, Double] = math.sqrt(x) match {
case s if s.isNaN => Left("Sqrt failed") //you can use pattern matching to calculate square just once
case s => Right(s)
}
def convertSafe(s: String): Either[String, Int] = Try(s.toInt).toOption.toRight("Converting failed")

然后你可以使用 for comprehension在您的 superSafe方法:
def superSafe(d: Int, x: Double, s: String): Unit = {
val r: Either[String, (Int, Double, Int)] = for { //for-comprehension shortcircuits
r1 <- divideSafe(d) //if divideSafe fails it whole comprehension will return Left(Divide failed)
r2 <- sqrtSafe(x) //if it succeds it will go further
r3 <- convertSafe(s)
} yield (r1,r2,r3)

r match {
case Right((r1,r2,r3)) => { //you could move it inside yield, I splitted it for clarity
println(r1)
println(r2)
println(r3)
}
case Left(e) => println(e)
}
}

关于scala - 在条件成立时在 Scala 中链接多个函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56093178/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com