LINUX.ORG.RU

Вышел Golang 1.17

 


1

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 ()

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

если это как раз подразумевает увеличение количества операций с памятью в текущем контексте

Что-то несусветное Вы пишите. Если объект освобождён, то и память под него освобождена. И её можно использовать под новый объект. А вот если он не освобождён – то кол-во операций с памятью возрастает. Потому что её нет, и нужно выделять.

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

@lazy8, проблемы readable синтаксиса во всех языках программирования - грамматики.

Не совсем. Есть ещё проблема «множество способов сделать одно и то же разными путями». Проблема множества сущностей. И даже когда называют типа __attribute__ или _class – из той же оперы.

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

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

Вообще я стараюсь в яву не лезть, но я так понимаю, что именно этим онанизмом и занимаются. Т.н. gc-free.

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

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

Да, понял про какие пулы речь. Я имел ввиду sync.Pool и про него говорил.

Но тогда нужно будет разбираться, как там статический анализатор решит разместить переменную. Каждый раз. И код заточенный под это дело уже будет выглядеть настолько отлично, что его нельзя будет назвать кодом на языке «Х» в полной мере.

И Го всё равно вызывает GC даже если не было ни выделения ни освобождения. Про это писали уже ребята из Discord, когда перетаскивали на Rust какой-то свой кэширующий сервис. Они всё оптимизировали, но получили огромную паузу. Сборщик просто обходил объекты в пустую, если не ошибаюсь.

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

Спасибо!

Эту https://archive.org/details/Software_Construction_Data_Structures_Ada_95_Michael_Feldman?view=theater&ui=embed&wrapper=false

качнул здесь
https://dokumen.pub/software-construction-and-data-structures-with-ada-95-2nd-edition-2nbsped-0201887959-9780201887952.html

По allocate конечно хорошая публикация.
Ныне allocate для своего API разрабатываю /но не для замены системного/.
Для Си /чтобы «не было стыдно за бесцельно прожитые»/ годы.

Кстати неплохая книженция «Data structures and algorithms with C 9781783323685».
В ней на каждый чих приведен код на Си /для начинающих ИМХО полезна/.

anonymous ()

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

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

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

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

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

Да, я так и написал. Ещё навеяло другой статьей с медиума: мы делаем финансовый low latency софт в клауде. Kernel bypass, по ядру под задачу. И на яве.

Статью про go -> rust тоже читал вроде. Интересная.

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

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

PS: Релиза 2.0 скорее всего никогда не будет. 2.0 – это такой running-gag.

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

касаемо изначального текста

В основном касательно поддерживаемых архитектур

  • добавлена архитектура windows/arm64
  • маководы лишаются поддержки всех версий систем раньше High Sierra (обычно это ничего не значит, Windows XP давно дропнута, но работает как и раньше)
  • openbsd/mips64 теперь поддерживает cgo
  • указатель на стек для всех ARM64, для тех кто пишет на ассемблере
  • зарезервирована архитектура loong64 (архитектура разработанная Академией наук Китая)

И про флаги -go и -compat для go mod tidy, например

  • go mod tidy -go=1.17
  • go mod tidy -compat=1.17

Как раз нужные для апгрейда.

lazy8 ()

Язык то в принципе нормальный. То что некоторые говорят что в нет нет ООП, просто утята. ООП на структурах и методах вполне норм.

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

package main

import (
	"fmt"
)

type Coord struct {
	x, y int
}

type A struct {
	name string
	coords []Coord
}

type B struct {
	v map[A]Coord // invalid map key type A
}

const b1 B = B{} // const initializer B{} is not a constant

func main() {
	b2 := B{}
	fmt.Println(b2)
}
anonymous ()
Ответ на: комментарий от undefiened

Вон оно как. А я досихпор не понимаю зачем эти женерики нужны. За плечами магистратура CS и 10 лет жабы. Ни разу женерики не юзал. Все что с ними видел это пример функции сложения разных типов :D

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

Не понятно как у вас ваши сборщики, которые сразу вычищаются с короткоживущими объектами себя хорошо показывают,

Потому что они generational. Они устроены по принципу экспоненциально увеличивающегося размера арен, которые просматриваются реже и реже с ростом размера. Приложения, которые выделяют много короткоживущих объектов (например, парсинг XML/JSON) и не шарят объекты между потоками, будут сидеть в первой арене. Тут и выделение памяти очень быстрое (арена), и высвобождение — тоже.

Мы точно так же делаем и в С++. Если парсятся документы для RPC, то это делается в арене. Просто в С++ арену сделать очень просто, и контролировать её очень просто. А в Java всё по максимуму скрыто от приложения, и только несколько настраиваемых параметров (размеры арен и частота просмотра) торчат наружу.

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

до этого ручное управление делалось через Unsafe.

Один большой «UB в продакшене», с точки зрения С++-ника. Но джавистам не понять))

ForeignMemory

Не прошло и ста лет)) Годная вещь, я её юзаю и с нетерпением жду Panama.

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

А я досихпор не понимаю зачем эти женерики нужны. За плечами магистратура CS и 10 лет жабы. Ни разу женерики не юзал.

Коллекции доводилось юзать? Вот что бывает, когда рантайм не умеет в мономорфизацию классов.

Если у тебя есть достаточно гибкие мономорфные дженерики («как в С++») И есть value-семантика, то ты можешь конструировать кастомные раскладки данных по памяти, что есть data-oriented design (DoD). И что есть очень хорошо с точки зрения кэшей и иерархии памяти.

Делать DoD в Java очень сложно. Там этим в приципе не заморачиваются. Хотя годные дизайны (PrestoDB) иногда появляются.

aist1 ★★ ()

Когда в гошечку завезут нормальную работу с raw сокетами и сборку/парсинг собственных tcp/ip пакетов? Dial не хватает даже нормальный порт сканер написать…

заточен под сетевое программирование, говорили они…

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

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

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

Я не справился и написал на BPF.

Ну, то есть как не справился, под линукс их есть, но вот с фрёй и макосью (= ворованная фря) облом, там Listen не работает, так как ядро не передает пакеты в raw сокеты. Тут-то нам и понадобится роутинг на datalink лейере OSI. Тут душные индусские макаки из гугола могли и поднапрячься. Хотя, кого мы обманываем, они же только христоматийные задачки с литкода умеют.

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

Ахаха, знакома я тема.

Дело в том, что в C++/Rust/Go(будут) инвариантные, и это накладывает определенные ограничения на парадигму их применения. В Java — ковариантные/контрвариантные, и поэтому могут вступать в иерархии наследования. Однако, реализация таких дженериков опять попала в «трясину Тьюринга». Они оказались полны по Тьюрингу, и на них можно выразить в принципе любые отношения обобщенных типов, но реально это сделать практически невозможно (term rewriting потому что, слишком сложно для человека).

Я, после 20 лет программирования на Java, её дженерики обхожу стороной и вещи уровня Tinkerpop API сдизайнить не смогу, потому что не хочу))

Т.е. они нужны, они важны. С ними можно много чего полезного делать даже в Java (вывод типов). Но пусть этим занимаются другие люди))

Но в Go будут инвариантные момноморфные дженерики. Т.е. это совсем другая парадигма и другие юзкейсы.

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

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

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

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

А как тебе такое?

MODULE Figures; (* Abstract module *)

TYPE
   Figure*    = POINTER TO FigureDesc;
   Interface* = POINTER TO InterfaceDesc;

   InterfaceDesc* = RECORD
      draw*  : PROCEDURE (f : Figure);
      clear* : PROCEDURE (f : Figure);
      mark*  : PROCEDURE (f : Figure);
      move*  : PROCEDURE (f : Figure; dx, dy : INTEGER);
   END;

   FigureDesc* = RECORD
      if : Interface;
   END;

PROCEDURE Init* (f : Figure; if : Interface);
BEGIN
   f.if := if
END Init;

PROCEDURE Draw* (f : Figure);
BEGIN
   f.if.draw(f)
END Draw;

(* Other procedures here *)

END Figures.

MODULE Rectangles;

IMPORT Figures;

TYPE
   Rectangle* = POINTER TO RectangleDesc;

   RectangleDesc* = RECORD
      (Figures.FigureDesc)
      x, y, w, h : INTEGER;
   END;

VAR
   if : Figures.Interface;

PROCEDURE New* (VAR r : Rectangle);
BEGIN
   NEW(r);
   Figures.Init(r, if)
END New;

PROCEDURE Draw* (f : Figure);
   VAR
      r : Rectangle;
BEGIN
   r := f(Rectangle); (* f AS Rectangle *)
   (* ... *)
END Draw;

(* Other procedures here *)

BEGIN (* Module initialisation *)
   NEW(if);
   if.draw  := Draw;
   if.clear := Clear;
   if.mark  := Mark;
   if.move  := Move
END Rectangles.

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

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

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

Я понимаю твой вопрос, могли бы такую фундаментальную вещь и сделать. С другой стороны, бесшовная интеграция с С там в языке заявлена изначально. Т.е. предполагается, что язык Го не совсем самостоятелен. Что-то придется писать на С.

aist1 ★★ ()