Статьи

Go для программистов на Java: управляющие структуры

Go (Golang) имеет только три базовые структуры управления. Однако каждый из них значительно более универсален, чем их коллеги по Java.

Если

Оператор if должен быть сразу узнаваем. В своей основной форме он выглядит так же, как в Java, только без скобок вокруг условия:

1
2
3
4
5
...
if err != nil {
   fmt.Println("An error occurred!")
}
...

Однако версия Go отличается от версии Java в двух отношениях. Во-первых, когда тело оператора if представляет собой только одну строку, Java позволяет пропустить открывающую и закрывающую скобки:

Герцог-голова

1
2
3
...
if(inputString == null) return "null";
...

Go, с другой стороны, имеет несколько сильных мнений о хорошо отформатированном и читабельном коде (подробнее об этом в следующей статье). Оператор Go if требует открывающей и закрывающей фигурной скобки независимо от того, что:

Суслик-голова

1
2
3
4
5
...
if inputString == null {
   return "null"
}
...

Во-вторых, Go компенсирует это ограничение гибкой функцией инициализации. Внутри самого объявления if вы можете поместить оператор инициализации непосредственно перед условием:

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

Здесь оператор if выполняет операцию удаления файла, возвращая переменную ошибки, которая заполняется, если удаление не удалось. Затем условие проверяет это значение и вводит блок if, если условие истинно.

Почему так, а не просто выполнять операцию удаления файла в отдельной строке над оператором if? Ключевой особенностью этого подхода является то, что переменные, созданные в операторе инициализации, имеют область действия, ограниченную блоком if.

Приведенный выше фрагмент кода является очень распространенным шаблоном в Go, и более поздняя статья этой серии будет более подробно посвящена обработке ошибок. Однако дело в том, что эта конструкция инициализации может создать любую переменную, которая должна находиться в области видимости до условия if, но вне области видимости после блока if.

за

Базовый цикл for в Go также похож на свой аналог Java. Он содержит оператор инициализации, условие, которое проверяется перед каждой итерацией, и код, выполняемый после каждой итерации. Единственное отличие состоит в том, что нет никаких паретезов, окружающих эти три вещи:

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

Однако цикл for имеет две другие формы, кроме этой базовой версии. Go не имеет структур управления цикла while или do, найденных в Java , поэтому другие формы цикла for имеют ту же функциональность на своем месте.

Если вы пишете оператор for только с условием, без кода инициализации или после итерации, то это по сути Java-цикл while:

1
2
3
4
5
...
for len(slice) < maxSize {
   slice = append(slice, getNextItemToAdd())
}
...

Конечно, вы можете сделать нечто подобное с циклом Java for, вставив пустые операторы для частей инициализации и / или после итерации. Тем не менее, версия Java всегда требует трех частей, строго говоря. Вы должны вставить точки с запятой для частей, которые вы хотите заполнить пустыми утверждениями. В Go конструкция только для условий представляет собой отдельный тип цикла for, и никакие точки с запятой не требуются.

В третьей форме цикла вы можете опустить даже условие. Это создает бесконечный цикл, требующий завершения оператора break в какой-то момент.

Суслик-голова

01
02
03
04
05
06
07
08
09
10
11
12
13
...
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
 
}
...

Голый цикл for — это эквивалент Go для Java:

Герцог-голова

01
02
03
04
05
06
07
08
09
10
11
...
while(true) {
   String command = System.console().readLine();
   if(command.equals("exit")) {
      break;
   }
 
   // do something based on the command typed
 
}
...

переключатель

В Java оператор switch выполняет один или несколько блоков кода на основе значения некоторой переменной. Для большей части истории Java вы можете включать только переменные типа примитива или перечисления, хотя в Java 7 наконец-то добавлена ​​поддержка String как типа переключателя.

Герцог-голова

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
...
switch(deviceType) {
    case "PHONE" :
        renderForPhone();
        break;
    case "TABLET" :
        renderForTablet();
        break;
    case "DESKTOP" :
        renderForDesktop();
        break;
    default :
        System.out.println("Unrecognized device: " + deviceType);
}
...

В Go оператор switch не просто сравнивает переменную со списком возможных совпадений. Скорее, переключатель Go проверяет несколько условий свободной формы . Условия могут быть совершенно не связаны друг с другом, и каждый может быть настолько сложным, насколько вам нравится. Для первого пройденного условия будет выполнен соответствующий код:

Суслик-голова

01
02
03
04
05
06
07
08
09
10
11
...
switch {
   case customerStatus == "DELINQUENT" :
      rejectOrder()
   case orderAmount > 1000 || customerStatus == "GOLD_LEVEL" :
      processOrderHighPriority()
   case orderAmount > 500 :
      processOrderMediumPriority()
   default :
      processOrder()
}

Помимо гибких условий, другое ключевое отличие от переключателя Java в том, что версия Go НЕ проваливается. В Java оператор switch может выполнять несколько блоков case. Если вы не поместите оператор break в конец блока case, то следующее условие case также будет оцениваться на соответствие.

С Go оператор switch в основном является более чистым способом написания беспорядочной серии блоков if-else.

Вывод

Ключевые слова if, for и switch очень похожи на свои аналоги в Java. Тем не менее, каждый из них предлагает расширенную гибкость, чтобы помочь вам написать более четкую и лаконичную логику. В следующей статье серии Go for Java Programmers мы рассмотрим конкретные правила Go для хорошо отформатированного кода.

Ссылка: Найдите программистов на Java: управляющие структуры от нашего партнера по JCG Стива Перкинса в блоге steveperkins.net .