Go (Golang) Vocabulary: 30 Terms Every Go Developer Needs to Know (англійською)
Вивчіть основний словниковий запас мови Go — goroutines, канали, інтерфейси, defer, контекст і понад 25 інших термінів, пояснених за допомогою прикладів розмов з розробниками.
Go (часто називається Golang) відзначається своєю простотою, швидкою компіляцією і відмінними примітивами одночасності. Незалежно від того, чи ви приєднуєтесь до команди розробників Go- first, чи читаєте код інфраструктури, написаний мовою Go, цей словник допоможе вам слідкувати за технічними обговореннями і чітко спілкуватися з вашими колегами.
Основні поняття мови
Goroutine
** Goroutine ** — це легка, одночасно виконувана функція, якою керує середовище виконання Go. Ви запускаєте гороутин з ключовим словом go. Горутини набагато дешевші, ніж потоки ОС — програма може запускати десятки тисяч з них одночасно.
«Спін догори рутину для кожного запиту, щоб ми обробляли їх одночасно.» «У нас є витік горотини — горотини починаються, але ніколи не закінчуються. Перевірте логіку каналу»
Channel
Канал є основним механізмом Go для комунікації між go-програмами. Ви надсилаєте значення на канал з <- і отримуєте з нього таким же чином. Канали можуть бути буферизованими (з чергою) або не буферизованими (синхронними).
«Передай результати назад через канал, щоб головний горитин міг їх зібрати» «Ми використовуємо буферизований канал з пропускною здатністю 100, щоб уникнути блокування виробників»
Горутинський протік
** Витік горорутини ** відбувається, коли горорутина запущена, але ніколи не завершується — зазвичай, тому що вона заблокована у очікуванні на каналі, до якого ніколи не записується або який ніколи не закривається. Утечки з часом збільшуються і вимагають пам’яті.
«Служба повільно споживає все більше пам’яті. Я підозрюю протікання горутина — давайте перевіримо з
pprof. “
WaitGroup
** sync.WaitGroup ** використовується для очікування завершення збірки команд- ланцюгів. Ви викликаєте Add(n) перед запуском goroutines і Done() у кожному goroutine, коли він закінчується. Wait() блокує, поки лічильник не досягне нуля.
«Використовуйте
WaitGroup, щоб почекати, поки всі goroutines завантаження завершаться, перш ніж повернутись»
Mutex
** sync.Mutex ** забезпечує взаємне виключення — тільки один гороутин може тримати замок в один момент часу. Скористайтеся цим пунктом, щоб захистити спільні дані від одночасних записів.
До карти можна отримати доступ за допомогою декількох горотунів — захистити її з
Mutexабо використовуватиsync.Map
Інтерфейси і структури
Interface
Interface в Go визначає набір методів. Будь-який тип, що реалізує ці методи задовольняє інтерфейс — не потрібно явне оголошення. Це називається * неявним * або * структурним * типуванням.
«Наша функція приймає інтерфейс
io.Reader, тому вона працює з файлами, мережевими з’єднаннями або буферами в пам’яті — будь-що, що реалізуєRead» «Визначте невеликий інтерфейс, який захоплює саме ту поведінку, яка вам потрібна — не імпортуйте весь конкретний тип»
Struct
** struct ** — це набір іменованих полів. Структури є основним способом визначення типів даних в Go. Вони не мають спадковості — замість цього використовується композиція.
«Створити
Userструктуру з полями дляID,Name, і
Embedding
** Вбудовування ** - це спосіб Go досягти повторного використання коду. Ви вбудовуєте одну структуру всередину іншої, і зовнішня структура автоматично успадковує поля і методи внутрішньої структури.
Ми вбудовуємо
BaseHandlerв кожну обробку структури, так що вони всі отримують журнал і конфігурацію безкоштовно
Метод приймання
** Приймач методу ** — це тип, з яким пов’ язано метод. У мові Go ви визначаєте методи поза тілом структури і вказуєте тип приймача у підписі функції. ** Приймач вказівника ** ( *T ) дозволяє методу змінювати структуру.
«Використовуйте тут приймач вказівника, щоб метод міг оновити поля структури» Метод використовує значення-реципієнта, тому він працює на копії — зміни не зберігаються
Обробка помилок
Error
Обробка error в Go явна — функції повертають error як останнє значення повернення. Викликачі повинні перевірити, чи помилка nil перед використанням результату.
Не ігноруйте повернуту помилку — завжди перевіряйте
if err != nil«Оберніть помилку з контекстом перед поверненням її:fmt.Errorf("failed to open file: %w", err)..»
Паніка і відновлення
** panic ** зупиняє звичайне виконання і розмотує стек — подібно до винятку. ** recover ** перехоплює паніку і дозволяє програмі продовжувати, зазвичай всередині функції defer.
«Не панікуйте через звичайні помилки — паніка є для справді невідновлюваних ситуацій» HTTP framework використовує
recoverв середньому програмному забезпеченні, щоб ловити паніки і повертати 500 замість аварії сервера
Паралельні шаблони
defer
** defer ** розкладає виклик функції, який буде виконано, коли повернеться навколишня функція, незалежно від того, як вона повернеться (звичайно або через паніку). Зазвичай, його використовують для очищення: закриття файлів, звільнення блокувань або ведення журналу.
«Використовуйте
defer file.Close()відразу після відкриття файлу — таким чином ви ніколи не забудете його закрити» «Defers виконуються в порядку LIFO, тому останнійdeferзареєстрований виконується першим»
Контекст
** context.Context ** переносить терміни, сигнали скасування і значення обсягу запитів через межі API. Майже кожна функція Go, що робить вхід/вихід, повинна приймати context.Context як свій перший параметр.
«Передавати контекст запиту до запиту бази даних, щоб він автоматично скасувався, якщо клієнт роз’єднається.» «Контекст має приєднаний термін — якщо операція триватиме довше, вона буде скасована.»
select
Інструкція ** select ** очікує на дії декількох каналів і продовжує з тим, який з них готовий першим. Це спосіб Go мультиплексувати одночасні операції.
«Ми використовуємо
selectз каналом тайм-ауту, щоб скасувати операцію, якщо вона триває довше 5 секунд»
Tooling
Модулі go
** Модулі Go ** (введені у Go 1. 11) є стандартною системою керування залежностями. Модуль визначається файлом go.mod, який вказує шлях модуля і версії залежностей.
Запустити
go mod tidyдля видалення невикористовуваних залежностей і додавання відсутніх Перевірте файлgo.modдля мінімальної необхідної версії Go
йдіть до ветеринара
** go vet ** — це інструмент статичного аналізу, який повідомляє про підозрілі конструкції, які, ймовірно, є вадами — речі, які компілятор дозволяє, але які, ймовірно, є неправильними, наприклад, неправильні рядки формату fmt.
Запустити
go vet ./...перед тим, як натиснути — це ловить багато поширених помилок
Перейти до fmt
** go fmt ** — стандартний формататор коду Go. На відміну від багатьох мов, Go має один офіційний стиль, який забезпечується цим інструментом. Всі коди Go повинні бути gofmt -форматованими.
Форматуйте код з
go fmt ./...перед відкриттям PR — інакше лінтер зазнає невдачі «Немає дискусії про форматування в Go —gofmtвирішує, і всі слідують за ним»
pprof
** pprof ** є вбудованим інструментом профілювання Go. За допомогою цієї програми можна створювати профілі використання процесора, розподілу пам’ яті, стеків графіків і багато іншого. Ви виставляєте кінцеву точку /debug/pprof або запускаєте go test -cpuprofile для збору профілів.
«Служба повільна під навантаженням — давайте приєднаємо
pprofі подивимося, куди йде час процесора»
пройти тест
** go test ** — вбудований тестовий запуск. Тестові файли закінчуються на _test.go і тестові функції починаються з Test. Бенчмаркові функції починаються з Benchmark.
Запустити
go test -race ./...для перевірки на перегони даних — це повільно, але ловить багато помилок одночасності
Як використовувати цю функцію в прикладі
** В перегляді коду: **
«Ця горутина не має можливості бути скасована — передайте
context.Contextі перевірте її в петлі» Ви блокуєте мутек, але не відкладаєте розблокування — якщо функція панікує, блокування ніколи не буде звільнено
** У системному проектуванні: **
«Go-програми дозволяють легко обробляти десятки тисяч одночасних з’єднань. Ми можемо створити горо-програму на з’єднання, не турбуючись про надмірну роботу потоку»
** Під час зневадження: **
“Службова пам’ять продовжує зростати. Давайте візьмемо
pprofпрофіль купу і перевіримо на витоки goroutine»
** При поясненні Перейти до колеги: **
“Інтерфейси Go є неявними — вашому типу не потрібно декларувати, що він реалізує інтерфейс. Якщо він має правильні методи, він задовольняє його автоматично»
Словниковий запас мови Го відображає її філософію: простий, чіткий і прагматичний. Після того, як ви ознайомитеся з цими термінами, вам буде набагато легше слідкувати за обговореннями коду і дизайну Go.