Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
680 views
in Technique[技术] by (71.8m points)

Groovy break out of outer switch from nested switch (not in loop)?

switch statements in Groovy are infinitely more flexible, powerful and applicable than in Java. For this reason I've just found myself wanting to use a nested switch for the first time in Groovy.

With this:

outerSwitch:
switch( var1 ){
    case 'x': 
        ...
        break
    case 'y':
        switch( var2 ){
            case 'a':
            // something
            break outerSwitch
            ...
        }
    ...
}

... I get a horrid message from the Groovy compiler saying "Groovy: the break statement with named label is only allowed inside loops". I don't know whether this is the same with Java.

There is an obvious silly workaround: you enclose your outer switch with a while( true ), apply the outerSwitch label to that, and put a break statement at the end of your outer switch.

Or you could do a for( int i = 0; i < 1; i++ ) ... or use a Groovy-er idiom for the same thing, I forget what all the options are... although having tried

outerSwitch:
1.times{
    switch( var1 ){
        ...
}

... I find that the Groovy compiler gives the same nasty message. So you can't fool it with a closure, seemingly.

Is there anything in the Groovy toolkits and boxes of tricks which lets you jump out of the outer switch from the nested switch more sensibly?

The trouble being, I suppose, that when you break from a case block you don't do so with a value... if you could go break true or break 'fiddle-de-dee' there'd be obvious ways to solve this.

An obvious workaround is that you can precede your nested switch with def breakouter = false and then change that as applicable in the case block. I'd just hope that Groovy would provide something more elegant...

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Not sure about the break behavior but if refactoring your switch statement is an option, perhaps the following could work:

def var1 = "y"
def var2 = "a" 

switch ([var1, var2]) {
  case { it.first() == "x"}: 
    println "var1 == 'x'"
    break

  case [['y', 'a']]:
    println "var1 == 'y', var2 == 'a'"
    break

  default: 
    println "something else"
}

where the first case condition is a closure which will execute the case if it returns true and the second is a list of lists which will execute the case if the outer list contains the value.

This code essentially replicates the functionality in your original code snippet but with a flat switch structure. Breaking with labels, even if it worked, is in my mind not a good pattern.

Output:

~> groovy test.groovy 

var1 == 'y', var2 == 'a'

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...