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

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

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

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

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

class Entity {
  var position
  function move(to) {
     this.position = to
  }
}

// наследуем
class Cat(Entity) {
  this.position = Position(x: 0, y: 100)

  function inPosition() {
    this.position.y != 0
    and
    this.position.x != 0
  }
}
menangen ★★★★★ ()
Ответ на: комментарий от menangen

https://play.golang.org/p/TycWw_GygfL

package main

import (
	"fmt"
)

type entity struct {
	position int
}

func (e *entity) move(x int) {
	e.position = x
}

type cat struct {
	entity
}

func (c *cat) inPosition(x int) bool {
	if c.position == x {
		return true
	}
	return false
}

func main() {
	c := &cat{}
	c.move(5)
	fmt.Println("in position 3: ", c.inPosition(3))
	fmt.Println("in position 5: ", c.inPosition(5))
}
ergo ()
Ответ на: комментарий от menangen

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

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

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

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

когда аргументы заканчиваются

У меня их вообще нет. Просто мимокрокодил и косо поглядываю, а вдруг «на потыкать».

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

А где его нет? Либо ты руками его собираешь, либо за тебя это делает робот, либо в гибридном режиме. Minecraft Server написан же под Java, а там ваще память не жалеют и не парятся насчёт тормозных GC

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

А где его нет?

Я уже хотел возразить, но потом подумал, что реальность-то на твоей стороне, а я становлюсь слишком стар.

Писать игровые сервера на Go, Java или даже Python можно, если SLA по задержкам можно выдержать. А вот игровые дивижки, которые графику рисуют, — это надо, чтобы в event loop память бралась только из пулов.

Но ты, наверное, имел в виду игровые сервера, так?

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

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

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

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

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

:= &cat{}

какой-то перл напоминает и не кажется удобным для чтения.

пример menangen кажется короче и легче читаемым. субъективно.

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

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

Сборщики более-менее неплохо себя показывают на сетевых приложениях, где (почти) все объекты короткоживущие и сразу вычищаются. А вот базу данных или кэш делать в управляемой сборщиком куче — это нарываться на задержки в минуты и более. Что в Java, что в Go.

aist1 ★★ ()
Ответ на: комментарий от crypt
type entity struct {
	position int
}

func (e *entity) move(x int) {
	e.position = x
}

type cat struct {
	entity
}

func (c *cat) inPosition(x int) bool {
	return c.position == x
}

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

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

Для игр используется пул. Объекты, созданные в течение отрисовки кадра, потом хлопаются все разом. Тут и выделение очень быстрое и удаление очень быстрое.

GC делает удаление долгим и, что самое страшное, непредсказуемым. Если у тебя есть 144 FPS, у тебя есть примерно 6 мс на каждый кадр. Из них, скажем, 5 уйдут на обработку логики. Ни один GC не гарантирует, что он не потратит больше 1 мс.

Точней есть реалтаймовые GC, но это экзотика.

На самом деле в теории, думаю, можно сделать GC, затюненный именно на игровой движок. Но на практике проще пользоваться C++.

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

кому и COBOL нормальный язык. На вкус и цвет фломастеры разные, каждый ЯП подчеркивает индивидуальность программиста и многое о нём говорит. Упёртые используют плюсы, растаманы ruby, шарпом мажоры, java родители этих мажоров, педанты использую паскаль, анархисты обмазываются сями и нодойжс и т.д.

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

Если бы дженерики были не нужны, то их бы не делали. С Go 2 такая же логика, просто так ничего не делается, разве что Just for fun.

Кстати, а какие там будут дженерики: как в Java, когда тип приводится к общему, или как в раст/C++ templates, когда для каждого типа генерируется своя функция?

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

Если бы дженерики были не нужны, то их бы не делали.

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

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

Го 1.х не может выйти за рамки, из-за обещания совместимости.

А Go 2 может:

https://go2goplay.golang.org/

(хоть и выглядит это довольно глупым и лапшевидным переписыванием интерфейсов под какую-то новую странную сущность)

(Или я просто не понял в чём там юмор \0/)

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

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

Поэтому там, где важна latency (игры и трейдинг, как минимум) нельзя выделять память на пути обработки данных.

Поэтому я вообще не понимаю прикола использования языков, сильно заточенных на gc без этого самого gc (как объяснили, через пулинг всего и вся). То есть это получается какой-то убогий и абсолютно неестественный сабсет, в разы хуже чем «С++ без исключений».

В плюсах хотя бы можно арены делать или через деструкторы нормально следить за ресурсами.

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

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

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

Поэтому я вообще не понимаю прикола использования языков, сильно заточенных на gc без этого самого gc (как объяснили, через пулинг всего и вся). То есть это получается какой-то убогий и абсолютно неестественный сабсет, в разы хуже чем «С++ без исключений».

А пуллинг не спасает от GC-паузы. Пуллинг спасает от выделения у системы памяти больше чем надо.

Это работает так

  • нужен объект
  • если памяти нет, запрос у системы
  • объект освободился, но пока GC его не собрал он ещё есть

И в этот момент, если нужен новый объект, то схема повториться и если памяти нет, то runtime полезет брать её у системы. В то время как пул позволит переиспользовать освободившийся объект между GC-паузами.

Ключевое здесь «между GC-паузами», потому что сборщик всё равно его соберёт. И возвращать системе память он не торопиться.

Это имеет смысл, например, когда в коротком промежутке создаётся и освобождаются множество объектов.

lazy8 ()

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

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

Вот в чем вопрос

Из говна и палок дворец не построишь …

anonymous ()