Путь Golang
411 subscribers
16 photos
2 files
37 links
Всё о Golang

Ресурсы и материалы: https://t.iss.one/waygolang/12

Кроме чата, Golang обсудить можно тут: https://t.iss.one/gogolang
Download Telegram
#go #rnotes #release ⚡️⚡️⚡️ Вышел перенасыщенный новшествами go версии 1.18:
https://go.dev/doc/go1.18

Отмечу наиболее интересное:
• Дженерики 👽 Начало. Много отложено на 1.19
• К дженерикам прилагаются экспериментальные пакеты — аналоги стандартных, основанные на дженериках: x/exp/constraints , x/exp/slices и x/exp/maps
• В компиляторе исправлены давние косметические ошибки и некоторые программы, которые ранее компилировались, вдруг перестанут
• Изменения в garbage collector
• Новые оптимизации в компиляторе
• Оптимизация линковщика, уменьшающая размер бинарника
• Порт AMD64 умеет теперь выбирать разные наборы процессорных команд
• runtime/debug.ReadBuildInfo теперь содержит и информацию о системе контроля версий, которая была во время сборки
• Новый пакет net/ip. Поддерживает сравнение и может быть ключом
• В пакетах bytes и string новая функция Cut. Это упрощенная функция для выделения префикса и остатка
#go #git #windows #ssh Часть I. Так получилось, что на работе мы используем Windows. Мне для одного проекта потребовалось использовать пакеты из приватных репозиториев. И из шкафа посыпались скелеты.

☝️ Современный GO умеет работать с Git, Subversion, Mercurial, Bazaar, и Fossil [1], но я рассматриваю только Git.

👉 Отмечу одну важную деталь: go mod ... и go get ... «ходят» не напрямую в ваш репозиторий, а через прокси, контролируемый значением переменной GOPROXY. Посмотрите, что говорит go env [2]. GO не просто пользуется прокси, а сверяет с базой контрольных сумм из переменной GOSUMDB. Переменные GONOPROXY и GONOSUMDB указывают, для каких путей импорта не будет использоваться прокси и/или база сумм. Переменная GOPRIVATE перечисляет пути импорта, для которых не будут использоваться ни прокси, ни суммы. Работу с приватными репозиториями следует начинать с настройки GOPRIVATE, ключ -w запишет переменную:
go env -w GOPRIVATE="git.mysecret.com/myrepo,git.supersecret.com"

🌧 Подвох кроется в том, что GO подавляет ввод пароля при работе с git. Что-то с этим придется делать.

🍏 Первый способ заключается в сохранении логина и пароля через настройку конфигурации [3]:
git config credential.helper store
или
git config credential.helper cache
Затем надо «поработать» с нужными приватным репозиториями напрямую командами git, чтобы он запросил, а затем запомнил логин/пароль:
git clone или git pull или git push
В случае store git запомнит логин/пароль в файл, в случае cache — временно в память. Строго говоря, там довольно гибкая система этих credentials, можете почитать для себя. Это работает для доступа по https (умолчание). Можно сразу задать пользователя:
git config credential.https://example.com.username myusername
Ещё один способ — указать git переписывать URL [4]:
git config --global url."https://api:$[email protected]/".insteadOf "https://github.com/"

🍐 Но что, если требуется использовать SSH (например, используется gitolite) и соответственно с ключами SSH? ...

Продолжение дальше...

[1]
https://go.dev/ref/mod
[2] https://proxy.golang.org/
[3] https://git-scm.com/docs/gitcredentials
[4] https://git-scm.com/docs/git-config#Documentation/git-config.txt-urlltbasegtinsteadOf
#go #git #windows #ssh Часть II. Так получилось, что на работе мы используем Windows. Мне для одного проекта потребовалось использовать пакеты из приватных репозиториев. И из шкафа посыпались скелеты.

... продолжение

🍐 Но что, если требуется использовать SSH (например, используется gitolite) и соотвественно с ключами SSH? Используем перенаправление:
git config --global url."ssh://[email protected]/".insteadOf "https://examples.com/"
Это заставит git использовать протокол SSH для выбранного URL.

🌶 Если ключ SSH можно хранить прямо на машине, то всё относительно просто. А вот если на ключе SSH должен стоять пароль, то начинаются вопросы. Нам требуется ssh-agent

На современных Windows 10 и 11 прямо в поставке идёт Windows-порт OpenSSH [5], его из коробки видит Git для Windows. Всё будет работать само. Кроме ssh-agent. После выполнения в PowerShell этих простых команд, в Windows появится сервис ssh-agent, который будет запускаться автоматически при перезагрузке компьютера [6][7]:
Get-Service -Name sshd | Set-Service -StartupType Automatic
Start-Service sshd
Командой ssh-add можно добавить ключи в агента. Никаких переменных окружения не надо настраивать. Современный агент работает через именованный канал (named pipe) [8]. Переменная SSH_AUTH_SOCK не используется ssh-agent в Windows.

В Windows OpenSSH ssh-agent запоминает добавленные ключи в реестр Windows, откуда считывает их при перезагрузке.Эти ключи может использовать только тот пользователь, который их добавил. Но если у пользователя Windows нет пароля, то ключ оказывается доступен для всех [9], и придется каждый раз удалять его через ssh-agent -d или ssh-agent -D

☣️ Этим недостатком не обладает старый добрый PuTTY. Можно настроить его.

☝️ Стандартная поставка Git для Windows включает команды start-ssh-agent.cmd и start-putty-agent.cmd. Представляют исторический интерес.

🏆 В современном Windows есть подсистема WSL2 (Windows Subsystem for Linux), и можно пользоваться ею. Ставим Windows Terminal (предупреждаю, без него без слез невозможно работать в Linux-консоли), инициализируем WSL2 [10] и просто работаем. Там и агент сразу запустится. С WSL2 умеют работать и vim, и VSCode [11] и GoLand [12]. Смотрите, для VSCode достаточно набрать code . внутри вашего воркспейса в WSL!

🛠 Важно! И PowerShell, и WSL2, и OpenSSH — это часть поставки Windows. Они просто есть. Windows Terminal является родной программой Microsoft, но в Windows 10 его придется через «Приложения Microsoft», а в Windows 11 он идет в поставке системы.

[5] https://docs.microsoft.com/en-us/windows-server/administration/openssh/openssh_install_firstuse
[6] https://docs.microsoft.com/en-us/windows-server/administration/openssh/openssh_keymanagement
[7] https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/get-service
[8] https://github.com/PowerShell/Win32-OpenSSH/issues/1136
[9] https://github.com/PowerShell/Win32-OpenSSH/issues/1487
[10] https://docs.microsoft.com/en-us/windows/wsl/install
[11] https://code.visualstudio.com/docs/remote/wsl
[12] https://www.jetbrains.com/help/go/2022.1/how-to-use-wsl-development-environment-in-product.html
#go #rnotes #release Go версии 1.19 вышел конечно несколько недель назад, но я всё же хочу на него обратить внимание:
https://go.dev/doc/go1.19

🤷‍♂️ В дженериках внезапно ничего нового не произошло

👍 Произошло знаковое событие — у Go наконец-то появилась описанная модель памяти. Что это? Это формализация поведения Go при конкурентной работе с переменными. Большинство статей про версию 1.19 делают акцент на этом и разбирают, что именно там внутри. Однако, в самом документе написано примерно следующее: «Если Вам необходимо прочитать этот документ — Вы слишком умный. Не будьте умным»
https://go.dev/ref/mem

📃 Go doc теперь умеет работать с простенькой разметкой. Т.е. можно делать заголовки, параграфы, внешние и внутренние ссылки, нумерованные и ненумерованные списки, и даже блоки кода. И go fmt умеет это проверять
https://go.dev/doc/comment

• Новый тег сборки //go:build unix, включающая в себя aix, android, darwin, dragonfly, freebsd, hurd, illumos, ios, linux, netbsd, openbsd, solaris

• Реализован soft memory limit — GC будет пытаться его соблюсти. Также теперь запускается несколько маленьких GC, вместо одного большого
https://go.dev/doc/gc-guide

‼️ Для новых горутин начальный размер стека теперь задается на основе статистики использования стека горутинами. Это к слову о пулах горутин

• На UNIX-системах RLIMIT_NOFILE теперь выставляется автоматом в максимально возможное значение при импорта пакета os

• Увеличена производительность конструкции switch за счет jump tables

В sync/atomic новые типы Bool, Int32, Int64, Uint32, Uint64, Uintptr, Pointer. Причем Pointer использует дженерики (первое использование в стандартной библиотеке), чтобы избежать конвертации в/из unsafe.Pointer

‼️ crypto/rand теперь сам не буферирует чтение. Обратите на это внимание

‼️ В принципе много мелких, но чувствительных изменений в crypto/*

Подарок всем, кто работает с разным IoT и бинарными данными. И fmt, и encoding/binary теперь оснащены функциями семейства Append*. Например можно сделать fmt.Appendf(buf, "%s", "карамба") или binary.BigEndian.AppendUint16(buf, modbusReg), прощай танцы вокруг bytes.Buffer

flag обзавелся функцией TextVar упрощающий задание типизированных данных в строках, типа IP-адреса, времени и так далее

• Результаты io.NopCloser и io.MultiReader теперь реализуют метод WriteTo

• В net/http теперь можно задаваемые пользователем коды 1xx в ResponseWriter.WriteHeader

В net/http появилась функция MaxBytesReader, обратите на неё внимание, так как сильно упрощает жизнь

• Любителям подуть щёки знанием алгоритмов сортировок — в sort он изменился

👍 В`time` Duration теперь умеет Abs. Очень полезно для проверки попадания в отрезок времени +-
#go #guide #google Google выпустил руководство по стилю написания кода на Golang. В Google:
https://google.github.io/styleguide/go/index

👉 Это три документа: общее руководство по стилю, расширенное руководство по каким-то конкретным темам и практики.

👉 Да, есть мнение, что это руководство «нормально делай — нормально будет» (c) Подольский. Документ действительно максимально насыщен и лаконичен. Выжимки делать трудно. Однако, почему-то заметное большинство коллег нормально не делает. А монструозное руководство с разжевыванием от Uber даже я не осилил: https://github.com/uber-go/guide/blob/master/style.md

☝️ Основные принципы стиля:
Читаемость. Это ПЕРВОЕ правило стиля
Простота
Лаконичность
Поддерживаемость
Согласованность

Читаемость. Код должен быть ясен для любого читающего. Два аспекта:
- Что код на самом деле делает?
• задавайте смысловые имена переменным;
• добавляйте дополнительные комментарии;
• разбивайте пробелами код и комментарии;
• раскладывайте код по разным функциям для модульности.
- Почему код делает то, что должен? Общий смысл в том, что понимание кода должно быть по мере чтения.
Приведен интересный на мой взгляд пример — функция strings.Cut, которая состоит из 4-ёх строк кода, но повышает в разы читаемость.

Простота
• код должен просто читаться сверху вниз;
• код не должен подразумевать, что читающий знает, что код делает;
• код не должен подразумевать, что читающий может запомнить весь предыдущий код;
• код не должен содержать не необходимых уровней абстракции;
• имена не должны отвлекать;
• все решения должны быть понятны читающему;
• комментарии должны описывать «почему», а не «что»;
• документация должна быть самодостаточной;
• код должен содержать понятные тестируемые ошибки;
• простой код часто противоречит «умному»;
• старайтесь использовать базовые конструкции языка (слайсы, мапы, структуры);
• если функция есть в стандартной библиотеке — используйте её;
• старайтесь использовать код Google.

Лаконичность
Приводится пример if err := doSomething(); err != nil { как пример лаконичного кода.

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

Согласованность
В целом, это про единообразие кода в рамках функции, файла, пакета, команды разработки, кодовой базы.

☝️ Руководство по стилю не заменяет effective Go https://go.dev/doc/effective_go , но расширяет его. «Не думайте, что Я пришел нарушить закон или пророков: не нарушить пришел Я, но исполнить.» (Мф. 5:17).

🫵 Стиль — это конёк golang на мой взгляд. Практики, руководства по практикам и стилям, доклады по практикам и стилям — всё в наших руках.
#go #rnotes #release Go версии 1.20 вышел конечно полтора месяца назад, но я всё же хочу на него обратить внимание:
https://go.dev/doc/go1.20

🤷‍♂️ В дженериках внезапно ничего нового не произошло.

Появилась конвертация из слайса в массив простым способом: [4]byte(x). Создаётся копия. Зачем это надо? А например чтобы получить comparable.

🤷‍♂️ Теперь интерфейсы могут удовлетворять ограничению comparable. Живите теперь с этим.

👉 У go build появился ключ -cover. Туда же пакет runtime/coverage. Все это бурно пропустили в описаниях, а меня заинтересовало, потому что ничего не понял. Что-то про интеграционные тесты: https://go.dev/testing/coverage

🔥 Компилятор научился в магию оптимизации по профайлу (PGO). Создаёте профайл pprof, подсовываете компилятору и или всё стало работать быстрее, или всё стало работать медленнее.

• Новый пакет crypto/ecdh для обмена ключами Диффи-Хеллмана (я обращаю внимание на криптографию)

Появилась поддержка множественных ошибок. Внезапно можно вернуть несколько %w в fmt.Errorf или сделать errors.Join(err, ... errN). Остановлюсь поподробнее. Считаю вредной штукой. Обработка ошибок в go может и была странной, но была идиоматичной и вынуждала обработать таки ошибку. И чем раньше, тем лучше. Теперь появился инструмент "да я не знаю, что делать с ошибкой, потом подумаю". И потом сложный путь разбора. Все кейсы, которые я смог придумать с парной ошибкой, только запутывались таким решением. Пример из proposal вообще не выдерживает никакой критики. Давать отдельные ошибки на логин и пароль является антипаттерном. Ещё одной неприятностью является то, что множественные ошибки могут теперь создаваться из-за человеческой ошибки за счёт множественного %w. Живите теперь с этим (c)

👍 Экспериментальный, но интересный пакет arena про арены памяти. Хотел написать "не лезьте туда". Да лезьте, конечно. Просто ради интереса. Идея арены простая. Если у нас много мелких аллокаций, то можно взять сразу большой кусок памяти и делать это всё там. Принцип как в append - взять с "запасиком".

🍄 Пакет http предоставляет костыль http.ResponseController. Смысл в том, что в func RequestHandler(w ResponseWriter, r *Request) добавляется возможность немного поуправлять вот этим w. Flush там сделать, или Timeout поменять. Если, конечно, изначальный тип содержит соответствующие методы. Да, у http.ResponseController под капотом тайп свитчинг.

🙀 Пакет crypto/rsa теперь использует новые алгоритмы с постоянным временем работы. Шифрование стало примерно в 20 раз дольше. Но всё ещё в пять раз быстрее дешифрования. Живите теперь с этим (c)

‼️ В пакете math/rand внезапно seed делается сам при инициализации. Если вы ожидали повторяемости при запуске, то этого больше нет (хотя, в этом случае ты немного странный, друг). Привет, обратная совместимость! Функции Seed и Read стали устаревшими.

🧌 Какой-то релиз странный получился. Как-будто бы открылось "политическое окно для хрени"



🇱🇹 Кстати. Я могу какие-то части своих излияний переводить на литовский язык. Но не понимаю, насколько это вообще надо. И насколько применимо.