【问题标题】:Scala basic for loops getting skipped and not entering the loop for executionScala基本的for循环被跳过并且没有进入循环执行
【发布时间】:2018-08-03 04:45:57
【问题描述】:

在我的服务中遇到一个问题,放置在 Scala 类中的任何 for 循环都会被跳过并且不会进入循环执行:

def createSample(){
  for (x <- 0 until 3) {
    println(x)
  }
}

另一个例子:

class messageTest extends FunSpec with GivenWhenThen with Matchers {

  def validatemessage(message: message, checkMessageRef: Boolean = true) = {
    assert(message.getMessageId == UserId.fromString("545n”))

    if (checkMessageRef) {
      assert(message.getMessageReferenceText == “refersnce”)
     }
  }

  val messageV5 = createmessageV5
  val testmessage = createtestMessageContextV5

  describe("message") {
    it("throws an error if message is not populated") {
      assert(
        intercept[InvalidFieldException] {
          new message(null, testmessage, "Search")
        }.getMessage == "Message Context cannot be null")
    }
    it("throws an error if MessagetestContext is not populated") {
      assert(
        intercept[InvalidFieldException] {
          new message(messageV5, null, “Fetch”)
        }.getMessage == "test Message Context cannot be null")
    }

    it("should initiate the context with testmessage when populated") {
      When("the constructor is called with valid data")
      messageV5.setUserId(“123454")
      val message = new message(messageV5, testmessage, "Search")

      Then("message is correctly populated")
      validatemessage(message, false)

    }

    it("should initiate debugTrace to accordingly to the input provided in the message") {
      val messageV5 = createmessageV5
      messageV5.setUserGUID("123454")
      When("the with a 'null' DebugTrace object")
      messageV5.setDebugTrace(null)
      Then("message debug trace is false")
      assert(!new message(messageV5, testmessage, "Search").getDebugTrace)
      When("the with a 'false' DebugTrace object")
      messageV5.setDebugTrace(false)
      Then("message debug trace is false")
      assert(!new message(messageV5, testmessage, "Search").getDebugTrace)
      When("the with a 'true' DebugTrace object")
      messageV5.setDebugTrace(true)
      Then("message debug trace is false")
      assert(new message(messageV5, testmessage, "Search").getDebugTrace)
    }

  }

  def createmessageV5: messageType = {
    val messageV5 = new messageType

    ***for (x <- 0 until 3) {
     println(x)
    }***

    messageV5.setMessageId(“545n”)

    messageV5.setMessageReference(“reference”)

    messageV5
  }
}

以上只是测试的一部分,但它按预期工作,但是当我将这个 for 循环添加到类中时,它会被跳过,无论我将它放在什么 scala 测试中,都会发生同样的情况。

简而言之,当它编译时,由于某种原因,它被读取为空语句,然后跳到下一行可执行代码。

【问题讨论】:

  • 我一定会得到0 1 2。确保从主函数调用createSample()
  • 您是否在代码中的任何位置调用createSample() 方法?
  • 如何知道for之前/之后的代码是否被执行?
  • 到目前为止您尝试过什么来解决它?
  • 我在 scala 类中运行测试时调试了代码,每次遇到 for 循环时它都会跳过它并且不进入执行 println

标签: java scala for-loop syntax compilation


【解决方案1】:

不清楚这是代码问题还是调试器问题,所以这里有两种可能的情况:

代码问题

如果createSample 在调试器外部运行时没有打印任何内容,那么这是代码问题,在调试器下运行它只会让事情变得混乱。使用println 语句来跟踪代码的执行,这可能有助于说明为什么没有调用该函数。用一个最小的失败示例更新您的问题,我们会尽力帮助解决它。

调试器问题

如果createSample 在调试器之外正确打印,则这是一个调试问题。调试器无法“进入循环”,因为您的代码中有 there is no loop,只需在 Range 对象上调用 foreach。默认情况下,除非您选择 Force Step Into,否则 IntelliJ 将跳过此调用。如果您这样做,您最终将到达Range.foreach 中的实际循环,该循环又调用包含您的println 语句的lambda 函数。

如果您在 println 语句上设置断点,调试器应该会停在那里。

【讨论】:

  • 谢谢!!看起来这是一个调试器问题,当我将调试点放在里面时它确实停止在里面,但是它确实会产生一个问题,因为当我运行测试时它不执行循环内的代码时测试失败
【解决方案2】:

让我们试试吧:

scala> def createSample(){
     |   for (x <- 0 until 3) {
     |     println(x)
     |   }
     | }
createSample: ()Unit

scala> createSample()
0
1
2

您的代码没有问题。所以问题是该方法没有被调用,因为:

  1. 你不叫它!
  2. 有一个exception 或某种错误,例如:

    scala> def createError(){
     |   throw new Exception("Ack Ack")
     | }
    createError: ()Unit
    
    scala> def pipe(){
     | createError()
     | createSample()
     | }
    pipe: Unit
    
    scala> pipe()
    java.lang.Exception: Ack Ack
    at .createError(<console>:8)
    at .pipe(<console>:10)
    ... 33 elided
    

现在因为你说它是一个服务,我想你是在调用一个第三方服务但没有捕捉到它的错误,所以你看不到异常;因此那部分代码没有运行。

【讨论】:

  • 谢谢,但该方法已被调用,这是我在本地系统上调试测试时发现的问题。当我们运行测试但从未进入时,调试步骤按预期到达 for 循环循环并跳到下一个可执行行,不抛出异常
  • @RoshanVarghese Dave 说您调用第三方服务。并不是说您在本地或远程运行某些东西。在 for 循环之前有一些东西默默地失败了。 David 还说“但没有捕捉到它的错误,所以你看不到异常” 尝试在 for 循环之前的任何地方放置 try/catch 块,并尽可能捕捉最通用的异常,以便调试这个。或者将 println("WE REACHED HERE") 放在 for 循环之前的任何位置。
  • 对,我明白你的意思,但正如我提到的,在测试期间添加 try/catch 后没有错误或异常,并且执行确实正确地到达了 for 循环。现有测试的唯一新变化是添加了简单的 for 循环。我假设语法可能不正确,但看起来不错。
  • 简而言之,当它编译时,由于某种原因被读取为空语句,只是跳到下一行可执行代码
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-30
  • 1970-01-01
  • 1970-01-01
  • 2019-05-17
  • 1970-01-01
相关资源
最近更新 更多