Документация go на русском


golang - Книги, документация, статьи и курсы по Go

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

  • Официальная документация

    • A Tour of Go -- хорошое пошаговое интерактивное руководство, построенное на примерах. Начать можно именно отсюда.
    • How to Write Go Code -- пример разработки простого пакета на Go, в процессе которого можно ознакомиться с организацией кода проекта на Go, а также с инструментарием разработчика.
    • Effective Go -- руководство по написанию чистого, идеоматического кода на Go. Читать обязательно, но после того, как уже есть какое-то представление об языке. Есть краткий пересказ на русском языке, но он, к сожалению, не поддерживается в актуальном состоянии.
    • Frequently Asked Questions - часто задаваемые вопросы по Go.
  • Другие руководства

    • Go by Example -- еще одно неплохое руководство, построенное на примерах.
  • Книги

  • Блоги и статьи

    • The Go Blog -- официальный блог языка.
    • Golang Planet -- агрегатор блог-постов на тему Go.
    • Habrahabr -- хаб по Go на Habrahabr.
  • Библиотеки

    • Awesome Go -- огромный список фрейморков, библиотек и программного обеспечения, написанного на Go, структурированный по темам.
  • Конкурентное программирование

  • Серверное и сетевое программирование

  • Веб-программирование

    • Writing Web Applications -- статья о написании простого веб-приложения.
    • Build Web Application with Golang -- довольно обширное руководство по Веб-программированию на Go; включает в том числе и краткое введение в сам язык.
  • Университетские курсы

    • Go Courses -- список университетских курсов, использующих Go.
  • Материалы на русском языке

    Сюда для удобства также повторно включены русские переводы вышеприведенных материалов

    • Краткий пересказ Effective Go на русском языке -- краткое изложение Effective Go на русском; к сожалению, не обновляется.
    • К. Докси. Введение в программирование на Go -- неплохая обзорная книга для начинающих.
    • М. Саммерфильд. Программирование на языке Go -- одна из первых бумажных книг по Go, довольно неплохая. Русский перевод, к сожалению, не очень качественный. Книга легко находится в электронном виде.
    • Habrahabr -- хаб по Go на Habrahabr.
    • Серия статей (довольно старая) на IBM Developer Works:
      1. Краткий обзор и основы программирования
      2. Разработка Web-приложений
      3. Работа с базами данных
      4. Создание GUI-приложений
    • Ю. Сердюк. Концепции параллелизма Go -- краткое описание концепции конкурентного программирования в Go на русском.
    • [скринкаст] Погружение в Google Go -- вводный курс
    • [скринкаст] Пишем веб-приложение на Go -- вводный курс, где рассматривается использование net/http, MongoDB, Сессий, Авторизации
    • [скринкаст] Программирование на Go -- 9 лекций от Техносферы Mail.ru
    • Алан А.А. Донован, Брайан У. Керниган. Язык программирования Go -- Перевод упомянутой ранее книги. ISBN 978-5-8459-2051-5
    • Батчер Мэтт, Фарина Мэтт. Go на практике -- практики использования Go(на примерах 1.7).

ru.stackoverflow.com

Язык Go для начинающих / Хабрахабр

Цель этой статьи — рассказать о языке программирования Go (Golang) тем разработчикам, которые смотрят в сторону этого языка, но еще не решились взяться за его изучение. Рассказ будет вестись на примере реального приложения, которое представляет из себя RESTful API веб-сервис. Передо мной стояла задача разработать бэкэнд к мобильному сервису. Суть сервиса довольно проста. Мобильное приложение, которое показывает посты пользователей, находящихся рядом с текущим местоположением. На посты пользователи могут оставлять свои комментарии, которые тоже, в свою очередь, можно комментировать. Получается своеобразный гео-форум.

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

Основные преимущества языка Go:

  • Простой и понятный синтаксис. Это делает написание кода приятным занятием.
  • Статическая типизация. Позволяет избежать ошибок, допущенных по невнимательности, упрощает чтение и понимание кода, делает код однозначным.
  • Скорость и компиляция. Скорость у Go в десятки раз быстрее, чем у скриптовых языков, при меньшем потреблении памяти. При этом, компиляция практически мгновенна. Весь проект компилируется в один бинарный файл, без зависимостей. Как говорится, «просто добавь воды». И вам не надо заботиться о памяти, есть сборщик мусора.
  • Отход от ООП. В языке нет классов, но есть структуры данных с методами. Наследование заменяется механизмом встраивания. Существуют интерфейсы, которые не нужно явно имплементировать, а лишь достаточно реализовать методы интерфейса.
  • Параллелизм. Параллельные вычисления в языке делаются просто, изящно и без головной боли. Горутины (что-то типа потоков) легковесны, потребляют мало памяти.
  • Богатая стандартная библиотека. В языке есть все необходимое для веб-разработки и не только. Количество сторонних библиотек постоянно растет. Кроме того, есть возможность использовать библиотеки C и C++.
  • Возможность писать в функциональном стиле. В языке есть замыкания (closures) и анонимные функции. Функции являются объектами первого порядка, их можно передавать в качестве аргументов и использовать в качестве типов данных.
  • Авторитетные отцы-основатели и сильное комьюнити. Роб Пайк, Кен Томпсон, Роберт Гризмер стояли у истоков. Сейчас у языка более 300 контрибьюторов. Язык имеет сильное сообщество и постоянно развивается.
  • Open Source
  • Обаятельный талисман

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

Итак, вернемся к нашей задаче. Хоть язык и не накладывает ограничений на структуру проекта, данное приложение я решил организовать по модели MVC. Правда View реализовывается на стороне клиента. В моем случае это был AngularJS, в перспективе — нативное мобильное приложение. Здесь я расскажу лишь об API на стороне сервиса.

Структура проекта получилась следующая:

/project/ /conf/ errors.go settings.go /controllers/ posts.go users.go /models/ posts.go users.go /utils/ helpers.go loctalk.go

Программа в Go разделяется на пакеты (package), что указывается в начале каждого файла. Имя пакета должно соответствовать директории в которой находятся файлы, входящие в пакет. Так же, должен быть главный пакет main с функцией main(). Он у меня находится в корневом файле приложения loctalk.go. Таким образом, у меня получилось 5 пакетов: conf, controllers, models, utils, main. Буду приводить неполное содержание файлов, а только минимально необходимое для понимания.

Пакет conf содержит константы и настройки сайта.

package conf import ( "os" ) const ( SITE_NAME string = "LocTalk" DEFAULT_LIMIT int = 10 MAX_LIMIT int = 1000 MAX_POST_CHARS int = 1000 ) func init() { mode := os.Getenv("MARTINI_ENV") switch mode { case "production": SiteUrl = "http://loctalk.net" AbsolutePath = "/path/to/project/" default: SiteUrl = "http://127.0.0.1" AbsolutePath = "/path/to/project/" } }

Думаю, комментировать тут нечего. Функция init() вызывается в каждом пакете до вызова main(). Их может быть несколько в разных файлах.

Пакет main.

package main import ( "github.com/go-martini/martini" "net/http" "loctalk/conf" "loctalk/controllers" "loctalk/models" "loctalk/utils" ) func main() { m := martini.Classic() m.Use(func(w http.ResponseWriter) { w.Header().Set("Content-Type", "application/json; charset=utf-8") }) m.Map(new(utils.MarshUnmarsh)) Auth := func(mu *utils.MarshUnmarsh, req *http.Request, rw http.ResponseWriter) { reqUserId := req.Header.Get("X-Auth-User") reqToken := req.Header.Get("X-Auth-Token") if !models.CheckToken(reqUserId, reqToken) { rw.WriteHeader(http.StatusUnauthorized) rw.Write(mu.Marshal(conf.ErrUserAccessDenied)) } } // ROUTES m.Get("/", controllers.Home) // users m.Get("/api/v1/users", controllers.GetUsers) m.Get("/api/v1/users/:id", controllers.GetUserById) m.Post("/api/v1/users", controllers.CreateUser) // … // posts m.Get("/api/v1/posts", controllers.GetRootPosts) m.Get("/api/v1/posts/:id", controllers.GetPostById) m.Post("/api/v1/posts", Auth, controllers.CreatePost) // ... m.Run() }

В самом верху определяется имя пакета. Далее идет список импортируемых пакетов. Мы будем использовать пакет Martini. Он добавляет легкую прослойку для быстрого и удобного создания веб-приложений. Обратите внимание как импортируется этот пакет. Нужно указать путь к репозиторию откуда он был взят. А чтобы его получить, достаточно в консоли набрать команду go get github.com/go-martini/martini

Далее мы создаем экземпляр Martini, настраиваем и запускаем его. Обратите внимание на знак « := ». Это сокращенный синтаксис, он означает: создать переменную соответствующего типа и инициализировать ее. Например, написав a := «hello», мы создадим переменную a типа string и присвоим ей строку «hello».

Переменная m в нашем случае имеет тип *ClassicMartini, именно это возвращает martini.Classic(). * означает указатель, т. е. передается не само значение, а лишь указатель на него. В метод m.Use() мы передаем функцию-обработчик. Этот Middleware позволяет Martini делать определенные действия над каждым запросом. В данном случае, мы определяем Content-Type для каждого запроса. Метод m.Map() же позволяет привязать нашу структуру и использовать ее затем в контроллерах при необходимости (механизм dependency injection). В данном случае, я создал обертку для кодирования структуры данных в формат json.

Тут же мы создаем внутреннюю функцию Auth, которая проверяет авторизацию пользователя. Ее можно вставить в наши роуты и она будет вызываться до вызова контроллера. Эти вещи возможны благодаря Martini. С использованием стандартной библиотеки код получился бы немного другой.

Взглянем на файл errors.go пакета conf.

package conf import ( "fmt" "net/http" ) type ApiError struct { Code int `json:"errorCode"` HttpCode int `json:"-"` Message string `json:"errorMsg"` Info string `json:"errorInfo"` } func (e *ApiError) Error() string { return e.Message } func NewApiError(err error) *ApiError { return &ApiError{0, http.StatusInternalServerError, err.Error(), ""} } var ErrUserPassEmpty = &ApiError{110, http.StatusBadRequest, "Password is empty", ""} var ErrUserNotFound = &ApiError{123, http.StatusNotFound, "User not found", ""} var ErrUserIdEmpty = &ApiError{130, http.StatusBadRequest, "Empty User Id", ""} var ErrUserIdWrong = &ApiError{131, http.StatusBadRequest, "Wrong User Id", ""} // … и т. д.

Язык поддерживает возврат нескольких значений. Вместо механизма try-catch, очень часто используется прием, когда вторым аргументом возвращается ошибка. И при ее наличии, она обрабатывается. Есть встроенный тип error, который представляет из себя интерфейс:

type error interface { Error() string }

Таким образом, чтобы реализовать этот интерфейс, достаточно иметь метод Error() string. Я создал свой тип для ошибок ApiError, который более специфичен для моих задач, однако совместим со встроенным типом error.

Обратите внимание на — type ApiError struct. Это определение структуры, модели данных, которую вы будете использовать постоянно в своей работе. Она состоит из полей определенных типов (надеюсь, вы успели заметить, что тип данных пишется после имени переменной). Кстати, полями могут быть другие структуры, наследуя все методы и поля. В одинарных кавычках `` указаны теги. Их указывать не обязательно. В данном случае они используются пакетом encoding/json для указания имени в выводе json (знак минус «-» вообще исключает поле из вывода).

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

Двигаемся дальше. Определение func (e *ApiError) Error() string означает ни что иное, как метод данной структуры. Переменная e — это указатель на структуру, своего рода self/this. Соответственно вызвав метод .Error() на структуре, мы получим ее поле Message.

Далее мы определяем предустановленные ошибки и заполняем их поля. Поля вида http.StatusBadRequest — это значения типа int в пакете http для стандартных кодов ответа, своего рода алиасы. Мы используем сокращенный синтаксис объявления структуры &ApiError{} с инициализацией. По другому можно было бы написать так:

MyError := new(ApiError) MyError.Code = 110 // …

Символ & означает получить указатель на данную структуру. Оператор new() так же возвращает указатель, а не значение. По-началу возникает небольшая путаница с указателями, но, со временем, вы привыкните.

Перейдем к нашим моделям. Приведу урезанную версию модели постов:

package models import ( "labix.org/v2/mgo/bson" "loctalk/conf" "loctalk/utils" "time" "unicode/utf8" "log" ) // GeoJSON format type Geo struct { Type string `json:"-"` Coordinates [2]float64 `json:"coordinates"` } type Post struct { Id bson.ObjectId `json:"id" bson:"_id,omitempty"` UserId bson.ObjectId `json:"userId"` UserName string `json:"userName"` ThumbUrl string `json:"thumbUrl"` ParentId bson.ObjectId `json:"parentId,omitempty" bson:",omitempty"` Enabled bool `json:"-"` Body string `json:"body"` Geo Geo `json:"geo"` Date time.Time `json:"date" bson:",omitempty"` } func NewPost() *Post { return new(Post) } func (p *Post) LoadById(id string) *conf.ApiError { if !bson.IsObjectIdHex(id) { return conf.ErrPostIdWrong } session := utils.NewDbSession() defer session.Close() c := session.Col("posts") err := c.Find(bson.M{"_id": bson.ObjectIdHex(id), "enabled": true}).One(p) if p.Id == "" { return conf.ErrPostNotFound } if err != nil { return conf.NewApiError(err) } return nil } func (p *Post) Create() (id string, err *conf.ApiError) { // validation switch { case p.UserId == "": err = conf.ErrUserIdEmpty case p.Body == "": err = conf.ErrPostBodyEmpty case utf8.RuneCountInString(p.Body) > conf.MAX_POST_CHARS: err = conf.ErrPostMaxSize case p.Geo.Coordinates[0] == 0.0 || p.Geo.Coordinates[1] == 0.0: err = conf.ErrPostLocationEmpty } if err != nil { return } p.Id = bson.NewObjectId() p.Geo.Type = "Point" p.Enabled = true p.Date = time.Now() session := utils.NewDbSession() defer session.Close() c := session.Col("posts") errDb := c.Insert(p) if errDb != nil { return "", conf.NewApiError(errDb) } return p.Id.Hex(), nil } func (p *Post) Update() *conf.ApiError { session := utils.NewDbSession() defer session.Close() c := session.Col("posts") err := c.UpdateId(p.Id, p) if err != nil { return conf.NewApiError(err) } return nil } func (p *Post) Disable() *conf.ApiError { session := utils.NewDbSession() defer session.Close() p.Enabled = false c := session.Col("posts") err := c.UpdateId(p.Id, p) if err != nil { return conf.NewApiError(err) } return nil } // …

Здесь мы используем замечательный драйвер для MongoDb — mgo, чтобы сохранять данные. Для удобства, я создал небольшую обертку над api mgo — utils.NewDbSession. Логика работы с данными: сначала мы создаем объект во внутренней структуре языка, а затем, с помощью метода этой структуры, сохраняем его в базу данных.

Обратите внимание, что в этих методах мы везде используем наш тип ошибки conf.ApiError. Стандартные ошибки мы конвертируем в наши с помощью conf.NewApiError(err). Так же, важен оператор defer. Он исполняется в самом конце выполнения метода. В данном случае, закрывает соединение с БД.

Что ж, осталось взглянуть на контроллер, который обрабатывает запросы и выводит json в ответ.

package controllers import ( "encoding/json" "fmt" "github.com/go-martini/martini" "labix.org/v2/mgo/bson" "loctalk/conf" "loctalk/models" "loctalk/utils" "net/http" ) func GetPostById(mu *utils.MarshUnmarsh, params martini.Params) (int, []byte) { id := params["id"] post := models.NewPost() err := post.LoadById(id) if err != nil { return err.HttpCode, mu.Marshal(err) } return http.StatusOK, mu.Marshal(post) } // ...

Здесь мы получаем из URL id запрашиваемого поста, создаем новый экземпляр нашей структуры и вызываем на ней метод LoadById(id) для загрузки данных из БД и заполнения данной структуры. Которую мы и выводим в HTTP ответ, предварительно преобразовав в json нашим методом mu.Marshal(post).

Обратите внимание на сигнатуру функции:

func GetPostById(mu *utils.MarshUnmarsh, params martini.Params) (int, []byte) Входные параметры нам предоставляет Martini с помощью механизма внедрения зависимостей (dependency injection). И мы возвращаем два параметра (int, []byte) — число (статус ответа) и массив байт.

Итак, мы разобрали основные компоненты и подходы, используя которые, вы сможете сделать эффективный RESTful API интерфейс в короткие сроки. Надеюсь, статья была полезна и вдохновит некоторых из вас заняться изучением замечательного языка Go. Уверен, за ним будущее.

Для изучения могу порекомендовать хорошую книгу на русском «Программирование на языке Go» Марка Саммерфильда. И, конечно, больше практиковаться.

UPD: Tour Go на русском.

habrahabr.ru

Приступая к работе — Введение в программирование на Go

Программирование — это искусство, ремесло и наука о написании программ, определяющих то, как компьютер будет работать. Эта книга научит вас писать компьютерные программы с использованием языка программирования, разработанного в компании Google, под названием Go.

Go — язык общего назначения с широкими возможностями и понятным синтаксисом. Благодаря мультиплатформенности, надежной, хорошо документированной стандартной библиотеке и ориентированности на удобные подходы к самой разработке, Go является идеальным языком для первых шагов в программировании.

Процесс разработки приложений на Go (и на большинстве других языков программирования) довольно прост:

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

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

Файлы и директории

Файл представляет собой набор данных, хранящийся в блоке с определенным именем. Современные операционные системы (такие как Windows или Mac OS X) состоят из миллионов файлов, содержащих большой объем различной информации — начиная от текстовых документов и заканчивая программами и мультимедиа-файлами.

Файлы определенным образом хранятся в компьютере: все они имеют имя, определенный размер (измеряемый в байтах) и соответствующий тип. Обычно тип файла определяется по его расширению — части имени, которая стоит после последней .. Например, файл, названный hello.txt, имеет расширение txt, а значит содержит текстовую информацию.

Папки (также называемые директориями) используются для группирования нескольких файлов.

Терминал

Большая часть взаимодействия с компьютером сейчас осуществляется с помощью графического пользовательского интерфейса (GUI). Мы используем клавиатуру, мышь, сенсорные экраны для взаимодействия с визуальными кнопками и другими отображаемыми элементами.

Но так было не всегда. Перед GUI в ходу был терминал — простой текстовый интерфейс к компьютеру, где вместо работы с кнопками на экране мы вводили команды и получали ответы.

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

Windows

Чтобы вызвать терминал (командную строку) в Windows, нужно нажать комбинацию клавиш Win+R (удерживая клавишу с логотипом Windows нажмите R), ввести в появившееся окно cmd.exe и нажать Enter. Вы должны увидеть черное окно, похожее на то, что ниже:

По умолчанию командная строка запускается из вашей домашней директории (в моём случае это C:\Users\caleb). Вы отдаёте команды компьютеру, набирая их в этом окне и нажимая Enter. Попробуйте ввести команду dir, которая выводит содержимое текущего каталога на экран. Вы должны увидеть что-то вроде этого:

C:\Users\caleb>dir Volume in drive C has no label. Volume Serial Number is B2F5-F125

Вы можете изменить текущий каталог с помощью команды cd. Например, там наверняка есть директория под названием Desktop. Вы можете посмотреть её содержимое, набрав cd Desktop, а затем dir. Чтобы вернуться в домашнюю директорию, используйте специальное имя .. (две точки): cd ... Одна точка обозначает текущий каталог (известен как рабочая директория), так что cd . ничего не сделает. Конечно, существует намного больше команд, которые можно использовать, но этих будет вполне достаточно для начала.

OSX

В OSX терминал можно найти, перейдя в Finder → Applications → Utilities → Terminal. Вы увидите такое окно:

По умолчанию, командная строка запускается из вашей домашней директории (в моём случае это /Users/caleb). Вы отдаёте команды компьютеру, набирая их в этом окне и нажимая Enter. Попробуйте ввести команду ls, которая выводит содержимое текущего каталога на экран. Вы должны увидеть что-то вроде этого:

caleb-min:~ caleb$ ls Desktop Downloads Movies Pictures Documents Library Music Public

Вы можете изменить текущий каталог с помощью команды cd. Например, там наверняка есть директория под названием Desktop. Вы можете посмотреть её содержимое набрав cd Desktop, а затем ls. Чтобы вернуться в домашнюю директорию, используйте специальное имя .. (две точки): cd ... Одна точка обозначает текущий каталог (известен как рабочая директория), так что cd . ничего не сделает. Конечно, существует намного больше команд, которые можно использовать, но этих будет вполне достаточно для начала.

Текстовый редактор

Основным инструментом программиста при разработке программного обеспечения является текстовый редактор. Текстовые редакторы в целом похожи на программы обработки текста (такие как Microsoft Word или OpenOffice), но в отличие от последних, там отсутствует какое-либо форматирование (полужирный, курсив и т.п.), что делает их ориентированными только на работу с простым текстом. Как в OSX, так и в Windows, по умолчанию уже присутствует встроенные текстовые редакторы. Но они очень ограничены в возможностях, поэтому я бы порекомендовал что-нибудь получше.

Дабы упростить установку, на сайте книги golang-book.com доступен специальный инсталлятор. Он установит Go, необходимые инструменты, текстовый редактор и настроит переменные окружения.

Windows

Для Windows инсталлятор установит текстовый редактор SciTe. Вы сможете найти его в меню Пуск → Все программы → Go → SciTe. После запуска вы должны увидеть такое окно:

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

Вы можете открыть файл, выбрав его в диалоге, находящимся в меню File → Open. Файлы могут быть сохранены с помощью меню File → Save или File → Save As.

Так как подобные действия вы будете выполнять достаточно часто, неплохо было бы узнать сочетания клавиш для быстрого доступа к пунктам меню. Вот самые распространённые из них:

  • Ctrl + S — сохранить текущий файл

  • Ctrl + X — вырезать выделенный текст (удалить его, предварительно сохранив в буфере обмена, для возможной вставки позже)

  • Ctrl + C — скопировать выделенный фрагмент текста в буфер обмена

  • Ctrl + V — вставить текст на место текущего положения курсора из буфера обмена

  • Используйте клавиши со стрелками для навигации по файлу, Home для перехода в начало строки, а End для перехода в конец

  • Удерживайте Shift при использовании клавиш навигации, чтобы выделить фрагмент текста без использования мыши

  • Ctrl + F — открыть диалоговое окно поиска по содержимому файла

OSX

Для OSX установщик поставит редактор Text Wrangler:

Как и Scite на Windows, окно Text Wrangler содержит большую белую область, где вводится текст. Файлы могут быть открыты при помощи File → Open, а сохранены с помощью File → Save или File → Save As. Вот некоторые полезные сочетания клавиш:

  • ⌘ + S — сохранить текущий файл

  • ⌘ + X — вырезать выделенный текст (удалить его, предварительно сохранив в буфере обмена, для возможной вставки позже)

  • ⌘ + C — скопировать выделенный фрагмент текста в буфер обмена

  • ⌘ + V — вставить текст на место текущего положения курсора из буфера обмена

  • Используйте клавиши со стрелками для навигации по файлу

  • ⌘ + F — открыть диалоговое окно поиска по содержимому файла

Инструментарий Go

Go — компилируемый язык программирования. Это означает, что исходный код (написанный вами код) переводится в язык, понятный компьютеру. Поэтому, прежде чем написать первую программу на Go, нужно разобраться с его компилятором.

Инсталлятор установит Go автоматически. Мы будем использовать первую версию языка. (Больше информации можно найти на http://golang.org/)

Давайте убедимся, что всё работает. Откроем терминал и введём там:

В ответ вы должны увидеть что-то вроде:

Ваш номер версии может быть немного другим. Если вы получили ошибку, попробуйте перезагрузить компьютер.

Инструментарий Go состоит из нескольких команд и подкоманд. Список всех доступных команд можно увидеть, набрав:

О том, как их использовать, мы узнаем в следующих главах.

golang-book.ru

Ваша первая программа — Введение в программирование на Go

Традиционно, первая программа, с которой начинается изучение любого языка программирования, называется «Hello World» — эта программа просто выводит в консоль строку Hello World. Давайте напишем её с помощью Go.

Сначала создадим новую директорию, в которой будем хранить нашу программу. Установщик, о котором говорилось в первой главе, создал в вашей домашней директории каталог Go. Теперь создайте директорию под названием ~/Go/src/golang-book/chapter2 (где ~ означает вашу домашнюю директорию). Вы можете сделать это из терминала с помощью следующих команд:

mkdir Go/src/golang-book mkdir Go/src/golang-book/chapter2

Используя текстовый редактор, введите следующее:

package main import "fmt" // this is a comment func main() { fmt.Println("Hello World") }

Убедитесь, что содержимое файла идентично показанному здесь примеру, и сохраните его под именем main.go в созданной ранее директории. Затем откройте новое окно терминала и введите:

cd Go/src/golang-book/chapter2 go run main.go

В окне терминала вы должны увидеть сообщение Hello World. Команда go run берет указанные файлы (разделенные пробелом), компилирует их в исполняемые файлы, сохраняет во временной директории и запускает. Если вы не увидели Hello World, то, вероятно, где-то была допущена ошибка, компилятор подскажет вам, где конкретно. Как и большинство компиляторов, компилятор Go крайне педантичен и не прощает ошибок.

Как читать программу на Go

Теперь давайте рассмотрим программу более детально. Программы на Go читаются сверху вниз, слева направо (как книга). Первая строка гласит:

Это называется «определение пакета». Любая Go программа начинается с определения имени пакета. Пакеты — это подход Go к организации повторного использования кода. Есть два типа программ на Go: исполняемые файлы и разделяемые библиотеки. Исполняемые файлы являются видом программ, которые можно запустить прямо из терминала (в Windows их имя заканчивается на .exe). Библиотеки являются коллекциями кода, который можно использовать из других программ. Детальнее мы будем рассматривать библиотеки чуть позже, а пока просто не забудьте включать эту строку в программы, которые вы пишите.

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

Дальше следует это:

Ключевое слово import позволяет подключить сторонние пакеты для использования их функциональности в нашей программе. Пакет fmt (сокращение от format) реализует форматирование для входных и выходных данных. Учитывая то, что мы только что узнали о пакетах, как вы думаете, что будет содержаться в верхней части файлов пакета fmt?

Обратите внимание, что fmt взят в двойные кавычки. Использование двойных кавычек называется «строковым литералом», который в свою очередь является видом «выражения». Строки в Go представляют собой набор символов (букв, чисел, …) определенной длины. Строки мы рассмотрим детально в следующей главе, а сейчас главное иметь в виду, что за открывающим символом " в конечном итоге должен последовать и закрывающий. Всё, что находится между ними, будет являться строкой (символ " сам по себе не является частью строки).

Строка, начинающаяся с // известна как комментарий. Комментарии игнорируются компилятором Go и служат исключительно пояснениями вам (или тем, кто будет потом читать ваш код). Go поддерживает два вида комментариев: // превращает в комментарий весь текст до конца строки и /* */, где комментарием является всё, что содержится между символами * (включая переносы строк).

Далее можно увидеть объявление функции:

func main() { fmt.Println("Hello World") }

Функции являются кирпичиками программы на Go. Они имеют входы, выходы и ряд действий, называемых операторами, расположенных в определенном порядке. Любая функция начинается с ключевого слова func, за которым следует имя функции (в нашем случае main), список из нуля и более параметров, возвращаемый тип (если есть) и само «тело», заключенное в фигурные скобки. Наша функция не имеет входных параметров, ничего не возвращает и содержит всего один оператор. Имя main является особенным, эта функция будет вызываться сама при запуске программы.

Заключительной частью нашей программы является эта строка:

fmt.Println("Hello World")

Этот оператор содержит три части: во-первых, это доступ к функции пакета fmt под названием Println (Print line), затем создание новой строки, содержащей Hello World, и вызов функции с этой строкой в качестве первого и единственного аргумента.

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

Создается новая исполняемая программа, которая использует библиотеку fmt и содержит функцию main. Эта функция не имеет аргументов, ничего не возвращает и делает следующее: использует функцию Println из библиотеки fmt и вызывает её, передавая один аргумент — строку Hello World.

Функция Println выполняет основную работу в этой программе. Вы можете узнать о ней больше, набрав в терминале команду:

Среди прочей информации вы должны увидеть это:

Println formats using the default formats for its operands and writes to standard output. Spaces are always added between operands and a newline is appended. It returns the number of bytes written and any write error encountered.

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

Сейчас документация говорит нам, что вызов Println пошлет передаваемые ей данные на стандартный вывод — терминал, вы сейчас работаете в нём. Эта функция является причиной, по которой Hello World отображается на экране.

В следующей главе вы поймете, каким образом Go хранит и представляет вещи вроде Hello World с помощью типов.

Задачи

  • Что такое отступ?

  • Что такое комментарий? Какие два способа записи комментариев существуют?

  • Наша программа начиналась с package main. С чего начинаются файлы в пакете fmt?

  • Мы использовали функцию Println из пакета fmt. Если бы мы хотели использовать функцию Exit из пакета os, что бы потребовалось сделать?

  • Измените написанную программу так, чтобы вместо Hello World она выводила Hello, my name is вместе с вашем именем.

golang-book.ru

4gophers | 4gophers.ru

Стриминг и распознавание лиц через веб-камеру
Перевод статьи “Stream and recognise people from a webcam with Go and Facebox”. От видеонаблюдения для предотвращения вторжения до распознавания личности человека за дверью и автоматического открытия дверей. Все это можно сделать с помощью нескольких строк на pyton, Go и используя Facebox. Для начала нам нужно научиться получать видео с веб-камеры. Есть множество вариантов, как это можно сделать с Go. К сожалению, большинство из них тянут за собой CGO биндинги к OpenCV, при этом поддержка функциональности очень ограничена, а сами проекты довольно монструозны.
Анонимизация изображений с помощью Go
Перевод статьи “Anonymising images with Go and Machine Box“ В стандартной библиотеке Go есть достаточное количество мощных инструментов для работы с изображениями. Это пакеты image, image/* и draw. В этом руководстве мы будем использовать эти инструменты совместно с Machine Box Go SDK для цензурирования изображений. В рамках этой статьи мы напишем простую консольную утилиту. Но тот же самый код можно будет использовать, например, для написания веб-приложений. Запускаем Facebox Facebox это один из образов Machine Box который позволяет распознавать лица с помощью алгоритмов машинного обучения.
Сетевые протоколы: Ethernet и Go
Перевод статьи “Network Protocol Breakdown: Ethernet and Go”. Если вы читаете эту статью, то есть очень большая вероятность, что прямо сейчас вы пользуетесь Ethernet (IEEE 802.3) соединением где-то между вашими устройствами и хостингом, на котором размещен этот блог. Семейство Ethernet технологий - это строительные блоки для современных компьютерных сетей. Было бы не плохо разобраться как именно Ethernet работает на физическом уровне, но в этой статье я сфокусируюсь на фреймах Ethernet канального уровня (“Ethernet frames”).
Распределенный поиск Трампа
Перевод статьи “Building a distributed Trump finder”. В этой статье мы будем работать с инструментом для машинного обучения “Machine Box”. Это очень классная штука, и вам обязательно нужно ее попробовать. По своей сути, это набор заранее подготовленных docker контейнеров, готовых к использованию и предоставляющих интерфейс для различных операций связанных с машинным обучением. К примеру, вы можете воспользоваться контейнером “facebox” для распознавания лиц. После запуска этого контейнера, у вас появится доступ к JSON api, которое позволит обучить этот “facebox” на определенных изображениях лиц людей, распознать эти лица на различных изображениях и сохранить “состояние” обученной модели для дальнейшего использования.
Глубинное обучение с нуля в Go - Часть 1: графы
Перевод статьи “Deep Learning from Scratch in Go - Part 1: Equations Are Graphs“ Это первая статья из целого цикла про алгоритмы глубинного обучение. Я постараюсь начать с самых азов и постепенно двигаться к объяснению современных разработкам в этой области. Глубинное обучение, на самом деле, совсем не новомодное изобретение. Сама идея появилась еще в начале 1980х. Но в наше время компьютеры стали значительно мощнее. В этой статье мы начнем разбираться с этой темой, начиная со знакомых вещей, со временем вникая в принципы работы глубинного обучения.
go tool trace
Перевод статьи “go tool trace“ Знаете ли вы как на самом деле работает ваша Go программа? go tool trace может это показать. Этот инструмент при запуске вашей программы визуализирует все события рантайма в довольно удобной форме. Этот инструмент один из самых лучших помощников при поиске проблем с производительностью, параллелизмом и несогласованностью. К сожалению, документации по нему не так много. В своей прошлой статье я упомянул, что мы использовали go tool trace в Pusher для поиска долгих пауз GC.

4gophers.ru

Типы — Введение в программирование на Go

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

Предположим, у вас есть собака по имени Шарик. Тут «Шарик» — это «Собака», этот тип описывает какой-то набор свойств, присущий всем собакам. Наши рассуждения должны быть примерно следующие: у собак 4 лапы, Шарик — собака, значит, у Шарика 4 лапы. Типы данных в языках программирования работают похожим образом: у всех строк есть длина; x — строка, а значит у x есть длина.

В математике мы часто говорим о множествах. Например, ℝ (множество всех вещественных чисел) или ℕ (множество всех натуральных чисел). Каждый элемент этих множеств имеет такие же свойства, как и все прочие элементы этого множества. Например, все натуральные числа ассоциативны - «для всех натуральных чисел a, b и c выполняется: a + (b + c) = (a + b) + c и a × (b × c) = (a × b) × c»; в этом смысле множества схожи с типами данных в языках программирования тем, что все значения одного типа имеют общие свойства.

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

В Go есть несколько встроенных типов данных, с которыми мы сейчас ознакомимся.

Числа

В Go есть несколько различных типов для представления чисел. Вообще, мы разделим числа на два различных класса: целые числа и числа с плавающей точкой.

Целые числа

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

Наша система строится на 10 различных цифрах. Когда мы исчерпываем доступные нам цифры, мы представляем большое число, используя новую цифру 2 (а затем 3, 4, 5, …) числа следуют одно за другим. Например, число, следующее за 9, это 10, число, следующее за 99, это 100 и так далее. Компьютеры делают то же самое, но они имеют только 2 цифры вместо 10. Поэтому, подсчет выглядит так: 0, 1, 10, 11, 100, 101, 110, 111 и так далее. Другое отличие между той системой счисления, что используем мы, и той, что использует компьютер - все типы чисел имеют строго определенный размер. У них есть ограниченное количество цифр. Поэтому четырехразрядное число может выглядеть так: 0000, 0001, 0010, 0011, 0100. В конце концов мы можем выйти за лимит, и большинство компьютеров просто вернутся к самому началу (что может стать причиной очень странного поведения программы).

В Go существуют следующие типы целых чисел: uint8, uint16, uint32, uint64, int8, int16, int32 и int64. 8, 16, 32 и 64 говорит нам, сколько бит использует каждый тип. uint означает «unsigned integer» (беззнаковое целое), в то время как int означает «signed integer» (знаковое целое). Беззнаковое целое может принимать только положительные значения (или ноль). В дополнение к этому существуют два типа-псевдонима: byte (то же самое, что uint8) и rune (то же самое, что int32). Байты — очень распространенная единица измерения в компьютерах (1 байт = 8 бит, 1024 байта = 1 килобайт, 1024 килобайта = 1 мегабайт, …), и именно поэтому тип byte в Go часто используется для определения других типов. Также существует 3 машинно-зависимых целочисленных типа: uint, int и uintptr. Они машинно-зависимы, потому что их размер зависит от архитектуры используемого компьютера.

В общем, если вы работаете с целыми числами — просто используйте тип int.

Числа с плавающей точкой

Числа с плавающей точкой — это числа, которые содержат вещественную часть (вещественные числа) (1.234, 123.4, 0.00001234, 12340000). Их представление в компьютере довольно сложно и не особо необходимо для их использования. Так что мы просто должны помнить:

  • Числа с плавающей точкой неточны. Бывают случаи, когда число вообще нельзя представить. Например, результатом вычисления 1.01 - 0.99 будет 0.020000000000000018 - число очень близкое к ожидаемому, но не то же самое.

  • Как и целые числа, числа с плавающей точкой имеют определенный размер (32 бита или 64 бита). Использование большего размера увеличивает точность (сколько цифр мы можем использовать для вычисления)

  • В дополнение к числам существуют несколько других значений, таких как: «not a number» (не число) (NaN, для вещей наподобие 0/0), а также положительная и отрицательная бесконечность (+∞ и −∞).

В Go есть два вещественных типа: float32 и float64 (соответственно, часто называемые вещественными числами с одинарной и двойной точностью). А также два дополнительных типа для представления комплексных чисел (чисел с мнимой частью): complex64 и complex128. Как правило, мы должны придерживаться типа float64, когда работаем с числами с плавающей точкой.

Пример

Давайте напишем программу-пример, использующую числа. Во-первых, создайте папку «chapter3» с файлом main.go внутри со следующим содержимым:

package main import "fmt" func main() { fmt.Println("1 + 1 = ", 1 + 1) }

Если вы запустите программу, то должны увидеть это:

$ go run main.go 1 + 1 = 2

Заметим, что эта программа очень схожа с программой, которую мы написали в главе 2. Она содержит ту же строку с указанием пакета, ту же строку с импортом, то же определение функции и использует ту же функцию Println. В этот раз вместо печати строки Hello World мы печатаем строку 1 + 1 = с последующим результатом выражения 1 + 1. Это выражение состоит из трех частей: числового литерала 1 (который является типом int), оператора + (который представляет сложение) и другого числового литерала 1. Давайте попробуем сделать то же самое, используя числа с плавающей точкой:

fmt.Println("1 + 1 =", 1.0 + 1.0)

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

В дополнение к сложению, в Go имеется несколько других операций:

Литерал Пояснение
+ сложение
- вычитание
* умножение
/ деление
% остаток от деления

Строки

Как мы видели в главе 2, строка — это последовательность символов определенной длины, используемая для представления текста. Строки в Go состоят из независимых байтов, обычно по одному на каждый символ (символы из других языков, таких как китайский, представляются несколькими байтами).

Строковые литералы могут быть созданы с помощью двойных кавычек "Hello World" или с помощью апострофов `Hello World`. Различие между ними в том, что строки в двойных кавычках не могут содержать новые строки и они позволяют использовать особые управляющие последовательности символов. Например, \n будет заменена символом новой строки, а \t - символом табуляции.

Распространенные операции над строками включают в себя нахождение длины строки len("Hello World"), доступ к отдельному символу в строке "Hello World"[1], и конкатенацию двух строк "Hello " + "World". Давайте модифицируем созданную ранее программу, чтобы проверить всё это:

package main import "fmt" func main() { fmt.Println(len("Hello World")) fmt.Println("Hello World"[1]) fmt.Println("Hello " + "World") }

На заметку:

  • Пробел тоже считается символом, поэтому длина строки 11 символов, а не 10 и третья строка содержит "Hello " вместо "Hello".

  • Строки “индексируются” начиная с 0, а не с 1. [1] даст вам второй элемент, а не первый. Также заметьте, что вы видите 101 вместо e, когда выполняете программу. Это происходит из-за того, что символ представляется байтом (помните, байт — это целое число).

    Можно думать об индексации так: "Hello World" 1. Читайте это так: «строка Hello World позиция 1», «на 1 позиции строки Hello World» или «второй символ строки Hello World».

  • Конкатенация использует тот же символ, что и сложение. Компилятор Go выясняет, что должно происходить, полагаясь на типы аргументов. Если по обе стороны от + находятся строки, компилятор предположит, что вы имели в виду конкатенацию, а не сложение (ведь сложение для строк бессмысленно).

Логические типы

Булевский тип (названный так в честь Джорджа Буля) — это специальный однобитный целочисленный тип, используемый для представления истинности и ложности. С этим типом используются три логических оператора:

Литерал Пояснение
&& И
|| ИЛИ
! НЕ

Вот пример программы, показывающей их использование:

func main() { fmt.Println(true && true) fmt.Println(true && false) fmt.Println(true || true) fmt.Println(true || false) fmt.Println(!true) }

Запуск этой программы должен вывести:

$ go run main.go true false true true false

Используем таблицы истинности, чтобы определить, как эти операторы работают:

Выражение Значение
true && true true
true && false false
false && true false
false && false false
Выражение Значение
true || true true
true || false true
false || true true
false || false false
Выражение Значение
!true false
!false true

Всё это — простейшие типы, включенные в Go и являющиеся основой, с помощью которой строятся все остальные типы.

Задачи

  • Как хранятся числа в компьютере?

  • Мы знаем, что в десятичной системе самое большое число из одной цифры - это 9, а из двух - 99. В бинарной системе самое большое число из двух цифр это 11 (3), самое большое число из трех цифр это 111 (7) и самое большое число из 4 цифр это 1111 (15). Вопрос: каково самое большое число из 8 цифр? (Подсказка: 101-1=9 и 102-1=99)

  • В зависимости от задачи вы можете использовать Go как калькулятор. Напишите программу, которая вычисляет 32132 × 42452 и печатает это в терминал (используйте оператор * для умножения).

  • Что такое строка? Как найти её длину?

  • Какое значение примет выражение (true && false) || (false && true) || !(false && false)?

golang-book.ru

Documentation - The Go Programming Language

The Go programming language is an open source project to make programmers more productive.

Go is expressive, concise, clean, and efficient. Its concurrency mechanisms make it easy to write programs that get the most out of multicore and networked machines, while its novel type system enables flexible and modular program construction. Go compiles quickly to machine code yet has the convenience of garbage collection and the power of run-time reflection. It's a fast, statically typed, compiled language that feels like a dynamically typed, interpreted language.

Installing Go

Getting Started

Instructions for downloading and installing the Go compilers, tools, and libraries.

Learning Go

A Tour of Go

An interactive introduction to Go in three sections. The first section covers basic syntax and data structures; the second discusses methods and interfaces; and the third introduces Go's concurrency primitives. Each section concludes with a few exercises so you can practice what you've learned. You can take the tour online or install it locally with:

$ go get golang.org/x/tour/gotour This will place the gotour binary in your workspace's bin directory.

How to write Go code

Also available as a screencast, this doc explains how to use the go command to fetch, build, and install packages, commands, and run tests.

Editor plugins and IDEs

A document that summarizes commonly used editor plugins and IDEs with Go support.

Effective Go

A document that gives tips for writing clear, idiomatic Go code. A must read for any new Go programmer. It augments the tour and the language specification, both of which should be read first.

Frequently Asked Questions (FAQ)

Answers to common questions about Go.

The Go Wiki

A wiki maintained by the Go community.

More

See the Learn page at the Wiki for more Go learning resources.

References

Package Documentation

The documentation for the Go standard library.

Command Documentation

The documentation for the Go tools.

Language Specification

The official Go Language specification.

The Go Memory Model

A document that specifies the conditions under which reads of a variable in one goroutine can be guaranteed to observe values produced by writes to the same variable in a different goroutine.

Release History

A summary of the changes between Go releases.

Articles

The Go Blog

The official blog of the Go project, featuring news and in-depth articles by the Go team and guests.

Codewalks

Guided tours of Go programs.

Language
Packages
Tools
More

See the Articles page at the Wiki for more Go articles.

Talks

A Video Tour of Go

Three things that make Go fast, fun, and productive: interfaces, reflection, and concurrency. Builds a toy web crawler to demonstrate these.

Code that grows with grace

One of Go's key design goals is code adaptability; that it should be easy to take a simple design and build upon it in a clean and natural way. In this talk Andrew Gerrand describes a simple "chat roulette" server that matches pairs of incoming TCP connections, and then use Go's concurrency mechanisms, interfaces, and standard library to extend it with a web interface and other features. While the function of the program changes dramatically, Go's flexibility preserves the original design as it grows.

Go Concurrency Patterns

Concurrency is the key to designing high performance network services. Go's concurrency primitives (goroutines and channels) provide a simple and efficient means of expressing concurrent execution. In this talk we see how tricky concurrency problems can be solved gracefully with simple Go code.

Advanced Go Concurrency Patterns

This talk expands on the Go Concurrency Patterns talk to dive deeper into Go's concurrency primitives.

More

See the Go Talks site and wiki page for more Go talks.

Non-English Documentation

See the NonEnglish page at the Wiki for localized documentation.

golang.org


Смотрите также