gpt4 book ai didi

Scala 隐式返回和 if-then-else 语句

转载 作者:行者123 更新时间:2023-12-04 19:51:53 24 4
gpt4 key购买 nike

我的一个问题是 - 如果我们依赖隐式返回,它很容易出错

例如。

def foo(bar: Int): Int =
{
if (f1(bar)) 0
if (f2(bar)) 1
else -1
}

有时我们只是忘记了 else 语句,为了解决这个问题,强制使用大括号,例如 .e.g

def foo(bar: Int): Int =
{
if (f1(bar)) {
0
} else if (f2(bar)) {
1
} else {
-1
}
}

但是新样式太冗长恕我直言,有什么办法可以解决吗?

最佳答案

实际上,我从来没有遇到过这个问题,而且我犯了很多愚蠢的错误。我怀疑您完全有能力学会不跳过 else 语句。 (请注意,大括号没有任何帮助;您仍然可以跳过中间的 else。)

如果您真的、真的发现这是一个问题,您可以滥用 match 语句:

true match {
case _ if f1(bar) => 0
case _ if f2(bar) => 1
case _ => -1
}

这将防止您犯任何错误。或者你可以自己编写一个实用方法:

trait Conditional[+A] {
def apply[B >: A](p: => Boolean, b: => B): Conditional[B]
def or[B >: A](default: => B): B
}
class FoundIt[+A](it: A) extends Conditional[A] {
def apply[B >: A](p: => Boolean, b: => B) = this
def or[B >: A](default: => B) = it
}
class NothingYet[+A] extends Conditional[A] {
def apply[B >: A](p: => Boolean, b: => B) = {
if (p) new FoundIt(b) else this
}
def or[B >: A](default: => B) = default
}
def ifelse[A](p: => Boolean, a: => A) = (new NothingYet[A]).apply(p,a)

ifelse( f1(bar), 0 )( f2(bar), 1 ) or -1

这对于长表达式来说有点困惑,所以您也可以(如果您希望它在那里工作,请使用 :paste 将其粘贴在一个大块中的 REPL 中):

trait Predicate[+A] {
def Or(p: => Boolean): Loadable[A]
def Else[B >: A](default: => B): B
}
trait Loadable[+A] {
def Then[B >: A](b: => B): Predicate[B]
}
object NotYetTrue extends Predicate[Nothing] {
def Or(p: => Boolean) = if (p) ActuallyLoad else SkipLoading
def Else[B >: Nothing](default: => B) = default
}
object SkipLoading extends Loadable[Nothing] {
def Then[B >: Nothing](b: => B) = NotYetTrue
}
object ActuallyLoad extends Loadable[Nothing] {
def Then[B >: Nothing](b: => B) = new Loaded[B](b)
}
class Loaded[+A](a: A) extends Predicate[A] with Loadable[A] {
def Or(p: => Boolean) = this
def Else[B >: A](default: => B) = a
def Then[B >: A](b: => B) = this
}
def If(p: => Boolean): Loadable[Nothing] = NotYetTrue.Or(p)

现在唯一的技巧是你必须在 REPL 中使用 :paste 来编写多行语句,并将继续放在上一行的末尾:

If (f1(bar)) Then 0 Or
(f2(bar)) Then 1 Else
-1

您也可以在一行中使用 Then { 0 并在下一行使用 } Or 重新开始,或者用圆括号/大括号和点(这是REPL 友好):

If (f1(bar)) .Then (0) .
Or (f2(bar)) .Then (1) .
Else (-1)

无论如何,所有这些技巧很好地说明了如何使用 Scala 构建复杂的 DSL,但并不是真正解决问题的最佳方法。您应该学会更加小心地处理 if/else 语句;否则,人们会对您为什么不按照标准方式做事感到困惑。 (如果它对性能至关重要,它可能会很慢——match 非常好,但是 If 魔法在高性能循环中并不好。)

关于Scala 隐式返回和 if-then-else 语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12541072/

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