LINUX.ORG.RU

Вышел Golang 1.17

 


2

3

Как всегда, релиз следует обещанию совместимости с Go 1.x. А значит что все существующие программы так же будут собираться Golang 1.17.

Изменения в языке

Указатель на массив

  • Преобразование из слайса []T в указатель на массив *[N]T, конструкцией вида go var array = (*[50]byte)(slice) Вызывает run-time panic при выходе за границы. Подробно.

unsafe

  1. unsafe.Add(ptr, len) = unsafe.Pointer(uintptr(ptr) + uintptr(len))
  2. unsafe.Slice, превращает указатель *T в слайс, unsafe.Slice(ptr, len) -> []T
Инструменты

Различные изменения в инструментах, включая

  • Сокращённый граф модулей для go 1.17 модулей.
  • Ленивая загрузка модулей
  • Отдельные блоки require в go.mod для косвенных зависимостей.
  • Добавлена поддержка комментария // Deprecated: в go.mod.
  • Удалена поддержка флага -insecure в go get -insecure
  • Если в go.mod отсутствует директива go, то версия принимается за go 1.11, а не за текущую. А для зависимостей с тем же изъяном за go 1.16 (о-оу).
  • Для модулей go1.17 команда go mod vendor теперь создаёт файл vendor/modules.txt и не включает go.mod и go.sum зависимостей.
  • Подавление запроса пароля при загрузке по SSH. Можно настроить.
  • Для обновления go.sum теперь стоит вызывать go mod download all как то было в go1.15.
  • Добавлен магический комментарий //go:build lines вместо // +build lines что бы [это ни значило]https://golang.org/design/draft-gobuild).
  • go run теперь позволяет запускать конеретную версию пакета, по типу go run example.com/cmd@v1.0.0
  • go vet бросает новые предупреждения для
    • //go:build and // +build lines
    • при подписке signal.Notify на канал без буфера
    • когда методы Is, As и Unwrap отличны от описанных в errors, но используются пакетом errors
  • cover теперь быстрее работает, но заметно только на огромных проектах
Компилятор
  • Аргументы передаются через регистры, а не стек. Что даёт ускорение около 5%, и снижение размера файла около 2%. Это только для 64-битных Linux, MacOS и Windows (linux/amd64, darwin/amd64, windows/amd64). Это изменения не касается безопасного кода, в основном относится к его unsafe части.
  • Так же улчшен формат runtime.Stack.
  • Функции содержащие замыкания теперь тоже могут быть встроены (inlined).

Компоновщик (linker)

  • Если используется внешний компоновщик, то опция -I передаётя ему.
Основные библиотеки

Cgo

  • Пакет runtime/cgo добавляет поддержку для передачи значений между Go и C. Посмотрите на runtime/cgo.Handle.

Разбор URL-query

  • Ранее, пакеты net/url and net/http принимали ; (точку с запятой) как разделитель наряду с &. Теперь это не так. И даже ошибка летит в лог, если встретится точка с запятой. Значения с ней игнорируются. Изменить поведение обратно для net/http можно с помощью [AllowQuerySemicolons]https://pkg.go.dev/net/http@master#AllowQuerySemicolons), но это сделано для безопсности.

И так далее включая небольшие изменения в библиотеках. Из которых, может стоит, отметить методы

  • time.Time.IsDST – летнее время
  • time.Time.UnixMilli и аналогичный ему UnixMicro для тех, кто не умеет делить сам
  • net.IP.IsPrivate
  • Методы Swap и CompareAndSwap для atomic.Value.
  • Для тестов добавлен флаг -shuffle для запуска тестов в хаотичном порядке.
  • Так же в тестах теперь есть методы T.Setenv (и для B тоже). Которые выставляют переменную на время теста или бенчмарка.

Текст новости исправлен и переработан @Shaman007 и другими корректорами

>>> Подробности



Проверено: Shaman007 ()
Последнее исправление: korvin_ (всего исправлений: 10)

Ответ на: комментарий от aist1

Мономорфизация для бедных

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

Опять же, вы смотрели код JIT? Почему бы не генерить отдельный код в рантайме для оптимизации горячего кода с полиморфизмом? Может JIT это уже умеет делать, но мне неприятно залезать в исходинки крестового уродца, чтобы удостовериться наверняка.

foror ★★★★★
()
Последнее исправление: foror (всего исправлений: 1)
Ответ на: комментарий от anonymous

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

ergo ★★★
()
Ответ на: комментарий от apt_install_lrzsz

Ну код то скомпилированный, какая х разница какая версия, это же не скрипт 🤷‍♂️ Но ты можешь указать в go.mod версию, что надо

ZogG
()
Ответ на: комментарий от anonymous

UB в том, что JIT-оптимизации могут легко поломать прикладной код, который нелегально использует sun.misc.Unsafe. Ты обновил JVM-ку и словил в проде «странные баги». Которые невозможно ни отловить, ни отладить.

aist1 ★★★
()
Ответ на: комментарий от anonymous

Чтобы работать в офисе, нужно быть fully vaccinated. Кто не хочет, продолжает сидеть в remote.

aist1 ★★★
()
Ответ на: комментарий от anonymous

Вот бесит что разработчики языка слишком большой упор сделали на скорость компиляции в ущерб элементарной функциональности.

Упор они сделали на простоту реализации компилятора. Функциональность - эта сложна! Пусть лучше «Googlers, not researchers, … not capable of understanding a brilliant language» (R. Pike) десять раз одно и то же пишут, всё нам работы меньше.

anonymous
()
Ответ на: комментарий от anonymous

я досихпор не понимаю зачем эти женерики нужны

Это говорит больше о тебе, чем о дженериках.

anonymous
()
Ответ на: комментарий от no-such-file

gcc

Зато говорят, что интероп go<->c гораздо быстрее и им даже можно пользоваться.

Быстрее, чем что? Вызов C кода из Go происходит через CGO, описание к которому гласит:

In order to use cgo … you’ll also need to first install a gcc compiler and have gcc … in your PATH environment … before compiling with cgo will work

Что как бы намекает на природу этого самого CGO. А пайковская поговорка забивает финальный гвоздь:

CGO is not Go

Иными словами, интероп только один. И с довольно большими задержками. Лет 7 назад был тред в рассылке на эту тему; не слежу, но, вроде, ничего с того времени не поменялось.

anonymous
()
Ответ на: комментарий от foror

Это сделано из-за невозможности использовать примитивы в дженериках.

Невозможность эта сделана сознательно. «Юзайте боксинг, нам так сильно проще». А то, что боксинг просаживает проиводительность на больших объектах памяти, так это архитекторов джавы мало волнует.

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

Я эту «новую реализацию дженериков» уже 10 лет жду. Скоро в криокамеру пора уже. Разморозь меня, когда они Valhalla допилят с value-типами. Которые изначально уже будут бесполезными относительно тех применений, для которых они, собственно, и нужны. Дажава, как язык, дизайнится людьми с CS-образованием.

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

То же самое с файберами, но тут хотя бы golang джавистам импульса придает. Project Loom даже слезно обещает что-то выкатить скоро. Не прошло и 10 лет.

aist1 ★★★
()
Ответ на: комментарий от anonymous

Какое бы ни было. «Юзать Unsafe напрямую» — это не понимать ничего в оптимизирующих компиляторах. Очень по-джавистки. «Там в JVM — магия, которая работает всегда». Ага, щаз.

Другое дело, что что-то типа Unsafe, должно было в публичном API появиться 10 лет назад. Но у JVM-щиков свои приоритеты.

aist1 ★★★
()
Ответ на: комментарий от aist1

Но у JVM-щиков свои приоритеты.

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

Потом, по рассказам очевидцев процессы там не самые располагающие. Чуть ли не предшественник cvs с ревью патчей по почте по разные стороны Атлантики.

это не понимать ничего в оптимизирующих компиляторах.

Справедливости ради это и к C относится. Много ли (особенно опенсорсного) софта корректно работает с -O3?

anonymous
()
Ответ на: комментарий от apt_install_lrzsz

Если проект не обновился и зависимость, я бы и так и так в продакшн не стал бы использовать ибо те, что не обновляются дырявые и кривые по-дефолту

ZogG
()
Ответ на: комментарий от anonymous

Потом, по рассказам очевидцев процессы там не самые располагающие. Чуть ли не предшественник cvs с ревью патчей по почте по разные стороны Атлантики.

Ну сейчас там всё нормально. Переползают с Mercurial на Git. просто их приоритеты даже сейчас несколько удивляют.

Справедливости ради это и к C относится.

Так это уже другая парадигма. Java UB не имеет, поэтому у джавистов нет даже понятия о том, что «что-то там может поломаться» из-за того, что какой-то недокументированный интерфейс вытащили. Еще спорили с командой JVM на публичных посиделках, что «вы никогда Unsafe не закроете, мы его используем потому что».

С Си совсем другая история. Там это черным по белому прописано. Поэтому, если чей-то код не собирается с -O3, то это уже другой диагноз. Это уже халатность, а не эльфизм.

aist1 ★★★
()
Ответ на: комментарий от ergo

Я могу вместо слайса сделать массив с запасом, чтобы точно хватило, эдак Go coords [20]Coord.

Но это костыль, слайс тут самое то. Или через interface{} и преобразовывать данные, но тоже костыль.

Ещё могли бы сделать чтобы можно сдеать перегрузку/протокол чтобы можно было создать своё сравнение, но нет.

func (this *A) Compare(a A) {
    // compare struct A
}

Ты не должен этого хотеть! Как авторы решили сравнивать только примитивные типы данных, так и сравнивай! Примитив - наше всё!

anonymous
()
Ответ на: комментарий от anonymous

Пайк — умный, но очень опиньонутый чувак. Я бы не «покупал» от него всё подряд. Ну и, соответственно, Go — тоже весьма опиньонутый язык.

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

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

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

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

aist1 ★★★
()
Ответ на: комментарий от anonymous

Быстрее, чем что

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

no-such-file ★★★★★
()
Ответ на: комментарий от aist1

Думаю их проблема в наследии и крестах. Где-то публиковались данные, что новому человеку нужен год, чтобы хоть чуть-чуть начать комитить в сырцы jvm на крестах. А про СУБД оракул на хабре была отдельная статья, там люди просто уже не понимают всю кодовую базу.

Поэтому такие задержки в реализации. Поэтому свежий ЯП с основателями не дедами и не хипстерами может легко уделать всё текущее легаси из 70-90-х.

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

foror ★★★★★
()

Поиски вдохновения и единомышленников Поиски вдохновения и единомышленников

@byko3y, есть github, …
Поищите интересные для вас проекты.
Бывает, что авторы проектов и e-mail свой публикуют …
На форумах

995 троллей и пять разработчиков, которым не интересны ваши задачи ...
anonymous
()
Ответ на: комментарий от foror

Думаю их проблема в наследии и крестах. Где-то публиковались данные, что новому человеку нужен год, чтобы хоть чуть-чуть начать комитить в сырцы jvm на крестах.

Дичь какая-то. Я за где-то полгода вечерами (!) разгреб Clang на столько, что встроил в него JIT, чтобы можно было вызывать полноценные «метафункции» на С++ во время компиляции. А так же хакнул парсер, чтобы его можно было вызывать из метафункций. Чтобы не конструировать AST «руками», а скормить парсеру фрагмент и получит его AST. Причем это всё в текущем «контексте». И это OSS проект, по которому оч мало документации.

Я смотрел код JVM, когда пытался разобраться, что там нужно для поддержки файберов сделать и сто уже сделано в рамках Loom. Там не то, чтобы «все просто». Я я разобрался довольно быстро. За день.

Я слышал аргумент, что «код JVM стал для нас очень душным, поэтому мы решили переписать JVM на Java и сделали Graal». Ну так что же вы так написали то? С плеткой кто-то заставлял? У V8, вон, совершенно нормальный код.

Плохой код? Взяли и отрефакторили. Любимое дело программистов.

Не в коде там дело совсем. А в менеджменте.

aist1 ★★★
()
Ответ на: комментарий от foror

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

Разморозь меня, ок? :) А то, боюсь, не доживу.

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

aist1 ★★★
()
Ответ на: комментарий от aist1

Т.е. вот что я имею в виду. Вот, например, есть известная проблема — недружественность Java к кэшам и современным иерархиям памяти. Что предлагают сделать? Panama, Foreign Segments, immutable value types, Valhalla (reified generics, primitives), SIMD,... Куча разных JCP, которые, безусловно, делают платформу существенно мощнее. Только все эти JCP ни вместе, ни по отдельности, и близко не подходят к C++ по возможностям.

Вот зачем это всё? Мы очень хотим использоваться в нише C++, но при этом очень не хотим предоставлять те возможности, которые эту нишу-то и создали.

Это же относится и к Go. Автор мечтал, что его язык будет использоваться одним образом, но он, на самом деле, стал использоваться другим образом. Он оказался на столько хорош, что пришли люди из других, более выразительных языков, и стали требовать привычных средств. Которые ломают изначальную философию. Вот сейчас запилят дженерики, против которых Пайк был изначально категорически (юзайте рантайм-полиморфизм).

То же самое и с Java. Все эти фичи, которыми сейчас платформу накачивают, никак не вписываются в её философию. Которая очень простая: не быть С++. Но так не получится. Чтобы быть в нише С++ надо быть С++.

aist1 ★★★
()
Последнее исправление: aist1 (всего исправлений: 1)
Ответ на: комментарий от anonymous

math.Min/Max ручками так и продолжишь писать?

У меня нет проблем. А вот лапшевидное что-то – это действительно проблема.

lazy8
() автор топика
Ответ на: комментарий от anonymous

Ещё могли бы сделать чтобы можно сдеать перегрузку/протокол чтобы можно было создать своё сравнение, но нет.

Так а кто мешает сделать своё сравнение и его использовать? Дрочку на операторы лучше сразу прекратить.

lazy8
() автор топика
Ответ на: комментарий от aist1

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

В Го изначально прицел на генераторы. Просто сообщество не хочет писать генераторы, а их заказчики это оплачивать. А генерики – способ стряхнуть эту работу на Гугл коллективным воем.

lazy8
() автор топика
Ответ на: комментарий от Legioner

Можно сделать GC, который гарантирует, что если на сборку уходит больше 1 мс, то он в нужный момент остановит сборку мусора на середине и просто запросит недостающую память у ОС (если того, что он собрал за 1 мс недостаточно для создания нового объекта).

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

Чтобы сборка мусора была не атомарной, а можно было «собрать чуть-чуть», объекты делятся на группы по тем же поколениям и другим параметрам.

KivApple ★★★★★
()
Последнее исправление: KivApple (всего исправлений: 2)
Ответ на: комментарий от aist1

Мы очень хотим использоваться в нише C++, но при этом очень не хотим предоставлять те возможности, которые эту нишу-то и создали.

Не вижу смысла переусложнять. Нужно просто дать очевидные и полезные вещи и они их делают. Список ты перечислил. Выжимать из железа все соки ценой переусложнения ЯП - нужно единицам.

Чтобы быть в нише С++ надо быть С++.

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

foror ★★★★★
()
Ответ на: комментарий от aist1

Я тоже выше писал, что не понимаю, зачем нужна «ява без явы» (т.е. без GC). По крайней мере в финансовой сфере. Единственное объяснение (точнее два) - это у нас исторически есть большое количество (бес)толковых программистов, которые слишком плохо говнякали на C++98, поэтому ява которая хотя бы без UB и может с чуть более толковыми анализаторами (хотя опять же, исторически).

Второй - это притом, что в финтехе большое количество толковых программистов на C++ (да вспомнить того ж Годболта), все равно очень тяжело находить людей, который хоть что-то могут.

И да, как замечено, что даже когда все эти фичи прикрутят в язык / VM еще несколько лет внедрять будут.

anonymous
()

@lazy8, ИМХО даже если бы вы убрали все согласные буквы из заголовка треда ничего катастрофического не было бы.
Не переживайте …

anonymous
()
Ответ на: комментарий от anonymous

bolgenos в принципе вполне можно пользоваться, а на v ничего кроме примеров с их сайта написать нельзя.

anonymous
()
Ответ на: комментарий от no-such-file

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

И получить непереносимый на обычный Go код?

anonymous
()
Ответ на: комментарий от foror

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

В C# все это уже сделали, и как-то не видно отжирания ниши крестов, скорее наоборот.

anonymous
()
Ответ на: комментарий от KivApple

Если бы все было так просто…

Во-первых, что значит остановиться? Gc использует Mark and sweep. То есть объекты исключаются из мёртвых, а не добавляются туда. То есть чтобы убедиться, что нет ссылок на объект, надо обойти все живые. Это, в отличие от счётчика ссылок позволяет грохнуть сразу много объектов с кольцевыми ссылками. Например, какой-нибудь бизнесс объект, который себя как хэнддер к своим подъобектам зарегистрировал.

Во-вторых, «попросить память у системы» это тот ещё потенциальный лаг. Я наблюдал ситуацию, когда обычный memmove (казалось бы, да?!) зависал на секунды из-за page fault.

anonymous
()
Ответ на: комментарий от anonymous

В C# все это уже сделали, и как-то не видно отжирания ниши крестов, скорее наоборот.

Так оно пилилось изначально под офтопик. Кто его всерьёз воспринимает? Даже сегодня под линухом нет нормальной IDE, я тут попробовал через VSCode в отладку SDK и обламался. Только свой код можно отлаживать… В 21 веке…

Опять же c# это тот еще переусложненный монстр со свистоперделками.

foror ★★★★★
()
Ответ на: комментарий от anonymous

непереносимый на обычный Go код

Тут ещё как посмотреть, как раз таки gccgo подход более «переносимый» в общем понимании.

no-such-file ★★★★★
()
Ответ на: комментарий от lazy8

В Го изначально прицел на генераторы.

Ты можешь объяснить, почему в языке, который изначально нацелен на кодогенераторы, до сих пор (третья декада 21-го века на дворе) нет аннотаций? И по этой причине те же веб-фреймворки делают карты роутинга через отдельные файлы? Хорошо, что есть хоть какие-то метаданные для поддержки ORM. Ума не приложу, как Пайк смог такой костыль проглядеть. Его надо было выдрать из языка, чтобы не позориться. Но кто-то продавил, чтобы можно было хоть как-то ORM делать без возврата в 70-е.

Что касается «кодогенераторы вместо дженериков». Удачи вам там делать мономорфизатор кодогенераторами. Вот мономорфизатор в Clang. Это, в совокупности, где-то 20% кодовой базы самого компилятора.

Мономорфные дженерики — это далеко не только «подставь вот сюда вот это тип». Это, в первую очередь, вывод типов + специализация кода. Сообщество такое тупо не осилит, вот и выклянчили у Гугла коллективным воем.

aist1 ★★★
()
Ответ на: комментарий от foror

Выжимать из железа все соки ценой переусложнения ЯП - нужно единицам.

Зачем тогда Unsafe достали из потрохов JVM, если это «нужно единицам»? Единицы могли бы и более подходящий язык использовать для своих частных задач, а не протаскивать лютый UB в продакшн.

Повторюсь, список ты перечислил и его активно пилят, заканчивают

Его не заканчивают, а только начинают. Это я тебе говорю как полупрофессиональный программист на С++ и профессиональный на Java. Мономорфные дженерики (Valhalla) могут пригодиться для Eclipse Collections, но и только. Файберы (Loom) в языке с таким GC, как в Java, не то, чтобы совсем бесполезны. Но их потенциал раскрыть не получится. Для попсы хватит, а высокопроизводиловка продолжит сидеть на С++.

Valhalla была бы хороша лет 10-15 назад. А сегодня это — ни о чем.

После чего джава спокойно отожрёт нишу крестов.

ЯП сложен не просто так, а «по причине». Парадигма С++ — это zero-cost надстройка над оптимизирующим AOT-компилятором. Java этим принципиально стать не сможет. У неё другая парадигма. Она тебя по-максимуму от железа отгораживает.

Java проиграла одну очень важную войну. Они надеялись, что все ринутся переписывать существующий код на pure java, но этого не произошло. А рантайм так и остался максимально огорожен от натива. И инерцию этой философии пока не получается переломить.

aist1 ★★★
()
Ответ на: комментарий от ergo

Считай это полупрофессиональным. Если я вижу достаточно основания для впиливания DSL (косты/бенефиты), я постараюсь его внедрить и (пере)использовать.

Если ты про мои эксперименты c Clang, то вот оно. Оно пока сейчас на паузе.

aist1 ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.