×Закрыть

Советы сеньоров: как прокачать знания junior Go

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

Іван Данилюк, Core Go developer в Status.im

15 років в ІТ (5 з них в Go)

Мова Go вважається однією з найпростіших для вивчення, але нехай це не вводить в оману — як правило, простою її знаходять досвідчені розробники, а джуніори можуть мати труднощі у розумінні тих чи інших аспектів мови. Цьому є дві причини:

  • мінімум магії — Go дуже мало речей робить за вас, тому від програміста очікується чітке розуміння, з чим він працює і який результат хоче мати;
  • нестандартний підхід до об’єктно-орієнтованого програмування — в Go немає класів та наслідування, і часто людям складно уявити, як взагалі можна будувати абстракції без цього (багато хто думає, що ООП — це і є класи, але це не так).

З чого починати вивчення?

Однозначно починати потрібно з проходження офіційного Go Tour (українська версія) — інтерактивного туру, який дасть 90% розуміння синтаксису та головних концепцій мови. Наступним має бути також офіційний документ Effective Go (переклад російською), який проходить по всім ключовим ідіоматичним конструкціям та концепціям Go. З мого досвіду, 70% всіх запитань новачків по Go мають відповіді у цьому документі. Також для початку варто ознайомитися з коротеньким How To Write Go Code. Оскільки Go є достатньо простою мовою, причому схожою на C та С-подібні мови, для більшості людей на Go Tour та Effective Go достатньо одних вихідних. Специфікація мови також коротенька, раджу в неї заглядати як в головне джерело істини в незрозумілих ситуаціях.

А от далі універсальної поради немає — комусь краще вчити мову по книжкам, хтось ліпше сприймає відеокурси, а інші прагнуть вивчати одразу на практиці. Гарна новина в тому, що останній варіант в Go працює (це називається bottom-up learning) — ви можете відкривати мову крок за кроком, програмуючи та вивчаючи її на ходу. Але ось деякі ресурси та книги для тих, хто любить спочатку вивчити цілком та повністю і потім застосовувати.

Книги:

Курси:

Які можуть бути труднощі?

Найбільші труднощі виникають через спробу писати на Go як на інших мовах. Це нормально, і сильно залежить від попереднього досвіду розробника, але важливо з самого початку прийняти, що Go — це є нова мова. І не просто нова, а й в деяких моментах дуже відмінна від мейнстріму мов програмування. Ці відмінності можуть збивати з пантелику на початку — відсутність виключень, класів та дженериків, автоматичне форматування коду, вплив маленької/великої літери змінної на видимість, тощо — але саме вони є причиною такого стрімкого успіху Go. Мені свого часу допомогло прийняти та «дати шанс» цим відмінностям, як не дивно, те, що називають «appeal to authority» — знаючи, що авторами Go є такі легенди computer science як Роб Пайк та Кен Томпсон — я просто довірився їх досвіду і прийняв як факт, що я є в рази менш досвідчений за цих гігантів. І це було дуже мудре рішення.

Проте в Go, як і в будь-якій мові, є свої підводні камені. Про них є купа гарних статей, проте зі свого досвіду я певен, що більшість з них можна уникнути, якщо з самого початку ознайомитись, як Go працює «під капотом» — принаймні, як реалізовані інтерфейси, слайси/масиви та вказівники. Саме на цю тему є стаття з візуалізаціями «How To Avoid Go Gotchas» (переклад російською).

Також нерідко доводиться чути, що не одразу дається розуміння, як працювати з concurrency-примітивами в Go. Насправді, це достатньо проста тема — її просто потрібно один раз правильно зрозуміти. Тут можу порадити свою спробу візуалізувати concurrency в Go — «Visualizing Concurrency in Go» (переклад російською та відеодоповідь) та дуже вдалу книгу «Concurrency in Go».

Як розвиватись далі?

Якби я міг дати лише одну пораду тут, то це було б одне слово — open-source. Проекти з відкритим кодом, яких безліч на гітхабі, — це не просто безцінне джерело коду, на якому можна вчитися, але й, без перебільшення, найкраща школа для будь-якого розробника.

Go тут займає особливу позицію, тому що це об’єктивно перша мова в світі, яка розроблялася з урахуванням соціального аспекту програмування. Саме це пояснює невпинне зростання використання Go для open-source проектів. В Go дуже мало що потрібно, щоб ваша першу програму було не соромно викласти на Github, що стимулює це робити частіше.

Коли ви публікуєте свій код або контріб’ютите в інший проект, це одразу дає розуміння, що на ваш код будуть дивитись інші (досвідчені) розробники, і змушує вас приділяти увагу чистоті та зрозумілості кода, писати юніт-тести та коментарі — іншими словами, природним шляхом вчить вас найкращим практикам програмування.

Наостанок, можу порадити приєднатись до українського Go community — ми регулярно проводимо мітапи у Києві, Львові та Харкові, перекладаємо та пишемо статті, виступаємо на міжнародних конференціях та проводимо воркшопи. Також у нас є дуже затишний та дружній Slack-чатик, в якому є канали і для новачків, і для HR-менеджерів з пропозиціями Go вакансій, яких з кожним місяцем все більше і більше. Приєднуйтесь!

Андрей Севастьянов, Software developer в Depositphotos

21 год опыта в IT

Наверное, я начну с общих рекомендаций и постепенно буду переходить к Go.

Git. Рекомендация первая относится к тому, чтобы освоить методологию разработки с git. Во-первых, большинство проектов на Go разрабатываются с использованием git, и с ним вы будете часто сталкиваться в повседневной работе. Во-вторых, сейчас популярно давать в резюме ссылку на профиль в github, и если работодатель соизволит туда посмотреть, то грамотно оформленные коммиты будут плюсом. Таким образом, вы прокачиваете дисциплину ума, систематичность, допускаете меньше ошибок и помогаете другим лучше понимать ваш код. Что такое грамотное оформление? Я бы начал с двух пунктов:

  • Коммиты должны быть небольшого размера. Чем меньше коммит, тем проще понять, зачем он был нужен. Также при его просмотре куда проще заметить ошибки. Когда же один в одном коммите три тысячи строк было добавлено и ещё полторы было изменено, то разобраться в нём очень сложно.
  • Коммит должен иметь содержательное сообщение. Часто это ссылка на ошибку/задачу. Когда вы смотрите код, то видите, что этот код делает. Но часто непонятно, зачем это делается. И, на мой взгляд, лучшее место для того, чтобы описать это, есть не комментарий, а сообщение коммита. Тогда команда git blame может дать много ценной информации тем, кто будет смотреть код.

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

Не ограничивать себя. Третья рекомендация больше связана с тем, что не стоит ограничивать себя изучением только Go и его особенностей. Старайтесь смотреть на мир IT шире, общая эрудиция тоже очень ценится и позволяет более комплексно подходить к решению проблем. Язык программирования Go был разработан в том числе и для написания сетевых демонов, поэтому чаще всего вы уже будете иметь некоторый опыт в сетевых взаимодействиях, многопоточности и немного в базах данных. Также Go оказался удобным и для написания некоторой общей логики, заняв промежуточное положение между C и С++. Поэтому имеет смысл и дальше развиваться в этих областях. Для прокачивания навыков, на мой взгляд, лучше всего подойдёт любая интересная лично вам задача, решение которой мотивировало бы вас. Впрочем, если уже программируете на Go, то велика вероятность, что у вас уже есть стремление к самым разным знаниям, и теперь важно оформить это своим преимуществом.

Многопоточность в программировании — это источник многих проблем. И, соответственно, было предложено много методов, как эти проблемы можно, если не побороть, то хотя бы облегчить. Гоурутины вместе с каналами — это ещё один метод решения этих проблем. Но чтобы стать профи, желательно всё-таки ознакомиться и с другими подходами. Тут есть много тем для изучения. Можно опуститься на уровень ниже и посмотреть на то, какие средства для работы с многопоточностью представляет операционная система, и как эти средства используются в Go для создания примитивов языка. Можно изучить подход в языке Rust, когда при написании программы даются некоторые подсказки компилятору относительно времени жизни и доступа к разным переменным, чтобы он мог на этапе компиляции проверить потокобезопасность многих участков кода. Можно посмотреть на сопрограммы (например, их реализация в Lua). Ну и совсем интересующиеся могут опуститься на уровень ядра и посмотреть, что работает там и почему многое из этого нежелательно использовать в обычном пользовательском коде. Также один из интересных подходов можно найти в языке Ada. В качестве задач для тренировки многопоточности можно брать разного рода моделирования системы, в которой взаимодействуют много агентов. Например, поведение людей в супермаркете, поведение машин на дорогах и т. п., когда естественным образом каждому агенту соответствует собственная гоурутина.

Сетевое программирование, на мой взгляд, это, прежде всего, опыт в реализации протоколов. Сетевые API в общем более или менее одинаковы в разных языках, а вот при практической реализации протоколов могут возникать разные нюансы. Тут для обучения можно брать разные Torrent-протоколы, много протоколов можно найти в распределенных Blockchain решениях, I2P, ... Берём, что интересно, и разбираемся. Или присоединяемся к активным разработкам, например, swarm

Базы данных. Тут ситуация такая, что в большинстве случаев, если брать реляционные базы данных вроде Oracle, MS SQL, то там уже выработаны классические подходы и большие фреймворки. В случае Go часто может встретиться какая-то нестандартная задача, которая потребует вертолётное ви́дение и нестандартные решения. Поэтому я бы посоветовал прокачивать общую эрудицию. Интересной является книга «Семь баз данных за семь недель», в которой рассмотрены достаточно разные примеры баз данных (классические реляционные, графовые, ключ-значение, ...). Не навредит.

Алгоритмический код в общем случае имеет мало зависимостей и является, по сути, перемалыванием байтов, который имеет мало зависимостей с другими библиотеками. Тут язык программирования Go оказался посередине между C и C++. При написании алгоритмического кода на C надо сражаться с большим количеством несложных рутинных задач, как то меджментом памяти, стратегией обработки ошибок, аскетичностью языковых средств. С другой стороны, С++ очень большой язык с массой нюансов, «острый, подобный бритве, которой легко пораниться», что требует большого порога вхождения. И если вы хотите улучшить себя именно в области, то, наверное, имеет смысл ознакомиться с этими двумя языками хотя бы для того, чтобы потом прочитать GoForCPPProgrammers.

Принимайте участие в конкурсах! Время от времени проводятся разные конкурсы, которые могут быть интересны рязработчикм на Go. Например, в прошлом году проходил Highload Cup. Участвуйте в таких конкурсах и улучшайте свои навыки. Удачи вам в изучении, не теряйте мотивацию!

Іван Кутузов, Technical leader (Golang expert) в SoftServe

13+ років досвіду в ІТ (3 з них в Go)

Golang (Go) — це мова програмування народжена всередині Google, дизайн якої, базується на принципі KISS. За рахунок цього код більш подібний до С, а нові конструкції та типи зробили мову ефективною та сучасною.

Розробка базується на тих самих вічних та загальних принципах computer science: структури даних, теорія алгоритмів, розуміння, що таке чистий код, як створювати тести та навіщо потрібно використовувати об’єктно-орієнтований підхід. Багато інформації можна знайти англійською мовою (у мене вже склалось враження, що це більше не є перешкодою).

Багато інформації та посилань зібрано на Wiki сторінці github проекту golang (code — як розпочати, effective — перші best practices), повертайтесь туди час від часу. Тож перше, з чого варто розпочати, — це познайомитись із синтаксисом та конструкціями. Це можна зробити, пройшовши GoTour, Golang tutorial series, online книгою Learning Go або пройти курс GoBootCamp.

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

Одразу переходьте до практики: оберіть собі задачу і сконцентрируйтесь на її виконанні, працюйте так, наче виконуєте замовлення (від запису вимог, моделювання, кодування, тестування різним чином і запуск на зовнішній платформі). Задача може бути з довільної області, основна порада на даному етапі — обрати більш прості речі, які ви можете опанувати за вихідні: обмінюватись інформацією через файли або internet, зтягувати інформацію за лінкою або декодувати JSON, обробляти або генерувати зображення.

Був випадок, коли задачу розробки сервісу обміну повідомленнями студент вирішив оформити через GUI для консолі (це ще та собі морока). Через це він драматично відстав від загального потоку і ледь встиг показати результат наприкінці курсу. Навчиться тримати фокус на задачі і додавати фічі у стилі еволюції (етапами, кожна нова після завершення роботи над попередньою). Ми стараємось постити матеріали workshop-ів, але можна знайти й інші варіанти. Приклади рішень з коментарями (web), система виконання малих задач з фідбеком від інших виконавців.

У Go багато рішень вже готові у standard library, але, щоб якісно їх використовувати, варто розуміти, для чого кожен з пакетів, яке його основне призначення та які його обмеження. Мова дозволяє нам сфокусуватись над рішенням задачі, а не обиранням того чи іншого framework-y. Набір сторонніх пактів можна дивитись через ресурс пошуку go-search.org або серед список визнанних awesome-go, які вже розподілені за категоріями.

Для мене було важко опанувати концепцію interface та concurrency на початку. Тож потрібна ваша наполегливість у практиці та додаткові статті, перегляд доповідей з конференцій та мітапів. Раджу звернути увагу на наступних авторів: Dave Cheney, William Kennedy, Mat Ryer, Ivan Danyliuk, Francesc Campoy. Слідкуйте за їх активністю через twitter, переглядайте виступи та читайте статті. Перевіряйте свої гіпотези, повторюйте те, що побачили, прочитали. Має з’явитись розуміння, де, коли і для чого вони потрібні.

Тримайте основний фокус на практиці. Переходьте до більш складних та комплексних проектів. Створіть сервіси, яким будете користуватись, бота для telegram, тулзу, яка буде знаходити подібні фото тощо. Під час розробки у вас буде виникати купа запитань, відповіді на які легко знайти в статтях або запитати у спільноти. Долучіться до open source проекту, це надасть вам якісний досвід взаємодії з іншими інженерами, ви отримаєте відгук на роботу і це буде значним плюсом під час проходження співбесіди.

Технологія вивчається через практику, спроби та помилки. Вчіться на помилках інших, перевіряйте себе, чи не повторюєте ви їх. Також варто спробувати інтегрувати ваше рішення із суміжними технологіями, розуміти, коли та як їх використовувати: Git, Docker, Kubernetes (will be plus), PostgreSQL, MongoDB, Redis, RabbitMQ, AWS etc. Наприклад, якщо розробляли систему пошуку інформації в Internet, додайте статистику, зробіть відстеження прогресу виконання, можливість продовжувати роботу після зупинки сервісу або розбийте складну задачу між кількома різними процесами та узгодьте їх роботу між собою.

Ознайомтесь із загальними алгоритмами, як будуються захищені рішення, надійні до введених даних користувачем, великої кількості та навмисно заплутані. Валідація даних — грає важливу роль під час розробки API сервісів, розуміння існуючих типів атак та слабких місць системи дає вам новий напрямок розвитку та вдосконалення. Додайте валідацію даних до вашої системи, пройдіться по OWASP top 10 і перевірте, чи не вразлива вона.

Обов’язково приділить увагу тестуванню, benchmarks для перевірки та виявлення ліпшого алгоритму, performance аудити вашого рішення, його оптимізацію. Часто зустрічаю помилку передчасної оптимізації, це робить код складним для розуміння та підвищує ризик помилок. Golang має великий потенціал, якщо його використовувати правильно. Відстежуйте та оптимізуйте вузькі місця, це може бути геть не те, що ви передбачали. Go test, go test -bench, go tool pprof — ваші помічники у цьому. Розуміння теорії тестування стане у нагоді, можна починати з перегляду виступів The Art of Testing. Які є типи тестування, для чого вони використовуються, які інструменти існують для цього (багато з них розроблені на Golang). Це розширить ваш арсенал інструментів, і також буде гарним плюсом на співбесіді.

За моїм досвідом, маючи базу з програмування, достатньо 3-5 місяців для переходу на production level використання технології Go (звісно, найефективніший варіант — це приєднатись до команди). Процес вдосконалення безперервний, більш розширений список літератури для всіх рівнів можна знайти на github. Працюйте з ним регулярно.

Сергей Мариеха, DevOps Engineer в MacPaw

7+ лет опыта в ІТ (3 из них в Go)

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

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

Алгоритмы и структуры данных. Да, да, да! Не учите их для галочки, учите их для себя! Скорее всего, вы просто будете гонять запросы между JSON/gRPC API, а задачи, связанные с алгоритмами, вы будете встречать только на собеседованиях, но важно понимать, что эти знания всегда будут актуальными и всегда пригодятся, когда именно под вот эту нестандартную задачу не окажется готового решения или библиотеки, которая бы удовлетворяла ваши нужды.

Книги. Начать, пожалуй, стоит с хорошей книги. Книг по Go есть уже достаточно много, но лишь несколько из них достойны внимания и действительно могут называться книгами, а не брошюрами. Я бы выделил The Go Programming Language от Алана Донована и Брайана Кернигана.

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

Шпаргалки. Часто забываешь самое простое. Go by Example на какое-то время станет постоянно открытой вкладкой в браузере.

Читайте классику. Как я уже говорил, самое крутое в Go — это его сообщество. За годы существования у него появились лидеры мнений, чьи мысли, посты в блогах, твиты и, конечно же, код, взрывали массы разработчиков бурными обсуждениями, что вело к новому витку развития языка. Многие из постов стали буквально «классикой». Приведу лишь некоторые из материалов:

Будьте в тренде. Фоловте в Twitter активных участников Go сообщества, читайте Хабр, общайтесь на Reddit, конечно же, читайте официальный блог Go и вступайте в сообщества в Slack, ходите на митапы и конференции, подписывайтесь на каналы в Telegram (например, на мой @golangdigest). Экспериментируйте с новыми подходами и технологиями. Если кратко — старайтесь быть в тренде всех новинок, это поможет вам расти и держать свою рыночную стоимость.

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

Тренируйтесь. Решая задачи, вы выработаете навык видеть определенные шаблоны решений, как только вы встречаетесь с проблемой.
LeetCode и HackerRank помогут вам в этом. Начните контрибьютить в open source, заведите пет проект, просите хороших специалистов ревьювить ваш код. Адекватно воспринимайте критику.

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

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

LinkedIn

13 комментариев

Подписаться на комментарииОтписаться от комментариев Комментарии могут оставлять только пользователи с подтвержденными аккаунтами.

Почему до сих пор не объявился Валялкин, я уже волнуюсь?

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

Дуже цікаво та синтетично! Дякую хлопці! Навіть забагато інформації як на мене :) Може і дезорієнтувати декого з новачків. Найважливіша порада, це Слек: gophers.in.ua.

Мені дуже подобається Golang.
Але є декілька речей які я ще не до кінця зрозумів.

Які best practices для роботи із пакетами?
Я не хочу всю програму тримати в одній папці. Набагато зручніше структурувати по підпапках (і інших мовах це будуть якісь класи і підкласи в namespace) . а у Го це вже получаютья інші пакети які потрібно включати із використанням повного шляху від $GOPATH
що робити коли я не знаю де в кінцевому рещультаті буде моя програма? я не знаю шляху . а відносний path не можна використовувати.

Як best practices для роботи із помилками?
Вже привик після кожного викклику функції перевіряти чи «if err != nil {» . Але все ще враження , що щось роблю не так. Особливо коли функція повертає декілька значень. Тоді при кожній помилці потрібно повернути якісь пості значення для всіх аргументів . Мають бути якісь правильні підходи для цього

Юніт тести принято робити без моків?
Не все вдається написати так щоб обійшлося без моків. Як це на практиці вирішується? Дійсно можна все покрити без використання моків?

Може порадите якісь статті.

Слушні питання.

Які best practices для роботи із пакетами?

З приводу «не хочу тримати в одній папці» — тут все просто. В Go папки використовуються інакше ніж в багатьох мовах, де вони фактично виконують роль «неймспейсів» і допомагають групувати файли. Папка в Go це окремий пакунок — тобто окрема абстракція, окремий модуль програми. Це просто потрібно прийняти як є і звикнути, або, як інколи кажуть «забути, що ви знали раніше».

Тому в Go, насправді, дуже простий алгоритм роботи з пакетами — будь яка програма чи бібліотека починаєтся з одного пакунку, нема шо думати. Коли код розростається, то потрібно дивитись не на «кількість файлів», а не кількість та глибину абстракцій та типів, і зв’язки між ними. Тоді в якийсь момент стає очевидним, що код вже настільки виріс, що ось таку і таку частину можно сміливо винести в окремий підпакунок. Це зменшить кількість файлів і складність «головного» пакунку, і, потенційно, поліпшить розуміння структури програми і покращить читабельність (за рахунок зміни назв на кшатлт func NewFoo() -> foo.New()).

Але плодити пакунки доки на то не виникла потреба це, як правило, лише спроба використовувати пакунки як неймспейси, що, хоча і не є помилкою, але веде до заплутаного коду, який потім складно рефакторити.

Абсолютний шлях це теж річ, до якої треба звикнути, і яка стимулує зберігати весь свій код у впорядкованому місті (GOPATH). Насправді, це дуже зручно. Я пам’ятаю як до Go в мене домашня директорія була місивом з папок типу Work/, Code/, Projects/ і т.д. але після переходу на Go я тепер тримаю в GOPATH (який в мене виставлений в ~ — домашню директорію) всі проекти, на всіх мовах. Це дуже зручно, тому що одразу знаєш де що шукати (типове місце розташування проектів — ~/src/github.com/mycompany/project). Якщо ж це просто код для тестування фіч чи забавок, який я не планую викладати на гітхаб, то такий код в мене лежить в ~/src/test/ — шляхи імпорту тоді є ’import "test/myproject/subpackage«`.

Коли проект переноситься/перейменовується — що, на моїй практиці, стається не дуже часто (може пару раз на пів-року), то це дуже простий find-and-replace, і навіть вбудована go fix вміє це робити (але потрібно згадувати точний синтаксис, тому будь який find-and-replace виходить швидше)).

Як best practices для роботи із помилками?

Це взагалі моя улюблена тема, тому що Go вчить людей поважати помилки. Після інших мов майже всі намагаються «перекласти» відповідальність за обробку помилок на мову, на «магічні» механізми обробки, але це призводить до того, що в більшості програм помилки тупо не обробляються. Навіть більше, це стимулює людей думати про код обробки помилок як про щось не важливе, як про якийсь «додатковий код», код «який можна написати потім, коли буде час», код який треба сховати кудись вниз подалі і таке інше.

Go каже просту річ — помилки це такі самі значення, як все інше. Якщо ви повертаєте якусь змінну з функції, скажімо Sqrt, то ви щось маєте зробити з тим значенням (інакше, навіщо викликати?). Так само і з помилками — або обробляйте їх, або примусово зибивайте (_ = foo()). Програми на кшталт errcheck допомагають тут бути чесними.

Одна з головних речей яку потрібно зрозуміти про помилки в Go, що це не просто «if err != nil { return err }». Так, прокидування помилки наверх часто має сенс, але саме тому воно і використовується — тому що має сенс. Якщо потрібно щось інше — з помилками можна робити все що потребує ситуація, це просто значення. Якщо потрібен стектрейс — додавайте його в помилку, нема проблем. (Багато розробників думають, що стектрейси потрібно вивалювати завжди і всюди, але це не так). Потрібна якась не стандартна інформація (коди помилок від драйвера і т.д.) — без проблем, створюєте тип. який задовольняє інтерфейсу error і використовуєте його. Потрібно надрукувати в лог і проігнорувати помилку — будь ласка.

В будь якому випадку, Go через якийсь час сформує у вас звичку одразу відповідати на питання — що программа буде робити у випадку помилки. Це підвищує шанси, що ви не будете відкладати обробку помилок на потім. Також, ця «локальність» (error path близький до happy path) має дуже позитивний ефект того, що будь хто, читаючи ваш код, буде розуміти як програма себе веде у випадку помилок (не потрібно скролити кудись чи бігати по купі файлів/класів, шукаючи, що воно може повернути).

Юніт тести принято робити без моків?

Моки дуже просто робити через інтерфейси, коли є потреба. Є програми типу go-mock які автоматизують це, але з ними треба бути дуже обережними.

Проблема з моками в тому, що дуже легко поставити це на «конвеер» і почати тестувати моки, а не реальні програми. В мене був випадок, коли в пул-ріквесті який мав додати тести в пакунок на 1 файл та 500 строк коду, було додано 3000 строк, 15 нових файлів (з них більшість код моків), і купа тестів, які тестували ці моки. Іронія була в тому, що як раз найбільш критичний код не був протестований — можна було вставити ділення на нуль в найважливіший функціі в пакунку і ці 3000 строк тестів з моками не зловили би проблему. Фактично ті тести тестували, що моки працюють правильно. І, на жаль, я цей патерн бачу регулярно, тому його потрібно нещадно нищити :) А моки використовувати дуже обережно і з розумом.

Там де дійсно складно зробити unit-тести без моків (наприклад, якщо потрібно бігати в мережу, або змінювати файлову систему, або модифікувати системний час тощо), то це вагома причина використати моки.

Статті на тему помилок:

— 8thlight.com/...​dling-patterns-in-go.html
— blog.golang.org/errors-are-values (переклад habr.com/post/269909)

Про пакунки:

— medium.com/...​ckage-layout-7cdbc8391fc1 (переклад habr.com/post/308198)

Дякую за розгорнуту відповідь.

То як ви працюєте із функціями типу

func myFunc(a int) (int,string,[]byte,string,error) {
  a1, err := otherFunc(a)

 if err != nil {
   return 0,"",nil,"",err
 } 

 a2, err := yestAnotherFunc(a)

 if err != nil {
   return 0,"",nil,"",err
 } 
 a3, err := almostFinalFunc(a1,a2)

 if err != nil {
   return 0,"",nil,"",err
 } 
 .......
}

Оці
return 0,"",nil,"",err
які повторяються декілька разів.
мене напрягають. Хочу знайти якись правильний спосіб для таких ситуацій.
Поки що зійшовся на тому щоб давати імена значенням які повертаються і просто return

func myFunc(a int) (b int,s1 string,ch []byte,s2 string, err error) {
...
if err != nil {
return
}
...

Якщо ви повертаєте 3 чи більше (у Вашому випадку 5) змінних, це вже питання дизайну — скоріш за все ця функція починалась з повернення 2-х змінних, а потім по принципу «робити так як вже зроблено» розрослась при рефакторінгах до сучасної версії. Але якщо ці 4 змінних (окрім помилки) таки пов’язані, то можливо розумніше їх відокремити в окрему структуру і повертати знову 2 значення — це чистіше, простіше та зрозуміліше.

Когда говорят про проблемы пакетов в Go, то обычно имеется в виду, что нельзя просто так для отдельно взятого проекта взять отдельно взятую версию пакета. Т.е. аналог pom.xml / composer.json / gemfile / package.json, где указывается версия. Когда вам это нужно, это нетривиально (хотя мне пока не было нужно).

Можливо, використовуючи наприклад Glide github.com/Masterminds/glide
в glide.yaml файлі вказуєте шлях до пакета на github і номер коміта(тобто версію)

Ну кто бы ещё написал самый длинный и популярный ответ в статье по GO? Спасибо)

1. Возможно я не совсем правильно понял вашу проблему, но все же постараюсь ответить. В Go принято делать вещи как можно проще, это касается и стуктуры проекта. Если у вас например API 3-4 эндпоинта, нету смысла плодить многое множество поддиректорий.
Возможно стоит прочитать вот это:
rakyll.org/style-packages
medium.com/...​ckage-layout-7cdbc8391fc1
www.ardanlabs.com/...​-work-in-go-language.html
Возможно прольют немного света на идеологию пакетов в Go

2. Прямо вот голден стандарта нету. Старайтесь разбивать ваши функции так что бы в одной функции не было 100500 вызовов где нужно хендлить ошибки. Прочитайте:
dave.cheney.net/...​rs-handle-them-gracefully
dave.cheney.net/...​ste/gocon-spring-2016.pdf
dave.cheney.net/tag/error-handling
www.ardanlabs.com/...​andling-in-go-part-i.html
www.ardanlabs.com/...​ndling-in-go-part-ii.html

3. Вот выступление Митчела Хашимото из HashiCorp. Наверное личший материал что есть про тестирование в Go. Мокать что-то для тестов абсолютно нормальная практика.
www.youtube.com/watch?v=yszygk1cpEc
Слайды: speakerdeck.com/...​/advanced-testing-with-go

+1 к golangbootcamp
Отличное дополнение к началу пути в Go

Ну и посоветовал бы подписаться на medium.com/tag/golang — там очень много действительно ценного и нового

зы: спасибо Сергей Мариеха (@heartwilltell) за познавательный и веселый канал в Telegram )

Спасибо, стараюсь :)

Подписаться на комментарии