Go 1 и будущее программ на Go
Введение
Выпуск версии Go 1, сокращённо называемой Go 1, является важным этапом в развитии языка. Go 1 представляет собой стабильную платформу для развития программ и проектов, написанных на Go.
Go 1 определяет два понятия: во-первых, спецификацию языка; во-вторых, спецификацию набора базовых API, «стандартных пакетов» библиотеки Go. Выпуск Go 1 включает их реализацию в виде двух наборов компиляторов (gc и gccgo), а также самих базовых библиотек.
Предполагается, что программы, написанные в соответствии со спецификацией Go 1, будут продолжать компилироваться и выполняться корректно, без изменений, на протяжении всего срока действия этой спецификации. В какой-то неопределённый момент может появиться спецификация Go 2, но до этого времени программы на Go, которые работают сегодня, должны продолжать работать даже при появлении будущих «точечных» релизов Go 1 (Go 1.1, Go 1.2 и т.д.).
Совместимость обеспечивается на уровне исходного кода. Бинарная совместимость скомпилированных пакетов не гарантируется между релизами. После выпуска точечной версии исходный код Go необходимо будет перекомпилировать для связи с новым релизом.
API может расширяться, добавляя новые пакеты и функции, но делать это следует таким образом, чтобы не нарушать существующий код на Go 1.
Ожидания
Хотя мы ожидаем, что подавляющее большинство программ сохранит эту совместимость со временем, невозможно гарантировать, что никакие будущие изменения не приведут к поломке какой-либо программы. Этот документ представляет собой попытку установить ожидания относительно совместимости программ на Go 1 в будущем. Существует несколько способов, при которых программа, которая компилируется и работает сегодня, может перестать работать после будущего точечного релиза. Все они маловероятны, но заслуживают записи.
- Безопасность. Возможна ситуация, когда будет выявлено нарушение безопасности в спецификации или реализации, решение которого потребует нарушения совместимости. Мы оставляем за собой право решать такие вопросы безопасности.
- Неописанное поведение. Спецификация Go стремится быть явной в большинстве свойств языка, но есть некоторые аспекты, которые остаются неописанными. Программы, зависящие от такого неописанного поведения, могут сломаться в будущих релизах.
- Ошибки в спецификации. Если станет необходимым устранить несогласованность или неполноту в спецификации, разрешение проблемы может повлиять на смысл или законность существующих программ. Мы оставляем за собой право устранять такие вопросы, включая обновление реализаций. За исключением вопросов безопасности, никакие несовместимые изменения в спецификации не будут внесены.
- Ошибки. Если компилятор или библиотека содержит ошибку, нарушающую спецификацию, программа, зависящая от такого ошибочного поведения, может сломаться после исправления ошибки. Мы оставляем за собой право исправлять такие ошибки.
- Литералы структур. Для добавления функциональности в последующих точечных релизах может потребоваться добавить поля в экспортируемые структуры API. Код, использующий неименованные литералы структур (например, pkg.T{3, "x"}), для создания значений этих типов, может перестать компилироваться после такого изменения. Однако код, использующий именованные литералы (например, pkg.T{A: 3, B: "x"}), продолжит компилироваться после такого изменения. Мы обновим такие структуры данных таким образом, чтобы именованные литералы структур оставались совместимыми, хотя неименованные литералы могут перестать компилироваться. (Существуют более сложные случаи, связанные с вложенными структурами данных или интерфейсами, но они имеют то же решение.) Поэтому рекомендуется использовать именованную запись для составных литералов, типы которых определены в отдельном пакете.
- Методы. Как и поля структур, может потребоваться добавить методы к типам, не являющимся интерфейсами. В некоторых обстоятельствах, например, когда тип встраивается в структуру вместе с другим типом, добавление нового метода может привести к конфликту с существующим методом другого встроенного типа. Мы не можем защитить от этого редкого случая и не гарантируем совместимость в случае возникновения такой ситуации.
-
Импорт с точкой. Если программа импортирует стандартный пакет с помощью
import . "path", дополнительные имена, определённые в импортируемом пакете в будущих релизах, могут конфликтовать с другими именами, определёнными в программе. Мы не рекомендуем использоватьimport .вне тестов, и использование его может привести к неудачной компиляции программы в будущих релизах. -
Использование пакета
unsafe. Пакеты, импортирующиеunsafe, могут зависеть от внутренних свойств реализации Go. Мы оставляем за собой право вносить изменения в реализацию, которые могут сломать такие программы.
Конечно, для всех указанных выше возможностей, если они возникнут, мы постараемся при возможности обновить спецификацию, компиляторы или библиотеки, не затрагивая существующий код.
Те же самые соображения относятся к последующим точечным релизам. Например, код, работающий под Go 1.2, должен быть совместим с Go 1.2.1, Go 1.3, Go 1.4 и т.д., хотя, возможно, не с Go 1.1, поскольку он может использовать функции, добавленные только в Go 1.2.
Функции, добавленные между релизами, доступные в репозитории исходного кода, но не входящие в номерные бинарные релизы, находятся в активной разработке. Никаких гарантий совместимости не предоставляется для программ, использующих такие функции, пока они не будут выпущены.
Наконец, хотя это не проблема корректности, возможно, что производительность программы может быть затронута изменениями в реализации компиляторов или библиотек, от которых она зависит. Ни каких гарантий относительно производительности конкретной программы между релизами не предоставляется.
Хотя эти ожидания относятся к Go 1 в целом, мы надеемся, что подобные соображения будут учтены при разработке программного обеспечения, созданного вне Go 1.
Субрепозитории
Код в субрепозиториях основного дерева go, таких как golang.org/x/net, может разрабатываться с более мягкими требованиями совместимости. Однако субрепозитории будут помечены соответствующим образом, чтобы идентифицировать версии, совместимые с точечными релизами Go 1.
Операционные системы
Невозможно гарантировать долгосрочную совместимость с интерфейсами операционных систем, которые изменяются сторонними организациями.
Пакет syscall поэтому находится вне сферы ответственности гарантий, предоставляемых здесь.
Начиная с версии Go 1.4, пакет syscall заморожен.
Любое развитие интерфейса системных вызовов должно поддерживаться в другом месте, например, в субрепозитории
go.sys.
За подробностями и историей см.
этот документ.
Инструменты
Наконец, инструментарий Go (компиляторы, компоновщики, инструменты сборки и т.д.) находится в активной разработке и может изменять своё поведение. Это значит, например, что скрипты, зависящие от местоположения и свойств инструментов, могут быть сломаны точечным релизом.
За исключением этих предупреждений, мы полагаем, что Go 1 станет прочной основой для разработки Go и его экосистемы.