在 Scala 中编写此条件语句的最佳方法
Best way to write this conditional statements in scala
我有两个相同类型的对象,但我想使用这些对象调用方法,但取决于几个布尔值。
def myMethod(a: Boolean, b: Boolean, obj1: MyClass, obj2: MyClass): Future[Done] = {
if(a) obj1.methodWhichReturnsFuture()
if(b) obj2.methodWhichReturnsFuture()
}
这里方法#methodWhichReturnsFuture 有return typr Future[Done]。这显示错误,因为我在这里 returning Unit。我虽然创建了一个 'var' 并在两个方法调用中分配它,但看起来这不是一个好方法。这绝对是基本的,但我想知道实现它的更好方法是什么?谢谢
在 Scala 中,没有 else
的 if
只能针对 side-effect 执行,因此
的结果值
if (a) obj1.methodWhichReturnsFuture()
将被丢弃,结果是 Unit
(()
) 的单例值。 if (b)
语句中也会发生同样的情况(从技术上讲,()
将是 myMethod
的结果,但它与 if (a)
中的 ()
相同) .
因此您需要添加 else
子句,这也会导致 Future[Done]
并确定如果 a
和 b
都是true(此外,如果您希望同时调用 obj1
和 obj2
,则需要决定是顺序执行还是并行执行)以及 a
和b
为假。
谢天谢地,因为 Done
是一个单例(就编码“这件事”而言,它与 Unit
基本相同,但在某种程度上更适合 Java 代码使用 Akka),有一个合理的默认值 Future[Done]
:Future.successful(Done)
(基本上可以解释为“是的,当然,我做到了(但实际上没有什么可做的)”)。
所以如果你想同时进行 obj1
和 obj2
调用(或者至少没有定义的“happens-before”关系),你可以这样写:
val obj1Fut = if (a) obj1.methodWhichReturnsFuture() else Future.successful(Done)
val obj2Fut = if (b) obj2.methodWhichReturnsFuture() else Future.successful(Done)
// exploits eagerness of Future, won't complete until both obj1Fut and obj2Fut have completed
obj1Fut.flatMap(_ => obj2Fut)
如果您不想在 obj1
调用之前执行 obj2
调用:
val obj1Fut = if (a) obj1.methodWhichReturnsFuture() else Future.successful(Done)
obj1Fut.flatMap { _ =>
if (b) obj2.methodWhichReturnsFuture()
else Future.successful(Done)
}
请注意,在您提供的 Unit
返回代码中,obj2
未来很有可能在 obj1
的未来完成之前完成。
如果您只想在 a
和 b
都为真时执行 obj1
调用:
if (a) obj1.methodWhichReturnsFuture()
else if (b) obj2.methodWhichReturnsFuture()
else Future.successful(Done)
// or the equivalent pattern match, which might be more legible than if else if else
// (a, b) match {
// case (true, _) => obj1.methodWhichReturnsFuture()
// case (false, true) => obj2.methodWhichReturnsFuture()
// case (false, false) => Future.successful(Done)
// }
我有两个相同类型的对象,但我想使用这些对象调用方法,但取决于几个布尔值。
def myMethod(a: Boolean, b: Boolean, obj1: MyClass, obj2: MyClass): Future[Done] = {
if(a) obj1.methodWhichReturnsFuture()
if(b) obj2.methodWhichReturnsFuture()
}
这里方法#methodWhichReturnsFuture 有return typr Future[Done]。这显示错误,因为我在这里 returning Unit。我虽然创建了一个 'var' 并在两个方法调用中分配它,但看起来这不是一个好方法。这绝对是基本的,但我想知道实现它的更好方法是什么?谢谢
在 Scala 中,没有 else
的 if
只能针对 side-effect 执行,因此
if (a) obj1.methodWhichReturnsFuture()
将被丢弃,结果是 Unit
(()
) 的单例值。 if (b)
语句中也会发生同样的情况(从技术上讲,()
将是 myMethod
的结果,但它与 if (a)
中的 ()
相同) .
因此您需要添加 else
子句,这也会导致 Future[Done]
并确定如果 a
和 b
都是true(此外,如果您希望同时调用 obj1
和 obj2
,则需要决定是顺序执行还是并行执行)以及 a
和b
为假。
谢天谢地,因为 Done
是一个单例(就编码“这件事”而言,它与 Unit
基本相同,但在某种程度上更适合 Java 代码使用 Akka),有一个合理的默认值 Future[Done]
:Future.successful(Done)
(基本上可以解释为“是的,当然,我做到了(但实际上没有什么可做的)”)。
所以如果你想同时进行 obj1
和 obj2
调用(或者至少没有定义的“happens-before”关系),你可以这样写:
val obj1Fut = if (a) obj1.methodWhichReturnsFuture() else Future.successful(Done)
val obj2Fut = if (b) obj2.methodWhichReturnsFuture() else Future.successful(Done)
// exploits eagerness of Future, won't complete until both obj1Fut and obj2Fut have completed
obj1Fut.flatMap(_ => obj2Fut)
如果您不想在 obj1
调用之前执行 obj2
调用:
val obj1Fut = if (a) obj1.methodWhichReturnsFuture() else Future.successful(Done)
obj1Fut.flatMap { _ =>
if (b) obj2.methodWhichReturnsFuture()
else Future.successful(Done)
}
请注意,在您提供的 Unit
返回代码中,obj2
未来很有可能在 obj1
的未来完成之前完成。
如果您只想在 a
和 b
都为真时执行 obj1
调用:
if (a) obj1.methodWhichReturnsFuture()
else if (b) obj2.methodWhichReturnsFuture()
else Future.successful(Done)
// or the equivalent pattern match, which might be more legible than if else if else
// (a, b) match {
// case (true, _) => obj1.methodWhichReturnsFuture()
// case (false, true) => obj2.methodWhichReturnsFuture()
// case (false, false) => Future.successful(Done)
// }