About Steve Perkins

Steve Perkins is the author of “Hibernate Search by Example”, and has over fifteen years of experience working with enterprise Java. Steve lives in Atlanta, GA, USA and currently works as a software architect at BetterCloud, where he writes software for the Google cloud ecosystem.

Go for Java Programmers: Control Structures

Go (Golang) has only three basic control structures.  However, each of them are significantly more versatile than their Java counterparts.

If

The if statement should be immediately recognizable.  In its basic form it appears the same as in Java, just without parentheses around the condition:
 
 
 
 

...
if err != nil {
   fmt.Println("An error occurred!")
}
...

However, Go’s version differs from Java’s if in two regards.  First, when the body of an if statement is only a single line, Java allows you to omit the opening and closing braces:

duke-head

...
if(inputString == null) return "null";
...

Go, on the other hand, has some strong opinions on well-formatted and readable code (more on this to come in the next article).  A Go if statement requires an opening and closing brace no matter what:

gopher-head

...
if inputString == null {
   return "null"
}
...

Secondly, Go makes up for this restriction with a flexible initialization feature. Inside of the if declaration itself, you can place an initialization statement just before the condition:

...
if err := os.Remove("data.csv"); err != nil {
   fmt.Println("Unable to delete the file 'data.csv'")
}
...

Here, the if statement performs a file delete operation, returning an error variable that’s populated if the delete failed.  The condition then checks this value, and enters the if block if the condition is true.

Why do it this way, as opposed to simply performing the file delete operation on a separate line above the if statement?  The key feature of this approach is that variables created in an initialization statement have scope limited to the if block.

The example snippet above is a very common pattern in Go, and a later article in this series will deal with error handling more thoroughly.  However, the point is that this initialization construct can create any variable that you need to have in-scope prior to the if condition, yet out-of-scope after the if block.

for

A basic for loop in Go is likewise similar to its Java counterpart.  It contains an initialization statement, a condition to be checked before each iteration, and code to executed following each iteration.  The only difference is that there are no paretheses surrounding these three things:

...
for index := 0; index < 10; index++ {
   fmt.Printf("index == %d", index)
}
...

However the for loop has two other forms besides this basic version.  Go does NOT have the while or do loop control structures found in Java, so the other for loop forms cover the same functionality in their place.

If you write a for statement with only a condition, and no initialization or post-iteration code, then it is essentially a Java while loop:

...
for len(slice) < maxSize {
   slice = append(slice, getNextItemToAdd())
}
...

Of course, you could do something similar with a Java for loop, by inserting empty statements for the initialization and/or post-iteration parts.  However, the Java version always requires three parts, strictly speaking.  You have to insert semicolons for the parts you wish to fill with empty statements.  In Go, the condition-only construct is a distinct type of for loop, and no placeholder semicolons are necessary.

In the third for loop form, you can omit even the condition.  This creates an infinite loop, requiring a break statement to terminate at some point.

gopher-head

...
consoleReader := bufio.NewReader(os.Stdin)
for {
   command, hasMoreInLine, err := bio.ReadLine()
   if err != nil || command == "exit" {
      // The user typed an "exit" command (or something went wrong).  Time to exit this loop!
      break;
   }

   // do something based on the command typed

}
...

The bare for loop is the Go equivalent to Java’s:

duke-head

...
while(true) {
   String command = System.console().readLine();
   if(command.equals("exit")) {
      break;
   }

   // do something based on the command typed

}
...

switch

In Java, a switch statement executes one or more blocks of code, based on the value of some variable.  For most of Java’s history, you could only switch on primitive or enum type variables, although Java 7 finally added support for String as a switch type.

duke-head

...
switch(deviceType) {
	case "PHONE" :
		renderForPhone();
		break;
	case "TABLET" :
		renderForTablet();
		break;
	case "DESKTOP" :
		renderForDesktop();
		break;
	default :
		System.out.println("Unrecognized device: " + deviceType);
}
...

In Go, a switch statement does not merely compare a variable to a list of possible matches.  Rather, a Go switch tests multiple free-form conditions.  The conditions may be completely unrelated to each other, and can each be as complex as you like.  The first condition that passes will have its corresponding code executed:

gopher-head

...
switch {
   case customerStatus == "DELINQUENT" :
      rejectOrder()
   case orderAmount > 1000 || customerStatus == "GOLD_LEVEL" :
      processOrderHighPriority()
   case orderAmount > 500 :
      processOrderMediumPriority()
   default :
      processOrder()
}

Aside from flexible case conditions, the other key difference from Java’s switch is that Go’s version does NOT fall through.  In Java, a switch statement might execute multiple case blocks.  If you do not put a break statement at the end of a case block, then the next case condition will be evaluated for a match as well.

With Go, a switch statement is basically just a cleaner way of writing a messy series of if-else blocks.

Conclusion

The if, for, and switch keywords are extremely similar to their Java counterparts.  However, each of them offers extended flexibility to help you write more clear and concise logic.  In the next article of the Go for Java Programmers series, we’ll look at Go’s particular rules for well-formatted code.

Reference: Go for Java Programmers: Control Structures from our JCG partner Steve Perkins at the steveperkins.net blog.
Related Whitepaper:

Software Architecture

This guide will introduce you to the world of Software Architecture!

This 162 page guide will cover topics within the field of software architecture including: software architecture as a solution balancing the concerns of different stakeholders, quality assurance, methods to describe and evaluate architectures, the influence of architecture on reuse, and the life cycle of a system and its architecture. This guide concludes with a comparison between the professions of software architect and software engineer.

Get it Now!  

Leave a Reply


four + 1 =



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

20,709 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books