Go — простой язык для серьезных задач


Содержание

Язык программирования Go: мнения и перспектива

Введение

Go – это язык программирования, который был разработан корпорацией Google. Часто его еще называют “Golang” – сокращение от “Google language”. Это компилируемый и многопоточный язык, релиз которого состоялся в ноябре 2009 года, а самый свежий выпуск 1.6 датируется февралем 2020 года. Одной из ключевых фигур, которые принимали участие в создании Go, является Роб Пайк, известный разработчик языков программирования, а также операционных систем, в данный момент работающий в Google. Выступая на одной из конференций, он отметил, что язык Go – это попытка перенять лучшие стороны таких языков, как C++ и Java.

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

Применение

Язык Go разрабатывался как язык для создания различных высокоэффективных программ, однако большинство программистов сходятся во мнении, что лучше всего он подходит для создания веб-приложений (в качестве back-end). При этом Go дает возможности писать и другие проекты, к примеру, Docker, InfluxDB и Kubernetes. По сути, применение языка Go ограничивается тремя основными направлениями: сетевое программное обеспечение, консольные утилиты и бэкенд.

Одной из отличительных особенностей языка является оригинальная система типов: в языке отсутствует наследование (один из принципов объектно-ориентированного программирования). Также в Go используется сокращенный синтаксис определения переменных и синтаксис анонимных функций.
Еще одна особенность этого языка – параллелизм, который заключается в том, что любая функция может быть выполнена одновременно с другой.

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

Плюсы языка Go

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

Во-первых, это его простота. Язык Go разрабатывался в качестве замены C: его высокая производительность почти сопоставима с языком Си, но более простой синтаксис дает возможность разрабатывать приложения гораздо быстрее (к примеру, как на Python). При этом многие разработчики изучают этот язык после Python или PHP либо используют два языка в связке (Python/Go и PHP/Go). Упрощенный синтаксис облегчает не только написание своего собственного кода, но и чтение кода, написанного другими программистами, что особенно важно в командной работе. Эта особенность Go, в свою очередь, ведет к другому важному факту: быстрое освоение Go позволяет перевести внимание с изучения самого языка на изучение программирования в целом.

Программисты постоянно сравнивают язык Go с другими языками: в его пользу свидетельствует тот факт, что, к примеру, в PHP существует 67 ключевых слов, а в Go их всего лишь 25.

Тут необходимо сделать отступление и сказать о том, что желание создать простой язык программирования родилось у разработчиков Google неслучайно: изначально они задумывали Go как быстро изучаемый язык, который запросто могут выучить несколько не очень опытных программистов для того, чтобы затем вместе писать какое-нибудь приложение. Именно поэтому некоторые считают язык Go языком, пригодным для больших корпораций, где в разработке продуктов будет участвовать множество разных людей. Как уже было замечено выше, простой и понятный синтаксис ведет к тому, что программистам Go не нужно вводить какие-то другие стандарты, обозначения или комментарии – они и без этого отлично поймут код друг друга. Многословность Go радует одних разработчиков и огорчает других, но именно благодаря ей код Go читается так легко.

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

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

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

Нельзя не отметить и четкую направленность языка Go: в отличие от PHP, на котором пишут большие проекты, Go больше предназначен для некрупных сервисов, которые необходимо быстро написать и внедрить, но которые должны отличаться чрезвычайной надежностью (так называемое robust software).

Развертка Go-приложения также выглядит намного проще, чем развертка приложения, написанного на PHP. Программируя на Go, вы можете создать артефакты для всех операционных систем или архитектур процессора, вам не нужно будет устанавливать Go на используемые вами сервера.

Синтаксис Go может быть непривычен тем, кто до этого программировал на PHP или Python. Если рассматривать код Go в сравнении с PHP, то Go не имеет объектов или классов, зато в нем есть структура, а точнее тип, который содержит именованные поля:

Еще одной причиной, по которой Go завоевывает все большую популярность, является наличие go fmt – инструмента, который помогает стандартизировать код. А использование go vet поможет вам найти возможные проблемы в коде. Иными словами, авторы языка Go попытались максимально упросить задачу разработки приложений на этом языке, особенно для новичков.

Именно поэтому многие на данный момент считают Go одним из лучших языков программирования и советуют изучать его не только студентам, но и школьникам. Кстати, такой прецедент уже был: учитель научил несколько 11-летних школьников писать и разбираться в коде на таком уровне, что они смогли написать генератор фракталов Мандельброта. А главное, для этого ему понадобилось всего 12-13 часов!

Минусы языка Go

В качестве негативной стороны Go часто называют его малую на данный момент распространенность – действительно, есть куда более распространенные языки программирования, которые используются для выполнения большинства задач. Значит ли это, что изучать Go не стоит? Совсем нет. Существует множество корпораций, которые используют язык Go в своих разработках. В первую очередь это, конечно же, Google Inc., а также Basecamp, BBC Worldwide, Canonical, DigitalOcean, Dropbox, eBay, Yahoo и многие другие компании по всему миру. Поэтому перспективы у этого языка программирования точно есть. Безусловно, программисты Go могут быть менее востребованы, чем, к примеру, PHP-разработчики, однако и конкуренция ниже, а значит, выше шанс найти интересную и хорошо оплачиваемую работу.

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

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

Вывод

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

Пишем первый проект на Golang

Пару месяцев назад я начал писать на Go так же известным, как Golang. И не только из-за их потрясающего логотипа. Основная причина была в том, что я хотел, чистую железяку на моем Raspberry Pi, а так же кроссплатформенность в паре с легкостью установки. Среди других причин были простота создания на Go асинхронного кода с помощью Go методов и уникальный подход к синхронизации каналов между подпрограммами (потоками) посредствам go routines.

С тех пор, как GO был выпущен в 2012 году, я много читал о нем и что ж, пришло время по-настоящему замарать руки и попробовать использовать его для своих задач.

Однако любопытно, продолжим .

Что же из себя представляет GO?

Go — это опен сорсный язык программирования , который позволяет легко создавать простое, надежное и эффективное программное обеспечение. Разрабатывался он внутри компании Google и на 2020 год уже являлся одним из самых быстроразвивающихся и адаптированных языков программирования. Первый релиз языка появился в марте 2012 года. А не так давно, начиная с выпуска Go 1.11, у него появилась поддержка модулей и управлять зависимостями стало немного удобнее.

Необходимые настройки среды

Для начала нужно все правильно настроить. Есть простой способ установить мою библиотеку с помощью Chocolatey.

В Windows мы используем Chocolatey в Powershell для установки Go и vscode…

С установленным Go и vscode у нас есть все, что нужно для начала.

Так как я использую Git bash на все случаи жизни, я запускаю следующую команду Visual Studio Code из Git Bash, чтобы установить go расширение. Если хотите, вы можете просто установить расширение из самого vscode.

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

Где найти отличные ресурсы и материалы по GO?

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

Создаем первый проект

Для того, чтобы начать на Go новый проект, мы сначала создаем пустую папку. Затем мы прописываем в этой папке команду go modules init, чтобы инициализировать модули Go. Модули используются для зависимостей.

Синтаксис

В Go мы определяем функцию, используя ключевое слово func.

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

Все переменные, функции, структуры, которые начинаются с верхнего регистра в Go являются публичными. А все переменные, функции, структуры, начинающиеся со строчной буквы, являются частными. Кроме того, как вы наверное уже заметили в примере, определения типов идут за именем переменной. Поместив оператор импорта поверх файла вы можете импортировать все необходимые пакеты. И последнее, но не менее важное: каждая программа go должна иметь хотя бы один main пакет.

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

Вперед, в бой!

Теперь у нас есть пустой проект, и к тому же мы уже немного знаем о синтаксисе, чтож, начнем! Открываем эту папку в vscode.

Сначала мы добавляем новый файл в нашу папку, называем ее main.go . Затем добавим тот код, который мы рассмотрели выше.

Теперь с помощью этого кода мы можем запустить наше приложение. Используя следующую команду в командной строке.

Можете также прогнать этот код в Go playground.

Тестирование

Чтобы добавить тесты в go, просто добавьте файл main_test.go. Добавим функцию проверяющую метод sayHi. Сигнатура методов тестирования всегда ДОЛЖНА быть TestXxx(t *testing.T). Первый X всегда должен быть в верхнем регистре.

Вы наверняка заметили что то новое в этом коде. Мы используем сокращение для присвоения значений переменной: =. Если функция sayHi не возвращает ожидаемое нами значение, мы выдадим ошибку с хорошим понятным сообщением.

Теперь, чтобы запустить наш тест, мы сделаем в командной строке следующее. Обратите внимание, что я запускаю все тесты из всех файлов и подпапок в моем проекте таким способом ./.

Пожалуйста, не бойтесь пробовать, изменяйте реализацию, и снова запустите тест, чтобы увидеть, как тесты пройдут неудачно. Для запуска с code coverage запустите такие тесты.

Чтобы подробнее ознакомится, пожалуйста, читайте документацию о testing package.

Компилируем и выполняем

Самым простым способом создать исполняемый файл будет:

Это команда создаст нам исполняемый файл Windows, как будто мы на Windows. Вы можете просто вызвать исполняемый файл и увидеть тот же результат, что мы имели при вызове go run main.go. Если мы хотим получить более подробный вывод и посмотреть, что происходит за под капотом, можно использовать -x опцию -в go build. А как нам скомпилировать один и тот же код для Linux или Raspberry Pi?

Чтобы запустить этот бинарник в Linux, не забудьте использовать chmod +x, а затем просто вызвать с помощью ./hello-world

Raspberry Pi 3 имеет архитектуру ARM v7, которую можно скомпилировать следующим образом. ПРИМЕЧАНИЕ: все это мы можем сделать с Windows.

Для запуска бинарника сделайте все то же самое, что и на любом другом компьютере с Linux chmod +x, а затем ./hello-world для запуска вашего приложения.

Резюмируя

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

И последнее, но не менее важное: я хотел бы поделиться с вами своим первым приложением на Go. Это интеграция с термостатом Nest, который я запускаю на своем Raspberry Pi, чтобы собрать данные о температуре и отобразить их в хорошем веб-приложении на React. Только не забудьте зарегистрироваться в рабочем пространстве Gophers Slack.

Стоит ли браться полному новичку за язык Go?

Здравствуйте! Для новичков, которые вообще не программировал ни разу, ни на каких языках, стоит ли браться за язык Go? Я хотел освоить язык Си, но, книга которую я читал неудовлетворил меня, до половины прочёл и заброисил это дело, уж очень сложно там написано. Это Стивен Прат, Язык программирования C. Лекции и упражнения, 5-е издание (2013). И разачарован в языке Си. А теперь немного погуглив, нашёл язык Go, что, мол он тоже почти похож как Си, но только легкий для освоения. Посоветуйте как поступить в моём случае? Цели мои: понять, вообще что такое программирование, и сделать крепкую опору изучив один язык, мог понимать другие языки.

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

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

Стивен Прат, Язык программирования C. Лекции и упражнения, 5-е издание (2013)

Если ты новичок, учи максимально востребованные в индустрии языки. Это C++, Java, PHP и Javascript. Конкретный выбор зависит от предпочтений области, в которой хочешь работать.

Но мой тебе совет, если есть альтернатива беги ты от этого программирования, пока не поздно.

Не стоит брать Golang

Для новичков, которые вообще не программировал ни разу, ни на каких языках, стоит ли браться за язык Go?

Не стоит. Язык подходит только для web’a, и то не совсем. Хайп вокруг него — сильно раздут Google, которая создавала язык для того, чтобы не профильные программисты (программисты python) могли писать сложные системы, не переучиваясь на Java, C++, Erlang, Rust, etc.

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

Берите K&R. Лучшая книга по Си и для начала очень подходит. Всё просто, понятно, без особых сложностей. Хотя простите за вопрос, а зачем вам вообще в программирование? Какие задачи хотите решать?

Это Стивен Прат, Язык программирования C. Лекции и упражнения, 5-е издание (2013).

Хорошая книга. Скорее всего читали просто копипастой примеров, поэтому не поняли.

Простите, почему? Я занимаюсь программирование уже больше -дцати лет и не могу сказать, что Си язык плохой или что-то в нем может разочаровать.

А теперь немного погуглив, нашёл язык Go, что, мол он тоже почти похож как Си, но только легкий для освоения.

Ничем не похож. Он ближе к Python, находится выше на уровне абстракции. Единственные общие вещи — это фигурные скобочки и возможность работы с памятью. Всё, на этом схожесть кончается. И нет, Golang не сможет заменить Pure C. Особенно для понимания работы самого компьютера.

Посоветуйте как поступить в моём случае? Цели мои: понять, вообще что такое программирование, и сделать крепкую опору изучив один язык, мог понимать другие языки.

  • Два раза подумать, правда ли интересно программирование. Быть может это вообще не ваше. Зачем вам эта профессия?
  • Взять K&R, прочитать. Написать что-то простое для себя. К примеру — файловый менеджер или тетрис.
  • Подумать куда идем, — вебота или декстоп.
  • Если выбота
    • Берем HTML, за неделю осваиваем разметку
    • Берем CSS, за вторую неделю осваиваем вёрстку (все это не так глубоко, но для старта хватит).
    • Берем JavaScript — осознаем как работать с DOM на уровне сервера
    • Параллельно — читаем что такое протокол HTTP и зачем о нужен (спецификацию понять можем, ведь мы до этого уже немного изучили Си и азы системного программирования)
    • Берем NodeJS/ES6 (тот же JavaScript, только уже на уровне сервера) + фреймворк вроде Express. Делаем серверную часть. В качестве БД — MongoDB.
    • Берем для frontend какой-нибудь фреймворк. Polymer и React выглядят лучше всего. Если хочется больше строгости — Ember (на самом деле я бы даже советовал его — пересесть на что-то после него очень просто и быстро можно).
    • Опционально повторяем последние два шага для Python3 + Django, Ruby + Rails, PHP + Laravel || Yii.
    • Паралельно с NodeJS разбираем SICP. Язык — Racket.
    • Далее — читаем про нагруженные сервисы и паттерны их построения. С NodeJS можно пересесть на Rust, Erlang или Java/Clojure для таких задач. Хотя и NodeJS хватит.
    • Опционально — изучаем Electron, чтобы писать декстоп приложения на том же стеке.
    • В процессе — читаем умные книги, вроде «Совершенный код», «Жемчужины программирования», «Искусство программирования» и т.п.
  • Если декстоп:
    • Берем учебник Юрова по Assembler, читаем, делаем простые примеры под DOS. Наша задача понять как оно работает на уровне железа.
    • Изучаем паттерны ООП и берем Java (ынтерпрайз и кросплатформ), C# (оффтопик) или С++/Qt (кроссплатформ, больше юниксово).
    • Не верим в то, что на интерпретируемых языках можно написать нормальное приложение для бизнеса. Исключение — платформы вроде Electron или QML, которые изначально заточены под это. Пока веберы начинают зарабатывать на доширак — переходим к написанию простой утилиты. Желательно что-то вроде морды к БД, 100500 файлового менеджера или тетриса.
    • Читаем SICP, изучаем Rust, D. Осознаем почему Golang ушел в веботу.
    • Решаем какая из платформ мамонтов будет нашей — .NET, JVM, Qt. Остальное не нужно практически работодателю. Чаще всего нужно первое.
    • Изучаем Haskell, постигаем дзен ФП. Потом пробуем ФП язык под нашу платформу.
    • Изучаем Racket/Common Lisp — осознаем, что другие языки не нужны. Плачем, что он не применяется практически и дальше идем грызть ынтерпрайзный кактус.
    • Изучаем TCL, осознаем почему продажа ЛСД в промышленных масштабах — это плохо, почему язык не стал популярным и почему кроме TCL вообще больше ничего не нужно. Материмся, что Тк такой страшный.
    • Изучаем Smalltalk и понимаем: а) ООП нигде нормально, кроме него не реализовано; б) плачем что он в рашке не популярен; в) мечтаем работать на нем и продолжаем работать на.
    • Изучаем параллельно книги по паттернам. Перечислены примеры в веботе.

По моему самый лучший выбор для новичка.

Крайне не соглашусь. Для новичка лучше роадмеп с изучение азов. Golang хорош для того, чтобы быстро налабать асинхронный сервер на компилируемом языке, если до этого занимался скриптотой. Так — он травмирует понимание ООП и ФП очень на долго. О системном программировании я вообще молчу.

Недавно сам учил. За 3 часа выучил до базового уровня (Вот сайт), за 2 дня написал многопоточное приложение для собственных нужд(несколько раз гуглил некоторые вещи).

Это плюс для тех кто знает хоть что-то. ТС — нуб.

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

Ключевое — «из которых я учил». Это а ТС вообще ничего не знает по матчасти. Си — тут лучший выбор и от него никуда не уйти.

А почему именно C? По моему это достаточно плохой выбор для начала.

А что лучше для понимания системщины, если не Си? Да и язык простой + служит параметром естественного отбора для тех, кому лучше не быть в профессии.

Когда я учил C, я знал только Pascal, Basic и Assembler, и среди этих 4 языков мне больше pascal понравился(хотя и он не ахти).

Может поэтому и нравится Golang, т.к. он все же ближе к ML, виртовским языкам и алголоподобным, нежели к c-family?

Go подойдет что узнать, что такое програмирование.

Т.е. вы считаете, что надо давать новичку сразу асинхронщину и урезанное представление ООП и ФП?

Помоему сейчас нет ни одного языка, изучив который ты сможешь легко понимать все другие языки. Вожмоно я ошибаюсь, но по моему чтобы понимать другие языки нужно изучить примерно следущий список: Assembler, C, Java, Haskell, Python, Forth, Lisp, JavaScript.

Список плюсую. Согласен. Заметьте, рекомендуемый вами же Golang вы сюда не включили)

Для новичка лучше роадмеп с изучение азов.

Так — он травмирует понимание ООП и ФП очень на долго. О системном программировании я вообще молчу.

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

Это плюс для тех кто знает хоть что-то. ТС — нуб.

Это был всего лишь показатель простоты языка, например тут python предлагали, так у меня на его изучение(до такого же уровня) ушло около 8 часов.

Ключевое — «из которых я учил». Это а ТС вообще ничего не знает по матчасти. Си — тут лучший выбор и от него никуда не уйти.

По моему C тут один из худших, но возможных вариантов. Выше вероятность сделать ошибку, нет сборщика мусора. К тому же сами себе противоречите перейти на ООП и ФП с C куда тяжелее, нет ни интерфейсов, ни методов. Да для изучения системного программирования подходит лучше, но системное программирование это вообще ни тема для новичка.

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

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

Может поэтому и нравится Golang, т.к. он все же ближе к ML, виртовским языкам и алголоподобным, нежели к c-family?

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

Т.е. вы считаете, что надо давать новичку сразу асинхронщину

Если ассинхронщина в таком виде как они имеется в Go, то почему нет ? Я Go из-за неё и выучил, она здесь предельно простая и удобная.

и урезанное представление ООП и ФП?

Когда человек захочет перейти на ООП или ФП, ему будет многое уже знакомо и понятно.

Список плюсую. Согласен. Заметьте, рекомендуемый вами же Golang вы сюда не включили)

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

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

Парадигмы — не специфичные вещи. Без их знания не будет понимания что человек делает. А для обучения алгоритмов (если вы про это) хватит по заглаза и Fortran, только он в жизни мало пригодится. Да даже как анонимус говорил — Васик подойдет, причем больше того же Golang — не будет непонятных лишних сущностей.

На понимание ООП и ФП уверен изучение Go особо ни как не повлияет

Еще как. Хотя бы возьмите представление ООП по А.Кею и то подобие, которое есть в Golang. В свое время мой знакомый так по С++ учил ООП, так до сих пор считает, что С++ эталон реализации ООП. И плевать, что Simula — не была полноценным ООП.

говорю как человек начинавший с изучения Basic на ZX SPectrum, я без проблем понял идеи и ООП и ФП и использовал их на практике в Delphi и Haskell.

А сколько перед этим была практика?

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

А потом получаются программы, которые весят 2 гига. Или казусы — вон у меня коллега недавно выдал, что VM для JavaScript нет, а NodeJS исполняется прямо в браузере его. Вся серверная логика. И поэтому не безопасна. Т.к. любой человек может ее посмотреть. А почему? Человек просто не понимает разницы между интерпретацией, компиляцией в натив и компиляцией в байт-код. И то где он исполняется. А это уже системный уровень.

Это был всего лишь показатель простоты языка, например тут python предлагали, так у меня на его изучение(до такого же уровня) ушло около 8 часов.

А сколько до этого языков было? Когда мне надо было пересесть на Rust я его часов за 12 усвоил на базовом уровне. Но это не значит, что «ржавчина» простая. Скорее просто то, что я с подобными языками уже сталкивался.

По моему C тут один из худших, но возможных вариантов. Выше вероятность сделать ошибку, нет сборщика мусора.

Все это скорее плюсы. Человек поймет как работет память и сделает ошибки эникея.

К тому же сами себе противоречите перейти на ООП и ФП с C куда тяжелее, нет ни интерфейсов, ни методов.

Нисколько. В Pure C нет ни ФП, ни ООП. Поэтому извратить понимание этих парадигм он не может.

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

Как можно быть программистам не понимая как работает конечный автомат? Потом появляются «программисты», которые плодят по 50 переменных на каждый чих, думаю что они память не будут занимать.

А кто вас назначил решателем кому в профессии место, а кому нет?

Меня — никто. А вот возможность освоить сложный инструмент — показатель. Не можешь освоить — лучше занимайся чем-нибудь другим. Где вреда не будет. Не можешь выучить Pure C — нечего делать в программистах.

Если именно как специальность — пусть работодатель решает кто ему нужен, профессионал за дорого, или быдлокодер за дешево.

А потом после быдлокодера поддерживать код. И дописывать. И рефакторить. А все почему? Потому что работадатель думал, что нанимает джуна, который способен учиться. А не племенного быдлокодера, который на все изобретает костыли и велосипеды.

Если речь просто о написания программ, то кто вам запрещает не использовать школопрограмки вместо профессиональных решений?

Человек решил попробовать программирование, явно не в качестве увлечения. Для школопрограм хватит и Lazarus.

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

Если не секрет — по каким? Всегда было интересно чем мотивируются люди выбирая Golang и Python вместо нормальных языков программирования.

Если ассинхронщина в таком виде как они имеется в Go, то почему нет ? Я Go из-за неё и выучил, она здесь предельно простая и удобная.

Спрошу просто — зачем Golang, если есть Erlang и Elixir? + простота не всегда хорошо. Она не стимулирует разбираться в матчасти.

Когда человек захочет перейти на ООП или ФП, ему будет многое уже знакомо и понятно.

Сравните подобие ООП Golang и то, что описывал А.Кей. Где легче то будет? По ФП — аналогично. Не вижу чем будет от Golang легче в том же хацкеле, если не монадами во все места.

Цукерберг рекомендует:  Школа - Высшее образование Нужно или нет


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

А я бы сказал — что он отвратительная комбинация из нормальных идей. Хуже только Python. Нет, я не спорю — языки можно применять для достижения бизнес-целей. Но учить по ним. обрекать человека на быдлокод изначально.

Введение в язык Go

Что такое Go

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

Работа над языком Go началась в 2007 в недрах компании Google. Одним из авторов является Кен Томпсон, который, к слову, является и одним из авторов языка Си (наряду с Денисом Ритчи). 10 ноября 2009 года язык был анонсирован, а в марте 2012 года вышла версия 1.0. При этом язык продолжает развиваться. Текущей версией на момент написания данной статьи является версия 1.12, которая вышла в феврале 2020 года.

Язык Go развивается как open source, то есть представляет поект с открытым исходным кодом, и все его коды и компилятор можно найти и использовать бесплатно. Официальный сайт проекта — https://golang.org, где можно много полезной информации о языке.

Go является кроссплатформенным, он позволяет создавать программы под различные операционные системы — Windows, Mac OS, Linux, FreeBSD. Код обладает переносимостью: программы, написанные для одной из этих операционных систем, могут быть легко с перекомпиляцией перенесены на другую ОС.

Основные особенности языка Go:

компилируемый — компилятор транслирует программу на Go в машинный код, понятный для определенной платформы

присутствует сборщик мусора, который автоматически очищает память

поддержка работы с сетевыми протоколами

поддержка многопоточности и параллельного программирования

В настоящее время Go находит широкое применение в различных сферах. В частности, среди известных проектов, которые применяют Go, можно найти следующие: Google, Dropbox, Netflix, Kubernetes, Docker, Twitch, Uber, CloudFlare и ряд других.

Что нужно для работы с Go? Прежде всего необходим текстовый редактор для набора кода и компилятор для преобразования кода в исполняемый файл. Также можно использовать специальные интегрированные среды разработки (IDE), которые поддерживают Go, например, GoLand от компании JetBrains. Существуют плагины для Go для других IDE, в частности, IntelliJ IDEA и Netbeans.

Установка компилятора

Пакет для установки компилятора можно загрузить с официального сайта https://golang.org/dl/.

По этому адресу пакеты установщиков для различных операционных систем. Так, при загрузки и запуске установщика для Windows открывается следующее окно:

После принятия лицензионного соглашения отобразится окно для выбора места установки:

По умолчанию используется путь «c:\go». Оставим этот путь по умолчанию и перейдем к следующему окну, на котором нажмем на кнопку Install:

Часть 1. Краткий обзор и основы программирования

Серия контента:

Этот контент является частью # из серии # статей: Язык программирования go

Этот контент является частью серии: Язык программирования go

Следите за выходом новых статей этой серии.

На рынке языков программирования появился новый игрок – язык программирования go от компании Google. Если верить официальным заявлениям Google, то go – это универсальный язык, пригодный для любых задач. Google анонсировал язык go в 2009 году, и с тех пор он немного изменился, но цели и задачи у него остались прежние: этот язык предназначен для системного программирования и по своей сути очень похож на С++.

Язык go — это компилируемый и многопоточный язык общего назначения, имеющий много общих черт с языком С++, поэтому для успешного освоения представленного материала необходимы определенные знания в C++.

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

В настоящее время поддержка языка go присутствует на платформах Linux, MacOS и FreeBSD. Удивляет отсутствие платформы Windows в этом списке, но работы ведутся, и скоро пользователи Windows смогут также попробовать go. С ходом работ по переносу go на ОС Windows можно ознакомиться на этой странице. На данный момент язык go может создавать исполняемый код для процессоров i386, amd64 и ARM. Кроме компилятора от компании Google, существует еще компилятор gccgo из коллекции GNU.

Пример использования

В языке go отсутствуют такие понятия, как класс, конструктор и деструктор (вместе с соответствующими зарезервированными словами). Однако в нем существуют структуры, позаимствованные из языка С, к которым можно привязать функции, поэтому в go можно создавать код и в стиле ООП. Наличие «сборщика мусора» упрощает работу с памятью, по сравнению с C или С++. Существуют и указатели, но арифметика для них не предусмотрена. Поэтому, даже зная адрес переменной, перемещаться в памяти относительного него невозможно. Это сделано из соображений безопасности. Сравнивая язык go с С++, стоит упомянуть о невозможности перегрузки функций и об отсутствии определяемых пользователем операций. Нет также заголовочных файлов и неявного преобразования типов. Многопоточность поддерживается на уровне языка, для связи потоков используются каналы. Они будут рассмотрены более подробно ниже.

В листинге 1 представлен пример программы на языке go, который будет понятен любому программисту, знакомому с синтаксисом C.

Листинг 1. Первое знакомство с go

Для работы с языком go потребуется установить следующее программное обеспечение:

  • GCC;
  • стандартная библиотека С;
  • генератор bison;
  • make;
  • awk;
  • редактор ed.

На платформе Ubuntu/Debian для этого используется следующая команда:

Затем необходимо загрузить из репозитария дистрибутив языка go. Для этого используется Mercurial – мультиплатформенная распределённая система управления версиями, которую можно загрузить командой:

Следующая команда загружает уже непосредственно сам язык:

Последний параметр — это имя каталога, в который будет установлен go. В данном примере подразумевается, что установка ведется из домашнего каталога пользователя и изначально каталога go нет. В противном случае могут возникнуть проблемы, так как по умолчанию go считает, что он установлен в каталоге $HOME/go. Если установить дистрибутив go в другой каталог, то его надо указать в переменной окружения $GOROOT, как показано ниже.

После получения дистрибутива можно переходить к сборке go:

На этом этапе будут собраны соответствующие библиотеки и исполняемые файлы. Если в конце в консоли будет напечатано сообщение ALL TESTS PASSED, то сборка прошла успешно, и можно приступать к программированию на go. Если возникают ошибки, это может быть связано с отсутствием инструментов, перечисленных выше. Также при отсутствии подключения к Интернет могут возникнуть ошибки при прохождении автоматизированных тестов, но это не является критичным для дальнейшей работы.

После этих действий код из листинга 1 можно сохранить в файле с именем hello.go и добавить значение $HOME/go/bin в переменную $PATH. В листинге 2 показано, как выполнить компиляцию и запуск go-программы на 32-битной версии Linux.

Листинг 2. Компиляция и запуск go-программы

Как видно, процесс компиляции и запуска в языке go совпадает с процессом, использующемся в языках С/С++. Для других платформ будут использоваться другие версии компилятора и компоновщика: 6g/6l для amd64 и 5g/5l для arm.

Типы данных, доступные в языке go

Язык go поддерживает исходный код в кодировке UTF-8, поэтому никаких специальных действий для использования символов, не входящих в английский алфавит, не потребуется. Даже в имени переменной могут содержаться китайские иероглифы.

Также в этом языке существует большое количество различных типов данных. Например, существует пять вариантов целочисленного типа int: int, int8, int16, int32, int64 . Такие же типы данных, но с префиксом u, представляют беззнаковые значения. Числа с плавающей точкой представлены тремя типами: float, float32 и float64 . В языке go нет неявного приведения типов, поэтому при компиляции могут возникать ошибки. Имеется даже два типа данных для комплексных переменных: complex64 и complex128 . Встроенный тип string представляет собой неизменяемый массив байт. В листинге 3 показан пример объявления констант.

Листинг 3. Объявление констант

Константы a и b получат значения 0 и 1 соответственно. Это обеспечивается специальным счетчиком iota , значение которого увеличивается при каждом последующем упоминании. Новые типы определяются с помощью ключевого слова type , как показано в листинге 4.

Листинг 4. Определение нового типа данных

Вся память в программе инициализируется, так что если объявить переменную, не присваивая ей значения, то она в любом случае получит значение по умолчанию. Значение по умолчанию равно 0 для числовых типов, false для булевых переменных и пустая строка для строк. В листинге 4 также можно увидеть пример объявления структуры в go, который ничем не отличается от объявления структуры в языке C. В языке go к структурам можно привязывать функции и делать из них, по сути, классы, как будет показано позже.

Говоря о типах, необходимо упомянуть сложные структуры, поддерживаемые на уровне языка, — массивы, срезы (slices) и хэш-таблицы. Главное отличие массивов в go от большинства популярных языков — это то, что они являются значениями, т.е. имя массива не является ссылкой. Ниже приведен пример объявления массива:

Получить адрес массива можно через &arr . Но из-за отсутствия адресной арифметики, никакой пользы из знания адреса извлечь нельзя, разве что передавать в функцию адрес массива вместо его копии, что положительно влияет на производительность. Инициализировать массив можно следующим образом:

Для инициализации определенных элементов необходимо указать индекс элемента и через запятую его значение. Если просто указать n значений через запятую, то будут инициализированы только первые n элементов. Так как в go вся память инициализируется, то все элементы, значения для которых не были заданы явно, получат значения по умолчанию.

На «настоящие» массивы больше похожи срезы, объявляемые как безразмерные массивы:

Задать значение среза можно адресом или фрагментом («срезом» – отсюда и название) массива, как показано ниже:

Существует также встроенная функция make(), которая выделяет память и возвращает адрес этого фрагмента памяти, который можно сохранить в переменной:

Ниже приведен пример создания хеш-таблицы:

В квадратных скобках задается тип ключа, а после него — тип хранимого значения. Хэш-таблицы можно и не инициализировать. Обращаться к элементам можно как в ассоциативном массиве в PHP: mp[“second”] . При обращении к несуществующему элементу генерируется ошибка. В go существует удобное средство for — range для итерации по значениям массива или хеш-таблицы, как показано ниже:

Объектно-ориентированным язык go назвать нельзя, но некоторые возможности ООП в нем имеются. Например, можно объявить функцию, привязанную к определенному типу. Тогда класс можно определить следующим образом: структура отвечает за поля, а привязанные методы реализуют поведение класса, как показано в листинге 5. Но все же основные возможности ООП, например, наследование, оказываются недоступными.

Цукерберг рекомендует:  Хакерский жаргон rulezzz или suxx
Листинг 5. Объявление класса в go

Также можно выполнить привязку к массиву и другим типам. Отдельно следует упомянуть интерфейсы. Они по своей сути похожи на интерфейсы в языке Java. При объявлении интерфейса в нем объявляется набор методов, и все типы, реализующие этот интерфейс, совместимы с переменной этого интерфейса, как показано в листинге 6.

Листинг 6. Использование интерфейсов

Работа с памятью в go организована по аналогии с языком С. При объявлении указателя для него необходимо получить память, за что отвечает оператор new() .

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

Функциональное программирование в go

Набор конструкций для контроля хода выполнения программы в языке go скуднее по сравнению с языком C. В go доступны только конструкции if , for и switch . Первое, что бросается в глаза, это отсутствие круглых скобок.

Листинг 7. Конструкции для управления ходом выполнения программы

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

Функции объявляются при помощи ключевого слова func . Особенностью является то, что они могут возвращать сразу несколько значений, по аналогии с множественным присваиванием, как показано в листинге 8.

Листинг 8. Множественное присваивание и создание функций

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

Конструкция defer представляет собой некий триггер, и функция foo() будет вызвана по достижении return . Если defer используется в функции несколько раз, то соответствующие методы выстраиваются в стек. Польза от подобного нововведения неочевидна, особенно при большом объеме кода. Так программисту, незнакомому с кодом, придется держать в памяти весь этот стек вызовов со всеми параметрами. При использовании defer структурное программирование не обеспечивается.

Многопоточное программирование

Многопоточное программирование в go обеспечивается ключевым словом go. Переданная в качестве параметра функция запускается в отдельном потоке. Функции могут общаться друг с другом через каналы. Все достаточно просто и эффективно, как можно увидеть в листинге 9.

Листинг 9. Многопоточная программа

В главной функции main() видно, что в разных потоках запускаются две функции. В качестве параметра им передается канал, созданный встроенной функцией make() . При создании канала можно указать его размер. Функция time.Sleep() отвечает за задержку при выполнении потока. В функции bar() в канал отправляются целые числа ( ch ), а в функции foo() они, по мере поступления, печатаются. Ничего сложного, но на этом простейшем примере наглядно показано, как организовать взаимодействие потоков в программе.

Пакеты

Представленной информации вполне достаточно для создания простейших программ, поэтому можно перейти к обсуждению архитектуры go-программы. Каждая программа – это пакет (см. package main в листинге 1), а точнее набор пакетов. Программы собираются из пакетов, и то, что обычно называется библиотеками, в go называется набором пакетов.

Исполняемая программа должна иметь пакет main и метод main , с которого начинается выполнение программы, и по завершении которого программа закрывается. Выражение import “package” дает доступ к методам, переменным и константам пакета package . Обращаться к ним следует через оператор . (точка), например, package.Foo() .

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

Например, клиент импортировал пакет package, в котором объявлены следующие переменные:

Вторая константа будет доступна клиенту по ссылке package.Hello.

Хотя язык go достаточно молод, он уже имеет обширную библиотеку пакетов. Выше использовался пакет fmt , предназначенный для форматированного ввода/вывода. Пакет os предоставляет доступ к файлам, аргументам командной строки, позволяет запускать другие программы и т.д. Есть пакеты для шифрования, сжатия, кодирования и журналирования. Отдельного внимания заслуживают пакеты net , http , websocket для работы с сетью, позволяющие без особых усилий создавать Web-приложения. В стандартной поставке есть даже пакет для работы с изображениями. После установки в каталоге $HOME/go появляется каталог pkg, в котором есть каталог, соответствующей архитектуре. В этом каталоге выполняется хранение и поиск пакетов.

Заключение

В 2009 go был признан языком года по версии организации TIOBE. Сложно сказать, насколько этот язык «созрел» для серьезных проектов, но его потенциал очевиден. Простота создания многопоточных и сетевых приложений позволяет говорить о жизнеспособности и востребованности проекта в целом. «Идеологическое родство» с языками С и С++, возможно, поможет языку go, как в свое время родство с С помогло развитию C++, а родство с C++ способствовало становлению Java. Огромную роль играет и поддержка со стороны разработчика языка – компании Google, возможно, самой влиятельной IT-компании на данный момент. В следующих статьях будут рассматриваться более сложные аспекты программирования на языке go.

Программирование на Go

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

Конечно, сложно охватить программирование go полностью в одной статье, но вы узнаете основы, которые помогут вам в дальнейшем. Но перед тем как перейти к рассмотрению языка, давайте поговорим про историю его развития и структуру. Статья рассчитана в первую очередь на тех, кто уже знает какой-либо Си подобный язык программирования, поэтому новичкам материал может показаться сложным, но им тоже может быть полезно. Я не говорю, что программирование на Go с нуля невозможно, просто для этого нужна более подробная литература.

История развития Go

Язык Go элегантен и прагматичен, но некоторые его особенности имеют смысл только под определенным историческим контекстом. История Go начинается с Си. Во многих отношениях Си стал основой для создания JavaScript, Ruby, Python, C++, C# и Java. Компиляторы или интерпретаторы некоторых из этих языков даже написаны на Си. Влияние Си легко заметить во многих языках. Он был разработан Денисом Ритчи для создания ядра Unix и потом использовался для создания ядра Linux.

Язык Go был создан легендами эпохи Unix и Си. Работая Google, Роберт Грисемер, Роб Пайк и Кен Томпсон были разочарованы в Си-языках из-за их проблем. Бъярн Страуструп, создать C++ говорил так: «Си позволяет легко выстрелить себе в ногу, в C++ это сложнее, но если вы все же выстрелите, то взорвете ногу целиком».

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

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

Также можно найти определенное сходство с динамическими языками, Go перенимает стиль написания кода у Python, настраиваемость у Ruby и простой параллелизм, вшитый в ядро языка, как у Node.js. Все начиналось, как язык, решающий некоторые проблемы Си и выросло в прекрасный язык программирования общего назначения.

Программирование на Go

Перед тем как мы перейдем к примерам написания программ, хотелось бы немного поговорить про синтаксис языка.

1. Синтаксис языка Go

Самое главное о чем стоит сказать — это структура программы. Она чем-то похожа на Java и Python. Программа разделяется на так называемые пакеты Package, которые можно рассматривать как альтернативу include или модулей в Python. В дополнение package позволяют настраивать области видимости для переменных. Импортируется пакет в программу с помощью инструкции import:

import имя_пакета

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

var имя_переменной тип

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

var имя_переменной := значение

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

var *имя_переменной тип

Чтобы получить доступ к переменной, которая была объявлена внутри package из другого package важно заметить, что доступны извне только переменные, написанные с большой буквы:

имя_пакета . имя_переменной
имя_пакета . имя_функции

Основные управляющие инструкции очень схожи по своему синтаксису с привычными в Си:

if условие <
действия
>

Цикл for тут точно такой, как и в Си, только без круглых скобок, так выглядит даже проще:

for i := 0; i i++ <
действия
>

Функции golang объявляются с помощью директивы func, и в ней можно указать не только параметры, но и возвращаемые переменные:

func имя_функции (принимаемые переменные) (возвращаемые переменные) <
действия
>

Важно заметить, что точка с запятой после строк не ставиться. Вместо ООП классов в Go используются структуры, которые могут иметь поля и методы, а также могут реализовать интерфейсы. Чтобы объявить структуру используется инструкция type:

type имя_структуры struct <
имя_поля тип_поля
>

Кроме полей, структуры могут иметь методы, что позволяет использовать их в качестве классов. Объявление метода немного отличается от функции golang:

func ( имя_указателя *тип_структуры ) имя_метода() <
действия
>

Создание объектов структур происходит так же, как и обычных переменных, а обращаться к их полям можно через точку:

имя_объекта . имя_метода (параметры)

К полям мы тоже обращаемся через точку:

имя_объекта . имя_поля

Теперь вы знаете основы языка и пришло время перейти ближе к практике. Дальше будет программирование на Go и примеры Golang, минимум теории.

2. Создание Hello World

Напишем нашу первую программу, как принято, это будет программа, которая выводит на экран строчку «Привет мир!». Вы можете установить Go в свою систему или же воспользоваться онлайн сервисом play.golang.org, который позволяет выполнять программы прямо в браузере. Мы будем работать с онлайн сервисом.

При открытии сайта вы увидите уже готовый код первой программы:

package main
import ( «fmt»)

func main() <
fmt.Println(«Hello, playground»)
>

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

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

Внутри функции main мы вызываем функцию библиотеки fmt, которую импортировали ранее с помощью синтаксиса точки. Метод printLn выводит строчку на экран.

Для языка Go был принят определенный синтаксис. Даже если компилятор не будет выдавать ошибок из-за несоответствия, его лучше соблюдать. Для имен переменных принято использовать верблюжий синтаксис, то есть FooBar или Foobar вместо foo_bar. А также обратите внимание, что Go не терпит никаких символов перед открывающей скобкой. Даже если поставить перевод строки, вы получите ошибку:

Также в Go стандартизированы отступы, хотя здесь нет таких требований, как в Python.

3. Основы языка Go

Рассмотрим работу с переменными и структурами. Это будет полезно начинающим пользователям. Как я уже говорил, язык имеет статическую типизацию. В Python, Ruby или JavaScript нужно выполнять множество проверок на правильность. Go избавляет от этой проблемы. Например, усложним наш предыдущий пример:

В этом примере, за вывод отвечает новая функция — print. Здесь явно указано, что ей нужно передать строку (string). А в функции main мы создаем переменную типа string и передаем ее в print. Если передать что-то другое, получим ошибку. Если, например, вы поменяете тип переменной на int, то получите это:

cannot use «Привет мир!» (type string) as type int in assignment

Также вы получите ошибку, если объявили переменную или импортировали пакет, но не используете его. Существует еще множество вещей, которые можно сделать с помощью Go, одна из них — это структуры. Давайте еще больше усложним нашу программу, создадим структуру site, с полями name и url, которая будет описывать какой-либо сайт:

В структуры будет метод print, который выводит строку «Добро пожаловать. «. В методе main мы инициализировали структуру и присвоили ее полям значения, а затем вызвали метод print.

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

Выводы

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

Язык Go — зачем он нужен и что на нем пишут? [закрыт]

Этот язык уже несколько лет в поле видимости.

  • Но что на нем пишут?
  • И что можно написать?
  • Стоит ли его учить?
  • Или он скоро исчезнет?

Закрыт по причине того, что необходимо переформулировать вопрос так, чтобы можно было дать объективно верный ответ участниками Kromster says support Monica, ermak0ff, Streletz, PashaPash, Max Mikheyenko 13 ноя ’15 в 17:51 .

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

5 ответов 5

И что можно написать?

Что угодно. На самом деле что угодно, но, в силу своих плюсов он очень популярен для разработки сервер-сайда (бэкенда).

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

  1. Для себя, своего стартапа
  2. Продавать готовый продукт
  3. Выполнить заказ, если заказчику подходят плюсы этого языка (придётся объяснять/убеждать)


Как уже писали — исчезнуть он не может, т.к. OpenSource. Т.е. никто не отберёт у Вас написанное на нём, максимум будет ухудшаться развитие/поддержка, во что слабо верится, т.к у языка очень существенные плюсы.

Плюсы или «почему я выбрал Go»

Производительность

По производительности для веб (готовые фреймворки) Go проигрывает только Java и С/С++ и наравне с node.js. При этом потребление ресурсов существенно ниже, чем у Java и производительность намного больше, чем у Python/Ruby.

Многопоточность

При этом имеет просто офигенную многопоточную модель по сравнению с ними. Пока это лучшее, что я встречал для многопточки/асинхрона. При этом он поддерживает и классические паттерны вроде мьютексов и колбэков.

Простота

Он очень прост в освоении. Мне кажется даже элементарен, особенно если есть основа из Python/JavaScript. Есть также довольно занятная модель наследования, которая, как мне кажется более прозрачна чем классическое ООП, но немного непривычна поначалу.

Надёжность

Язык этот компилируемый и статически типизированный. Что даёт выявление многих ошибок задолго до продакшена. К примеру такие ошибки в Python выявляются только непосредственным тестированием и, если тестов нет, то шансов положить систему очень много. Тут же это исключается на этапе компиляции.

Скорость компиляции

И, наконец, одна из главнейших фишек — не стоит бояться типизации и компиляции. В 145% случаев Вам не придётся объявлять тип переменой в коде — он задаётся автоматически при присвоении ей значения. Объявлять переменные заранее также не нужно.

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

Итого

Т.е. мы имеем плюсы из двух миров — скорость компиляции/запуска интерпретируемого и надёжность компилируемого языков. Плюc сверху производительность, мультипарадигменность (можно писать в функциональном стиле), простота и низкое ресурсопотребление.

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

Пишем первый проект на Golang

Пару месяцев назад я начал писать на Go так же известным, как Golang. И не только из-за их потрясающего логотипа. Основная причина была в том, что я хотел, чистую железяку на моем Raspberry Pi, а так же кроссплатформенность в паре с легкостью установки. Среди других причин были простота создания на Go асинхронного кода с помощью Go методов и уникальный подход к синхронизации каналов между подпрограммами (потоками) посредствам go routines.

С тех пор, как GO был выпущен в 2012 году, я много читал о нем и что ж, пришло время по-настоящему замарать руки и попробовать использовать его для своих задач.

Однако любопытно, продолжим .

Что же из себя представляет GO?

Go — это опен сорсный язык программирования , который позволяет легко создавать простое, надежное и эффективное программное обеспечение. Разрабатывался он внутри компании Google и на 2020 год уже являлся одним из самых быстроразвивающихся и адаптированных языков программирования. Первый релиз языка появился в марте 2012 года. А не так давно, начиная с выпуска Go 1.11, у него появилась поддержка модулей и управлять зависимостями стало немного удобнее.

Необходимые настройки среды

Для начала нужно все правильно настроить. Есть простой способ установить мою библиотеку с помощью Chocolatey.

В Windows мы используем Chocolatey в Powershell для установки Go и vscode…

С установленным Go и vscode у нас есть все, что нужно для начала.

Так как я использую Git bash на все случаи жизни, я запускаю следующую команду Visual Studio Code из Git Bash, чтобы установить go расширение. Если хотите, вы можете просто установить расширение из самого vscode.

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

Где найти отличные ресурсы и материалы по GO?

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

Создаем первый проект

Для того, чтобы начать на Go новый проект, мы сначала создаем пустую папку. Затем мы прописываем в этой папке команду go modules init, чтобы инициализировать модули Go. Модули используются для зависимостей.

Синтаксис

В Go мы определяем функцию, используя ключевое слово func.

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

Все переменные, функции, структуры, которые начинаются с верхнего регистра в Go являются публичными. А все переменные, функции, структуры, начинающиеся со строчной буквы, являются частными. Кроме того, как вы наверное уже заметили в примере, определения типов идут за именем переменной. Поместив оператор импорта поверх файла вы можете импортировать все необходимые пакеты. И последнее, но не менее важное: каждая программа go должна иметь хотя бы один main пакет.

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

Вперед, в бой!

Теперь у нас есть пустой проект, и к тому же мы уже немного знаем о синтаксисе, чтож, начнем! Открываем эту папку в vscode.

Сначала мы добавляем новый файл в нашу папку, называем ее main.go . Затем добавим тот код, который мы рассмотрели выше.

Теперь с помощью этого кода мы можем запустить наше приложение. Используя следующую команду в командной строке.

Можете также прогнать этот код в Go playground.

Тестирование

Чтобы добавить тесты в go, просто добавьте файл main_test.go. Добавим функцию проверяющую метод sayHi. Сигнатура методов тестирования всегда ДОЛЖНА быть TestXxx(t *testing.T). Первый X всегда должен быть в верхнем регистре.

Вы наверняка заметили что то новое в этом коде. Мы используем сокращение для присвоения значений переменной: =. Если функция sayHi не возвращает ожидаемое нами значение, мы выдадим ошибку с хорошим понятным сообщением.

Теперь, чтобы запустить наш тест, мы сделаем в командной строке следующее. Обратите внимание, что я запускаю все тесты из всех файлов и подпапок в моем проекте таким способом ./.

Пожалуйста, не бойтесь пробовать, изменяйте реализацию, и снова запустите тест, чтобы увидеть, как тесты пройдут неудачно. Для запуска с code coverage запустите такие тесты.

Цукерберг рекомендует:  Школа - Высшее образование Нужно или нет

Чтобы подробнее ознакомится, пожалуйста, читайте документацию о testing package.

Компилируем и выполняем

Самым простым способом создать исполняемый файл будет:

Это команда создаст нам исполняемый файл Windows, как будто мы на Windows. Вы можете просто вызвать исполняемый файл и увидеть тот же результат, что мы имели при вызове go run main.go. Если мы хотим получить более подробный вывод и посмотреть, что происходит за под капотом, можно использовать -x опцию -в go build. А как нам скомпилировать один и тот же код для Linux или Raspberry Pi?

Чтобы запустить этот бинарник в Linux, не забудьте использовать chmod +x, а затем просто вызвать с помощью ./hello-world

Raspberry Pi 3 имеет архитектуру ARM v7, которую можно скомпилировать следующим образом. ПРИМЕЧАНИЕ: все это мы можем сделать с Windows.

Для запуска бинарника сделайте все то же самое, что и на любом другом компьютере с Linux chmod +x, а затем ./hello-world для запуска вашего приложения.

Резюмируя

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

И последнее, но не менее важное: я хотел бы поделиться с вами своим первым приложением на Go. Это интеграция с термостатом Nest, который я запускаю на своем Raspberry Pi, чтобы собрать данные о температуре и отобразить их в хорошем веб-приложении на React. Только не забудьте зарегистрироваться в рабочем пространстве Gophers Slack.

Go — простой язык для серьезных задач

Группа: Главные администраторы
Сообщений: 14349
Регистрация: 12.10.2007
Из: Twilight Zone
Пользователь №: 1

Цель этой статьи — рассказать о языке программирования 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, mian.

Буду приводить неполное содержание файлов, а только минимально необходимое для понимания.

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

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(). Их может быть несколько в разных файлах.

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-8tf-8»)
>)

Auth := func(mu *utils.MarshUnmarsh, req *http.Request, rw http.ResponseWriter) <
reqUser )
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)
// .

В самом верху определяется имя пакета. Далее идет список импортируемых пакетов. Мы будем использовать пакет 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.

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
>

Язык поддерживает возврат нескольких значений. Вместо механизма 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() так же возвращает указатель, а не значение. По-началу возникает небольшая путаница с указателями, но, со временем, вы привыкните.

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

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 (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. <
return conf.ErrPostNotFound
>
if err != nil <
return conf.NewApiError(err)
>
return 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 в ответ.

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) <
]
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» Марка Саммерфильда. И, конечно, больше практиковаться.

4gophers

Глубинное обучение с нуля в Go — Часть 1: графы

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

Глубинное обучение, на самом деле, совсем не новомодное изобретение. Сама идея появилась еще в начале 1980х. Но в наше время компьютеры стали значительно мощнее. В этой статье мы начнем разбираться с этой темой, начиная со знакомых вещей, со временем вникая в принципы работы глубинного обучения. Мы не будем нырять с головой в глубинное обучение на протяжении нескольких первых статей и вам не придется столкнутся с кучей непонятных терминов в самом начале, все произойдет постепенно.

И начнем мы с изучения понятий необходимых для старта. В этом цикле мы не раз будем сталкиваться с понятием “граф”, которое относится, как можно догадаться, к [теории графов](https://en.wikipedia.org/wiki/Graph_(discrete_mathematics). Не путайте с “графиком”.

Вычисления

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

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

Для большей конкретики давайте рассмотрим простой пример:

Эта программа может быть представлена в виде абстрактного синтаксического дерева(AST), вроде такого (для построения AST использовалась библиотека, работающая поверх goast-viewer):

Глядя на этот пример, можно догадаться, что все уравнения могут быть представлены в виде компьютерной программы, а компьютерная программа может быть представлена в виде графа. Давайте рассмотрим поближе выражение 1+1 :

Это выражение можно представить в виде упрощенного графа, откуда мы удалили все не нужное:

Как видно, граф расширяется в глубину, начиная с вершины. Вычисляемые значения в программе как бы всплывают наверх. Когда программа запускается, она начинает выполнятся с самого верха. Но нода не может быть вычислена пока не будут вычислены все зависимости. Стрелки показывают на зависимости между нодами. К примеру, значение ноды *ast.BinaryExpr зависит от значений *ast.BasicLit (тип: INT ). Как только мы поняли что оба значения 1 и знаем что делает + , то модем вычислить значение ноды *ast.BinaryExpr которое будет равно 2 .

Уравнения в виде графов

Почему мы потратили столько времени чтобы представить 1+1 в виде графа? Потому что этот подходя является основой всего глубинное обучение, только вместо 1+1 будут более сложные уравнения. Не пугайтесь слова “уравнения”, все не так страшно. Лично я один из тех людей, кто занимается глубинным обучением (и другими областями машинного обучения) без каких либо обширных математических познаний. По моему опыту, нет более надежного способа обучения, чем визуализация рассматриваемых концепций.

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

Таким образом, мы можем создать что-то вроде такого:

Граф нашего уравнения будет выглядеть так:

Зачем использовать объекты для графов?

После прочтения всего выше описанного, модно прийти к выводу, что если все программы это графы и математические уравнения это тоже графы, то мы модем просто использовать встроенные математические выражения. Зачем нам использовать объекты, как в примере выше, если проще написать fmt.Printf(«%v», 1+1) ? В конце концов, это выражение тоже будет графом. Использование объектов для таких выражений слишком избыточно.

Вы совершенно правы. Для простых уравнений использование объектов для манипулирования графами не имеет смысла(ну, только если вы не из джава мира, в котором все делается только так).

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

Вычислительная устойчивость

К примеру возьмем уравнение y = log(1+x). С точки зрения языка программирования у этого уравнения будут проблемы с вычислительной точностью — при очень маленьких x ответ, скорее всего, будет не верный. Проблема в самом устройстве float64 — просто не хватает бит для работы с диапазонами от 1 до 1 + 10e-16 . Для корректной работы с уравнением y=log(1+x) необходимо использовать встроенную библиотечную функцию math.Log1p как показано в примере ниже:

Конечно, когда программист осведомлен о этой проблеме, он будет использовать math.Log1p для реализации нейронных сетей й все будет хорошо. Но, думаю вы согласитесь со мной, было бы намного лучше, если бы при работы с уравнениями вида log(1+x) автоматически использовался math.Log1p(x) . Это может помочь избавится от целого ряда человеческих ошибок.

Оптимизации спицифические для машинного обучения

Рассмотрим еще один вариант программы, похожей на ту с которой мы начали:

Эта программа компилируется в ассемблер ниже:

В частности, обратите внимание на последний день: MOVQ $2, «».

r0+8(FP) . Видно, что функция оптимизирована и сразу возвращается 2 . Нет никакой операции сложения. Компилятор понимает как оптимизировать код, во время компиляции вычисляя что 1 + 1 = 2. Просто заменяя выражения константами, компилятор умудряется использовать меньше циклов процессора в рантайме. Если вам интересно побольше узнать о том как работает оптимизация в компиляторе, то почитайте о свертке констант.

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

Представим, что вы вместо сложения 1 + 1 хотите выполнить []int <1, 1, 1>+ []int <1,1,1>. Компилятор не сможет оптимизировать это выражение и заменить его на []int <2, 2, 2>. И вот тут использование объектов для работы с графами может показать себя во всей красе. При работе с объектами у вас появляется возможность выполнять аналогичные оптимизации. В библиотеке Gorgonia сейчас нет встраивания констант(была попытка реализовать это в более ранних версиях, но пока нет понимания как это делать правильно), но она предоставляет целый ряд других оптимизаций, например удаление общих подвыражений, когда некоторые переменные исключаются и дерево ужимается до своего минимального вида. Другие, более классические библиотеки, такие как TensorFlow или Theano, используют большое количество самых различных алгоритмов оптимизаций для работы с графами и не только.

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

Обратное распространение ошибки

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

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

Почему Go?

Если вы работаете с гомоиконичными языками, такими как lisp или Julia, то у вас нет необходимости создавать дополнительные объекты для работы графами. Если у вас есть доступ к внутренним структурам самой программы и возможность изменять программу во время выполнения, то большинство необходимых операций модно реализовать “на лету”(если извернуться, то подобного можно добиться в Go, но это не самый оптимальный подход). Это позволяет упростить реализацию алгоритма обратного распространения ошибки переложив часть логики на рантайм. К сожалению, в случае с машинным обучением, нам придется самим реализовывать большинство структур и организовывать работ с ними.

Замечу, что это не камень в огород Go, Pyhton или Lua. Все эти языки имеют как преимущества, так и недостатки. Но почему, как по мне, Go более предпочтителен для глубинного обучения, несмотря на большое количество библиотек для того же Python или Lua? Одна из основных причин, которая подтолкнула меня на создание Gorgonia, была возможность собирать все в один банарник. Сделать такое на Python или Lua весьма нетривиальная задача. Деплоить go-прораммы одно удовольствие

Я уверен, что использование Go для работы с данными — это замечательная идея. Этот язык строго(достаточно строго для меня) типизирован, и он компилируется в один бинарный файл. Go предоставляет лучшую “механическую” связанность между различными частями системы, что позволить реализовать более быстрый и качественный AI. И не стоит забывать, что так или иначе, все наши программы запускаются на определенном железе. И я просто хочу работать с высокоуровневыми структурами для реализации своих идей. Именно это было движущей силой для меня. Надеюсь, моя реализация вам понравится и вы будете ее использовать.

Понравилась статья? Поделиться с друзьями:
Все языки программирования для начинающих