可以在“ for .. range”循环(如在标准的for循环)中的每次迭代之后添加最终语句吗?

In a for task := range ch {..} loop (iterating over a channel), I have several places where I want to step forward to the next element (continue); however, I need to execute an additional statement before the continue (setting a flag to mark the worker routine is currently idle), but before the next element is received from the channel - see code sample below.

Currently, I have to repeat this statement before every continue. This works, but is not very elegant, and a worker.setIdle() can easily be forgotten. It would be nice if I could set up such a "finalizer" statement at the entry of the loop, something like you could expect of a for task := range ch; worker.setIdle() {...} construct, but of course that is syntactically incorrect. It would be like a defer in a loop, which is executed at the end of each loop iteration instead at the end of the function. Is there a way to express this in Go?

for task := range ch {
  ...
  if (...) {
    ...
    worker.setIdle()
    continue
  }
  ...
  if (...) {
    ...
    worker.setIdle()
    continue
  }
  ...
  if (...) {
    ...
    worker.setIdle()
    continue
  }
  ...
  worker.setIdle()
}

EDIT: Thanks for the replies - I think the best solution (or at least another alternative) might be an anonymous function as follows:

for task := range ch {
  func () {
    ...
    if (...) {
      ...
      return
    }
    ...
  } ()
  worker.setIdle()
}

Only drawback is that the return statements might be misleading, they should probably be commented. A "defer" statement on basic block granularity (or also whole loop granularity) would be nice to have :-)

An easy way to achieve this to extract the body of the loop to a function and restructure your code like this:

for task := range ch {
  doSomething(task)
  worker.setIdle()
}

func doSomething(task Task) {
   if (...) {
     ...
     return
   }
   if (...) {
     ...
     return
   }
   ...
}

This may lead to a better seperation of concerns: One function to handle incoming tasks and the worker and on function to do the actual work.

Use a for loop without the range clause. Receive on the channel in the loop and break from the loop when the channel is closed.

for {
    worker.setIdle()
    task, ok := <-ch
    if !ok {
        break
    }
    if (...) {
       ...
       continue
    }
    ...
    if (...) {
       ...
       continue
    }
    ...
    if (...) {
       ...
       continue
    }
    ...
}