在Scala中逐个执行方法序列,只有在前一个方法返回true时才继续

时间:2013-03-18 21:07:01

标签: scala

我使用scala环绕STAF来运行具有多个步骤的测试。

基本上每一步都是一个返回布尔值的方法调用。这些步骤按顺序执行。我想知道是否有办法告诉Scala只有前一个返回true才能进入下一步?

谢谢,

修改

在下面添加了一个示例。

这是我在测试后收集数据的步骤列表。它有3个步骤。 1)压缩日志,2)将压缩存档复制到某处,3)清除日志目录

zipDir(handle, "testmachine1", """C:\Logs""", """C:\Logs.zip""")
copyFile(handle, "testmachine1", """C:\Logs.zip""", "RepoMachine", """c:\data""")
clearDirContent(handle, "testmachine1", """C:\Logs""")

对我来说,如果前面的步骤已正确执行,那么继续下去才有意义。例如,如果首先创建zip文件时出错,则在步骤2中复制zip文件是没有意义的。

为了说明我的观点,这是一个完成我想要的简单方法:

var result = zipDir(handle, "testmachine1", """C:\Logs""", """C:\Logs.zip""")
if (result) 
    result = copyFile(handle, "testmachine1", """C:\Logs.zip""", "RepoMachine", """c:\data""")
if (result) 
    result = clearDirContent(handle, "testmachine1", """C:\Logs""")

4 个答案:

答案 0 :(得分:3)

我不知道任何scala,但使用普通的java你只需和它们在一起。一旦func返回false,表达式就为false并且执行停止。

val result = fun1() && func2() && func3()

答案 1 :(得分:2)

嗯,在你的情况下,你可以使用简单的布尔值和:

val result = zipDir(handle, "testmachine1", """C:\Logs""", """C:\Logs.zip""")
          && copyFile(handle, "testmachine1", """C:\Logs.zip""", "RepoMachine", """c:\data""")
          && clearDirContent(handle, "testmachine1", """C:\Logs""")
&&不同的

&会在第一个错误值

上停止

过时回答:

listOfMethods.forall(f => f(x))怎么样?它会短路,因此不会执行第一次错误后的操作:

scala> def a() = { println("A"); false } 
a: ()Boolean

scala> def b() = { println("B"); true }
b: ()Boolean                                          

scala> List(a _ ,b _ ).forall(f => f())
A
res2: Boolean = false

重要提示:你必须将闭包放入你的收藏中:如果你写List(a(1), b(2))魔法不会发生:a(1)和b(2)将会急切执行被列入清单。你可以这样写:

def foo(x: Int) = { println ("Foo is " + x); false}
def bar(x: Int) = { println ("Bar is " + x); false}
List(
  () => foo(1), 
  () => bar(2)
).forall{ fun => fun() } 

答案 2 :(得分:1)

我认为你想通过返回scalaz的验证或某种形式的Either来理解,所以它会是

for {
  res1 <- func1
  res2 <- func2
  ...
} yield resN

这样,当你的函数返回失败时,它会停在失败的地方。

答案 3 :(得分:1)

惯用Scala的方法是使用for-comprehension。你的中间方法需要返回一个在其上定义了.map和.flatMap的类型 - 在这里,如果操作成功,你可以返回一个选项,否则返回None。如果要保留错误消息,请查看验证或任一。

var result = for {
  zipped <- zipDir(handle, "testmachine1", """C:\Logs""", """C:\Logs.zip""")
  copied <- copyFile(handle, "testmachine1", """C:\Logs.zip""", "RepoMachine", """c:\data""")
  cleared <- clearDirContent(handle, "testmachine1", """C:\Logs""")
} yield {
   cleared
}
如果所有3个操作都发生,那么

result将是一些,否则为无。如果任何中间步骤没有返回,则操作短路;在引擎盖下,for-comprehension使用map and flat-map

我之所以建议短路的原因是因为它更加灵活。例如,您可能会遇到不再需要对文件名和路径进行硬编码的问题,因此如果zip操作成功,您可以让zipDir返回压缩文件的完整路径。您的代码可能看起来像

val result = for {
  zipped  <- zipDir(handle, machine, filepath)
  copied  <- copyFile(handle, machine, zipped, newlocation)
  cleared <- clearDirContent(handle, machine, filepath)
} yield cleared