Любой, кто впервые сталкивается с языком программирования Go, обязательно будет сбит с толку некоторыми дизайнерскими решениями, лежащими в основе этого языка. Обратные объявления, синтаксис method, встроенный параллелизм, отсутствие наследования — все это поначалу может показаться странным, если не сказать больше.

Поработав немного с языком, вы начинаете понимать, к чему стремились разработчики Go. Используйте его немного больше, и вы начнете ценить его. Вы начинаете понимать, насколько облегченные процедуры go могут быть лучше, чем потоки, и как встроенные функции параллелизма могут сделать код намного более надежным. Вы узнаете, что наследование ООП не так круто, как вас когда-то учили, и его часто лучше избегать.

Однако то, что я собираюсь показать вам, обязательно заставит вас съежиться. Давайте посмотрим на очень простой фрагмент кода.

package main
import "fmt"
func main() {
 var status bool = true
 if status {
  fmt.Println("True")
 } else {
  fmt.Println("False")
 }
}

Пока ничего особенного. Выполнение кода выдает True на стандартный вывод, как и следовало ожидать. Становится намного интереснее, когда мы добавляем в код следующую строку.

var true = false

Мы помещаем его непосредственно перед функцией, в результате чего получается следующий код.

package main
import "fmt"
var true = false
func main() {
 var status bool = true
 if status {
  fmt.Println("True")
 } else {
  fmt.Println("False")
 }
}

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

облом. Кажется, что вы можете переопределить константу и использовать ее как переменную. Хуже всего то, что вы можете делать это даже со встроенными типами. Взгляните на следующий вариант кода.

package main
import "fmt"
var int = false
func main() {
 var status bool = int
 if status {
  fmt.Println("True")
 } else {
  fmt.Println("False")
 }
}

Мы используем int в качестве переменной. Это не может быть хорошо.

Я подал проблему в проект go. К сожалению, мне не удалось получить подробное объяснение, почему это разрешено. Что я знаю, так это то, что это останется во всех 1.x.x версиях языка из-за обещания обратной совместимости, которое было сделано.

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

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