Go in a nutshell
  • Go in a nutshell
  • Введение
  • Родословная или Should I Go?
  • Hello, world!
  • Базовые типы данных
  • Go - установка, сборка
  • Алфавит и пакеты
  • Синтаксис
  • Приведение типов
  • Операторы
  • Константы
  • Управление потоком
  • Массивы, срезы, отображения
  • Именованные типы и структуры
  • Указатели и оператор new
  • Функции
  • Работа с параметрами командной строки
  • Завершение работы программы
  • Методы
Powered by GitBook
On this page

Was this helpful?

Алфавит и пакеты

За 15 лет, если бы я писал каждый день только одну страницу, можно было бы уже иметь примерно 5500 страниц. Значит, я написал намного меньше, чем мог. И все же я не считаю себя большим лентяем! Дело в том, что в эти годы я еще работал как журналист и делал много других вещей. Например, я писал статьи для газет и журналов, занимался школьными проблемами, играл со своей дочкой, слушал музыку, ходил гулять, думал. А думать - это тоже полезное дело. Может быть, даже самое полезное из всех других. По-моему, каждый человек должен полчаса в день думать. Это можно делать всюду - сидя за столом, гуляя в лесу, в одиночестве или в компании.

Джанни Родари

Пожалуй и мне следует сделать для себя некоторые выводы. Необходимо думать и писать. Приступим!

Коль скоро уж решено - ни дня без строчки - я долго колебался, продолжить ли речь рассказом о небазовых (именовнных) типах, что было бы, вероятно, логично, но всё же решил поговорить с вами пока что о более абстрактных вещах. А для этого вам достаточно знаний базовых примитивов.

Язык Go (кстати, настоятельно попрошу избегать по отношению к нему употребления вульгарного термина "GOLANG"), имея все внешние атрибуты языка сугубо процедурно-функционального, тем не менеее позционируется (и не без оснований, весьма тонких) как ООП язык. Go - язык регистрозависимый и этот факт несёт огромную смысловую нагрузку. Все переменные, функции, поля структур, инкапсулирующие те или иные сущности, при именовании с заглавной буквы считаются "экспортируемыми" и, грубо выражаясь, приобретают модификатор "public" в терминах классического ООП. Говоря вообще, с неймингом в Go дело обстоит довольно запутанно. Пожалуй, пользуясь правилами, привычными для других популярных языков, к примеру семейства С/С++, вы вряд ли ошибётесь. Если же излагать материал научно, то необходимо отметить следующее:

  • Имена переменных не могут начинаться с цифр

  • В идентификаторах запрещено использовать зарезервированные (ключевые) слова Go

  • В нейминге в качестве букв рассматриваются не только привычные символы английского алфавита, на самом деле под «буквами» понимаются все символы Юникода, относящиеся к категориям «Lu» (буквы верхнего регистра), «Ll» (буквы нижнего регистра), «Lt» (заглавные буквы), «Lm» (буквы-модификаторы) или «Lo» (прочие буквы). Под «цифрами» понимают все символы Юникода из категории «Nd» (числа, десятичные цифры). Таким образом, ничто не мешает использовать в идентификаторах, например, кириллицу или, к примеру, китайские иероглифы. Представляете красоту и полёт фантазии? А какое раздолье для обфускатора...

  • В именах пакетов используются только строчные буквы.

  • Все ключевые слова Go пишутся в нижнем регистре.

package main
import "fmt"

func main(){
    var 金瓶梅 = "Jīn Píng Méi"
    fmt.Println(金瓶梅)
}
// Цзинь пин мэй - цыеты и сливы в золотой вазе...

Пожалуй, всё об алфавите.

Пакеты

Пакеты - это одна из фундаментальных основ языка Go. В этом языке нет динамической линковки, и на выходе мы всегда имеем статический бинарник. Объяснение этому очень простое - разработчики Go всё время стремятся к наивозможной степени минимализма, и объяснением дизайна почти любого аспекта Go является упрощение архитектуры. Однако (и мы ещё с вами с этим встретимся) в среде *.NIX возможно создание Shared object`ов (SO файлов) средствами Go (точнее CGO). Причём такие никсовые аналоги DLL смогут "бесшовно" работать с C/C++, JAVA посредством JNI, Python при помощи ctypes, Ruby, используя FFI. И это только те кейсы, с которыми реально работал автор! Эта возможность - истинный сахар для программиста: там, где нужно было бы корпеть, переписывая чей-то код на C++, можно по-быстрому подкинуть в проект SO-шник, написанный на Go, и наслаждаться своим умом и сообразительностью.

Однако, вернёмся к пакетам. Пакеты - есть библиотеки констант, переменных и функций, только не скомпилированные. Стандартное расширение файлов - *.go. Все сущности, начинающиеся с заглавных букв, считаются экспортируемыми (доступными в пакете main или любом другом пакете). Верно также и обратное утверждение. Инкапсуляция. Повеяло ООП...

Нейминг пакетов в Go чем-то напоминает таковой в JAVA, ибо используются FQDN. Создадим в каталоге %GOPATH% папку fqdn.org. В ней разместим файл (назовём его utils.go) такого содержания:

package utils
import "fmt"
var V int
func F() {
	fmt.Println("Value of \"V\" is",  V)
}

Congratulations, мы создали пакет fqdn.org/utils!

Строкой import "fmt" мы подключили пакет fmt стандартного набора пакетов дистрибутива Go. В строке fmt.Println() соответственно была вызвана экспортируемая функция Println() данного пакета. "Дистрибутивные" библиотеки являются частью языка и развиваются/добавляются от версии к версии по мере его развития.

Важно! Внутри каталога может размещаться лишь один пакет. Пакет позволительно логически разбить на некоторое количество файлов. Для избежания путаницы при разрастании набора библиотек, которые вы будете постепенно создавать в процессе работы, рекомендую для каждой библиотеки создавать свой подкаталог. Таким образом, создадим в нашем корневом каталоге со "сферическим" названием fqdn.org (у вас он может называться, предположим, mycompany.com или как-то иначе) папку common-utils и переместим туда файл utils.go. В результате импорт и использование функций нашего пакета теперь будут выглядеть так:

package main
import "fqdn.org/common-utils"

func main(){
    utils.F()
}

Для добавления нового пакета вы просто создадите в корневом каталоге новую папку "new-awesome-project" и станете помещать туда файлы с заголовком, скажем, "package awesome". И так далее.

Сторонние же пакеты необходимо самостоятельно скачивать (привет NPM, Nuget)... Чаще всего это приходиться делать с Github. Поэтому наличие установленного и настроенного git - обязательно. Команда получения пакета выглядит как-то так:

go get github.com/jacobsa/go-serial/serial

То есть Go умный, и git использует самостоятельно, напрямую, без нашего вмешательства. Столь же прост и апдейт - go get -u full_package_name, либо go get -u all - для всех установленных third-party packages. Где же находятся скачанные пакеты? Резонный вопрос. Выполните в консоли команду go env и найдите в её выводе параметр GOPATH. именно это и есть хранилище для third-party packages. Кроме прочего, именно сюда вы будете помещать ваши собственные творения!

Nota bene!

Все экспортируемые сущности должны быть определённым образом описаны в коде!

Далее, установим golint: go get golang.org/x/lint/golint

Это - инструмент для валидации нашего кода. Golint разработан командой Go и проверяет код на основе документов Effective Go и CodeReviewComments.

Запускаем: golint fqdn.org/common-utils

Вывод работы программы:

Как видите, валидацию мы не прошли. К слову, проходить её не обязательно, всё будет работать и так, но мы же с вами стремимся к познанию естественных наук в их чистоте. Пускай зазвучит музыка небесных сфер:

package utils
import "fmt"

// V is a global variable
var V int
// F is a func to ptint us a value of the global variable
func F() {
	fmt.Println("Value of \"V\" is",  V)
}

Вот теперь golint умиротворённо молчит.

Данные комментарии к коду необходимы для инструмента go doc. Поэтому, чем яснее будет ваш код, и чем лучше документирован пакет, тем легче им будет пользоваться как вам самому так и третьим лицам.

Приведём на основе нашего кода простой пример:

Сейчас я выскажу невероятную крамолу, но всё это дело мне очень напоминает веб-фреймворки, где мы подключаем библиотеку и юзаем библиотечный код. Хотя там конечно - не тот размах, и не та харизма!

За сим и закончим теоретическую часть о пакетах. а остальное придёт на практике.

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

PreviousGo - установка, сборкаNextСинтаксис

Last updated 4 years ago

Was this helpful?

Использование golint
Использование go doc