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 . |