Go

Поделись знанием:
Перейти к: навигация, поиск
Go
Класс языка:

многопоточный, императивный, структурированный

Тип исполнения:

компилируемый

Появился в:

2009

Автор:

Роберт Гризмер, Роб Пайк и Кен Томпсон

Система типов:

строгая, статическая, с выводом типов

Основные реализации:

gc (8g, 6g, 5g), gccgo

Испытал влияние:

Си, Python, Оберон-2, Активный Оберон, Limbo

Go (часто также Golang) — компилируемый многопоточный язык программирования, разработанный компанией Google[1]. Первоначальная разработка Go началась в сентябре 2007 года, а его непосредственным проектированием занимались Роберт Гризмер, Роб Пайк и Кен Томпсон[2], занимавшиеся до этого проектом разработки операционной системы Inferno. Официально язык был представлен в ноябре 2009 года. На данный момент его поддержка осуществляется для операционных систем FreeBSD, OpenBSD, Linux, Mac OS X, Windows[3], начиная с версии 1.3 в язык Go включена экспериментальная поддержка DragonFly BSD, Plan 9 и Solaris, начиная с версии 1.4 — поддержка платформы Android.





Название

Название языка, выбранное компанией Google, практически совпадает с названием языка программирования Go!, созданного Ф. Джи. МакКейбом и К. Л. Кларком в 2003 году.[4] Обсуждение названия ведётся на странице, посвящённой Go[4].

Назначение и основные возможности языка

Язык Go разрабатывался как язык системного программирования для создания высокоэффективных программ, работающих на современных распределённых системах и многоядерных процессорах. Он может рассматриваться как попытка создать замену языку Си. При разработке уделялось особое внимание обеспечению высокоэффективной компиляции. Программы на Go компилируются в объектный код (хотя доступен и интерпретатор) и не требуют для исполнения виртуальной машины.

Основные возможности языка Go[2]:

  • Go — язык со строгой статической типизацией. Доступен автоматический вывод типов, для пользовательских типов — «утиная типизация».
  • Полноценная поддержка указателей, но без возможности применять к ним арифметические операции, в отличие от C/C++/D.
  • Строковый тип со встроенной поддержкой юникода.
  • Использование динамических массивов, хэш-таблиц, срезов (слайсов), вариант цикла для обхода коллекции.
  • Средства функционального программирования: неименованные функции, замыкания, передача функций в параметрах и возврат функциональных значений.
  • Автоматическое управление памятью со сборщиком мусора.
  • Средства объектно-ориентированного программирования, но без поддержки наследования реализации (наследуются только интерфейсы). По большому счёту, Go является процедурным языком с поддержкой интерфейсов.
  • Средства параллельного программирования: встроенные в язык потоки (go routines), взаимодействие потоков через каналы и другие средства организации многопоточных программ.
  • Достаточно лаконичный и простой синтаксис, основанный на Си, но существенно доработанный, с большим количеством синтаксического сахара.

При этом из языка сознательно исключены:

Язык продолжает развиваться, и разработчики рассматривают возможность включения в язык средств обобщённого программирования. В «Часто задаваемых вопросах»[2] по языку приводятся аргументы против использования утверждений, а наследование без указания типа, наоборот, отстаивается.

Синтаксис

Синтаксис языка Go схож с синтаксисом языка Си, с отдельными элементами, заимствованными из Оберона и скриптовых языков.

Go — регистро-зависимый язык с полной поддержкой Юникода в строках и идентификаторах
Идентификатор традиционно может быть любой непустой последовательностью, включающей буквы, цифры и знак подчёркивания, начинающийся с буквы и не совпадающий ни с одним из ключевых слов языка Go. При этом под «буквами» понимаются все символы Юникода, относящиеся к категориям «Lu» (буквы верхнего регистра), «Ll» (буквы нижнего регистра), «Lt» (заглавные буквы), «Lm» (буквы-модификаторы) или «Lo» (прочие буквы), под «цифрами» — все символы из категории «Nd» (числа, десятичные цифры). Таким образом, ничто не мешает использовать в идентификаторах, например, русские буквы.
Идентификаторы, различающиеся только регистром букв, являются различными. В языке существует ряд соглашений об использовании заглавных и строчных букв. В частности, в именах пакетов используются только строчные буквы. Все ключевые слова Go пишутся в нижнем регистре.
Естественно, в строковых литералах могут использоваться все символы Юникода без ограничений.
Комментарии и точки с запятой
Go использует оба типа комментариев в стиле Си: строчные (начинающиеся с // …) и блочные (/* … */). Строчный комментарий рассматривается компилятором как перевод строки. Блочный, располагающийся на одной строке — как пробел, на нескольких строках — как перевод строки.
Точка с запятой в Go используется в качестве обязательного разделителя в некоторых операциях (if, for, switch).
Формально также она должна завершать каждую команду, но практически ставить такую точку с запятой в конце строки нет необходимости, так как компилятор в процессе обработки кода сам добавляет точки с запятой в конец каждой строки, которая, без учёта пустых символов, завершается идентификатором, числом, символьным литералом, строкой, ключевыми словами break, continue, fallthrough, return, командой инкремента или декремента (++ или —) или закрывающей круглой, квадратной или фигурной скобкой (важное исключение — запятая в приведённый список не входит). Из этого следует две особенности:
  • Практически точка с запятой нужна только в некоторых форматах операторов if, for, switch и для разделения команд, расположенных на одной строке. Поэтому в коде на Go точек с запятой очень мало.
  • Побочным эффектом автоматической расстановки точек с запятой компилятором стало то, что не в любом месте программы, где допустим пробел, можно использовать перенос строки. В частности, в описаниях, командах инициализации и конструкциях if, for, switch нельзя переносить открывающуюся фигурную скобку на следующую строку:
func g() // !
{        // НЕВЕРНО
}

if x {
}      // !
else { // НЕВЕРНО
}

func g(){ // ВЕРНО
}

if x {
} else { // ВЕРНО
}
Здесь в двух первых случаях компилятор вставит точку с запятой в строке, помеченной комментарием с восклицательным знаком, так как строка заканчивается (без учёта пробелов и комментария), соответственно, на круглую и фигурную закрывающиеся скобки. В результате будет нарушен синтаксис объявления функции в первом случае и условного оператора — во втором.
Аналогично нельзя в списке элементов, разделённых запятыми, переносить запятую на следующую строку:
func f(i      // !
     , k int  // !
     , s      // !
     , t string) string { // НЕВЕРНО
}

func f(i,      
       k int, 
       s, 
       t string) string { // ВЕРНО
}
При переносе запятой на следующую строку текущая строка заканчивается идентификатором и в её конце автоматически ставится точка с запятой, что нарушает синтаксис списка (запятая, как уже говорилось выше — исключение из правила, после неё точка с запятой компилятором не добавляется).
Таким образом, язык диктует определённый стиль записи кода. В комплект компилятора Go входит утилита gofmt, обеспечивающая правильное и единообразное форматирование исходных текстов. Все тексты стандартной библиотеки Go отформатированы этой утилитой.
Объявление типа
Синтаксис объявления типа, в основном, решён в духе Паскаля.
Go C++
 var v1 int                
 var v2 string             
 var v3 [10]int            
 var v4 []int              
 var v5 struct { f int }   
 var v6 *int               
 var v7 map[string]int     
 var v8 func(a int) int
 int v1;
 const std::string v2;  (примерно)
 int v3[10];
 int* v4;  (примерно)
 struct { int f; } v5;
 int* v6;  (но нет арифметики для указателей)
 std::unordered_map* v7;  (примерно)
 int (*v8)(int a);
При объявлении переменные инициализируются на нулевое значение для данного типа (0 для int, пустая строка для string, nil для указателей).
Объявления можно группировать:
var (
	i int
	m float
)
Автоматический вывод типов
Язык Go поддерживает также автоматический вывод типов. Переменная может быть инициализирована при объявлении, её тип при этом можно не указывать — типом переменной становится тип присваиваемого ей выражения. Для литералов (чисел, символов, строк) стандарт языка определяет конкретные встроенные типы, к которым относится каждое такое значение. Чтобы инициализировать переменную другого типа, к литералу необходимо применить явное преобразование типа.
var v = *p
Присваивания
Внутри функции короткий синтаксис присваивания переменным значения с автоматическим выводом типов напоминает обычное присваивание в Паскале:
v1 := v2 // аналог var v1 = v2
Go допускает множественные присваивания, выполняемые параллельно:
i, j = j, i    // Поменять местами значения i и j.
Аргументы функций и методов
объявляются таким образом:
func f(i, j, k int, s, t string) string { }
Функции могут возвращать несколько значений
типы таких значений заключаются в скобки:
func f(a, b int) (int, string) {
	return a+b, "сложение"
}
Результаты функций также могут быть именованы:
func incTwo(a, b int) (c, d int) {
	c = a+1
	d = b+1
	return
}
Несколько значений, возвращаемых функциями, присваиваются переменным их перечислением через запятую, при этом количество переменных, которым присваивается результат вызова функции, должно точно совпадать с количеством возвращаемых функцией значений:
first, second := incTwo(1, 2) // first = 2, second = 3
first := incTwo(1, 2) // НЕВЕРНО - нет переменной, которой присваивается второй результат
Обязательное использование локальных переменных и псевдопеременная «_»
Любая локальная переменная обязательно должна быть использована, то есть её значение должно участвовать в какой-либо операции в пределах функции, где она объявлена. В отличие от Паскаля и Си, где объявление локальной переменной и последующее её неиспользование или потеря значения, присвоенного локальной переменной (когда переменной присваивается значение, которое затем нигде не читается), может лишь вызывать предупреждение (warning) компилятора, в Go такая ситуация считается языковой ошибкой и приводит к невозможности компиляции программы. Это означает, в частности, что программист не может проигнорировать значение (или одно из значений), возвращаемое вызываемой функцией, просто присвоив его какой-нибудь переменной и отказавшись от его дальнейшего использования. Если возникает необходимость игнорировать одно из значений, возвращаемых вызовом функции, используется предопределённая псевдопеременная с именем «_» (один знак подчёркивания). Она может быть указана в любом месте, где должна быть переменная, принимающая значение. Соответствующее значение не будет присвоено никакой переменной и просто потеряется. Смысл такого архитектурного решения — выявление на стадии компиляции возможной потери результатов вычислений: случайный пропуск обработки значения будет обнаружен компилятором, а использование псевдопеременной «_» укажет на то, что программист сознательно проигнорировал результаты.
Так, в примере выше, если из двух возвращаемых функцией incTwo значений нужно только одно, вместо второй переменной нужно указать «_»:
first := incTwo(1, 2) // НЕВЕРНО
first, _ := incTwo(1, 2) // ВЕРНО, второй результат не используется
Переменная «_» может указываться в списке присваивания любое число раз. Все результаты функции, которым соответствует «_», будут проигнорированы.
Механизм отложенного вызова defer
Отложенный вызов заменяет сразу несколько синтаксических средств, в частности, обработчики исключений и блоки с гарантированным завершением. Вызов функции, которому предшествует ключевое слово defer, параметризуется в той точке программы, где размещён, а выполняется непосредственно перед выходом программы из области видимости, где он был объявлен, независимо от того, как и по какой причине происходит этот выход. Ниже пример использования defer в качестве блока гарантированного завершения[5]
// Функция, копирующая файл
func CopyFile(dstName, srcName string) (written int64, err error) { 
    src, err := os.Open(srcName)  // Открытие файла-источника
    if err != nil {               // Проверка
        return                    // Если неудача, возврат с ошибкой
    }
    // Если пришли сюда, то файл-источник был успешно открыт 
    defer src.Close()  // Отложенный вызов: src.Close() будет вызван по завершении CopyFile

    dst, err := os.Create(dstName) // Открытие файла-приёмника
    if err != nil {                // Проверка и возврат при ошибке 
        return
    }
    defer dst.Close()  // Отложенный вызов: dst.Close() будет вызван по завершении CopyFile

    return io.Copy(dst, src)  // Копирование данных и возврат из функции
    // После всех операций будут вызваны: сначала dst.Close(), затем src.Close()
}
Прочие синтаксические различия
Отсутствуют круглые скобки для условных конструкций for и if:
func print(arr []int) {
    n := len(arr)
    for i := 0; i < n; i++ {
        println(arr[i])
    }
}
Любые циклы в Go описываются с помощью конструкции for, синтаксических аналогов while, do-while и других вариантов циклической конструкции в языке нет. Но конструкция for позволяет организовать цикл любого желаемого вида.
for { // бесконечный цикл
    // Выход из цикла должен быть организован вручную,
    // обычно это делается с помощью конструкций return или break
}

for i < 10 { // цикл выполняется, пока условие истинно (аналог while в Си)
}

for i := 0; i < 10; i++ { // точно то же самое, что цикл for в Си
}

var arr []int
for i, v := range arr { // цикл по элементам массива или среза arr
// i - индекс текущего элемента
// v - сам текущий элемент (аналог arr[i])
}

for i := range arr {
// используется только индекс
}

for _, v := range arr {
// используется только элемент массива
}

for range arr {  //цикл по коллекции без переменных - поддерживается с версии 1.4
    // Может использоваться, когда коллекция используется только в качестве счётчика итераций,
    // а само текущее значение не требуется.
}

Особенности архитектуры

Обработка ошибок и исключительных ситуаций

Язык Go не поддерживает типичный для большинства современных языков синтаксис структурной обработки исключений (блоки try-catch); авторы сочли, что его применение провоцирует программиста на игнорирование ошибок.

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

  • В одном из параметров (обычно последнем) функция возвращает объект-ошибку. В качестве типа ошибки обычно используется библиотечный интерфейс error. Типичной практикой является возврат пустого указателя nil, если функция выполнилась без ошибок.
  • После вызова полученный из функции объект проверяется и ошибка, если она возникла, обрабатывается.
func ReadFile(srcName string)(result string, err error) {
    file, err := os.Open("file.txt")
    if err != nil {
        return nil, err 
    } 
    ... // Дальнейшее исполнение функции, если ошибки не было
    return result, nil  // Возврат результата и пустой ошибки, если выполнение успешно
}
  • Проигнорировать ошибку, возвращаемую из функции (в примере выше — не проверить значение переменной err) невозможно, так как инициализация переменной без последующего использования в языке Go приводит к ошибке компиляции. Конечно, этот эффект можно обойти подстановкой вместо err псевдопеременной «_», но это считается плохой практикой и, во всяком случае, явно бросается в глаза при просмотре кода.

Начинающие программисты на Go нередко критикуют его идеологию обработки ошибок, заявляя, что многочисленные проверки ошибок засоряют код и затрудняют его восприятие, тогда как механизм исключений позволяет сосредоточить всю обработку ошибок в блоках catch. В действительности идеология Go вполне позволяет обрабатывать ошибки элегантно и экономно, в литературе по языку описан ряд паттернов для этого (см., например, [blog.golang.org/errors-are-values статью Роба Пайка в официальном блоге Go] ([habrahabr.ru/post/269909/ русский перевод]).

При возникновении фатальных ошибок, делающих невозможным дальнейшее исполнение программы, возникает состояние «паники» (panic). Типичный пример возникновения паники — деление на нуль в процессе вычислений либо обращение за границы массива. В отсутствие обработки паника приводит к аварийному завершению программы с выдачей сообщения об ошибке и трассировки стека вызовов. Для обеспечения отказоустойчивости программы паника тоже может быть перехвачена и обработана. Для это используется механизм отложенного исполнения defer. Инструкция defer, как говорилось выше, получает в качестве параметра вызов функции (то есть фактически создаёт замыкание), который производится тогда, когда исполнение программы покидает текущую область видимости. Это происходит даже в случае паники. Для её перехвата в функции, вызываемой в defer, необходимо вызвать стандартную функцию recover() — она прекращает системную обработку паники и возвращает её причину в виде объекта error. Далее программист может обработать полученную ошибку любым желаемым образом, в том числе и возобновить панику, вызвав стандартную функцию panic(err error).

Многопоточность

Модель многопоточности Go была создана на основе CSP (англ.) Тони Хоара по типу предыдущих распараллеливаемых языков программирования Occam и Limbo,[2], но также присутствуют такие особенности Пи-исчисления, как канальная передача.

Go дает возможность создать новый поток выполнения программы (go-процедуру) с помощью ключевого слова go, которое запускает анонимную или именованную функцию в заново созданной go-процедуре (аналог сопрограмм). Все go-процедуры в рамках одного процесса используют общее адресное пространство, выполняясь над ОС-потоками, но без жёсткой привязки к последним, что позволяет выполняющейся go-процедуре покидать поток с заблокированной go-процедурой (ждущей, например, отправки или приема сообщения из канала) и продолжать работу далее.

func server(i int) {
	for {
		print(i)
		time.Sleep(10)
	}
}
go server(1)
go server(2)

В выражении go можно использовать замыкания.

var g int
go func(i int) {
	s := 0
	for j := 0; j < i; j++ { s += j }
	g = s
}(1000)

Для связи между go-процедурами используются каналы (встроенный тип chan), через которые можно передавать любые значения. Для передачи значения в канал используется <- в качестве бинарного оператора, для получения сообщения из канала — <- в качестве унарного оператора.

Объектно-ориентированное программирование

Специальное ключевое слово для объявления класса в Go отсутствует, но для любого именованного типа, включая структуры и базовые типы вроде int, можно определить методы, так что в смысле ООП все такие типы являются классами.

type newInt int

Синтаксис определения метода заимствован из языка Оберон-2 и отличается от обычного определения функции тем, что получатель англ. receiver, то есть объект, для которого вызывается метод, явно указывается в описании после ключевого слова func. Если в C++ или Java получатель всегда имеет стандартное имя (this), то в Go он указывается явно и его имя может быть любым.

type myType struct { i int }
func (p *myType) get() int { return p.i }
func (p *myType) set(i int) { p.i = i }

Наследование классов (структур) в Go формально отсутствует, но имеется технически эквивалентный ему механизм встраивания (англ. embedding). В описании структуры можно использовать так называемое анонимное поле — поле, для которого не указывается имя, а только тип.

Там где в классических объектно-ориентированных языках используются классы, в Go задействованы интерфейсы (похожи на абстрактные классы C++). В Go каждый тип, предоставляющий методы, обозначенные в интерфейсе, может трактоваться как реализация интерфейса, явного объявления не требуется.

type myInterface interface {
	get() int
	set(i int)
}

Объявленный выше тип myType реализует интерфейс myInterface, хотя это нигде не указано явно.

Такой подход к наследованию соответствует некоторым практическим тенденциям современного программирования. Так в знаменитой книге «банды четырёх» (Эрих Гамма и др.) о паттернах проектирования, в частности, написано:

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

В Go нет понятия виртуальной функции. Полиморфизм обеспечивается за счёт интерфейсов. Если для вызова метода используется переменная обычного типа, то такой вызов связывается статически, то есть всегда вызывается метод, определённый для данного конкретного типа. Если же метод вызывается для переменной типа «интерфейс», то такой вызов связывается динамически, и в момент исполнения для запуска выбирается тот вариант метода, который определён для типа объекта, фактически присвоенного в момент вызова этой переменной.

Динамическая поддержка объектно-ориентированного программирования для Go осуществлена с помощью проекта [github.com/losalamos/goop GOOP].

История версий

На текущий момент существует только одна основная версия самого языка Go — версия 1. Версии среды разработки (компилятора, инструментария и стандартных библиотек) Go нумеруются по двухзначной («<версия языка>.<основной релиз>») либо трёхзначной («<версия языка>.<основной релиз>.<дополнительный релиз>») системе. Выпуск новой «двузначной» версии автоматически означает прекращение поддержки предыдущей «двузначной» версии. «Трёхзначные» версии выпускаются для исправления обнаруженных ошибок и проблем с безопасностью; исправления безопасности в таких версиях могут затрагивать две последние «двузначные» версии[6]. На апрель 2016 года последней является версия 1.6.2, вышедшая 20 апреля 2016 года.

С марта 2012 года, когда была представлена версия Go 1, вышли следующие основные версии:

  • go 1 — 28 марта 2012 года — Первая официальная версия; зафиксированы библиотеки, внесены изменения в синтаксис.
  • go 1.1 — 13 мая 2013 года — целочисленное деление на нуль стало синтаксической ошибкой, введены method values — замыкания метода с заданным значением-источником, в некоторых случаях стало необязательным использование return; в реализации разрешено выбирать между 32- и 64-разрядным представлением стандартного целочисленного типа, изменения в поддержке Unicode.
  • go 1.2 — 1 декабря 2013 года — любая попытка обратиться по указателю nil гарантированно вызывает панику, введены трёхиндексные срезы. Доработки Unicode.
  • go 1.3 — 18 июня 2014 года — изменена модель распределения памяти; удалена поддержка платформы Windows 2000, добавлены DragonFly BSD, FreeBSD, NetBSD, OpenBSD, Plan 9, Solaris.
  • go 1.4 — 10 декабря 2014 года — разрешена конструкция цикла «for range x { … }» (цикл по коллекции без использования переменных), запрещено двойное автоматическое разыменование при вызове метода (если x **T — двойной указатель на тип T, то вызов метода для x в виде x.m() — запрещён); в реализацию добавлена поддержка платформ Android, NaCl on AMR, Plan9 on AMD64.
  • go 1.5 — 19 августа 2015 года — в записи map-литералов указание типа каждого элемента сделано факультативным, в реализации среда исполнения и компилятор полностью переписаны на Go и ассемблере, более не используется язык Си.
  • go 1.6 — 17 февраля 2016 года — изменений в языке нет, среда портирована на платформы Linux on 64-bit MIPS, Android on 32-bit x86 (android/386), изменения в инструментарии.
  • go 1.7 - 16 августа 2016 — уменьшены время компиляции и размер бинарных файлов, увеличена скорость работы и в стандартную библиотеку добавлен пакет context.

Реализации

На данный момент существуют два основных компилятора Go:

  • 6g (и сопутствующие ему инструменты, вместе известные под названием gc) написан на Си с применением yacc/Bison для парсера
  • Gccgo — ещё один компилятор Go с клиентской частью, написанной на C++, и рекурсивным парсером, совмещённым со стандартным бэк-эндом GCC[7]. Поддержка Go доступна в GCC, начиная с версии 4.6[8].

А так же перспективные разработки:

  • llgo — прослойка для компиляции в llvm, написанная на самом go (находится в разработке)[9].
  • SSA interpreter — интерпретатор, позволяющий запускать программы на go.

Средства разработки

Среда разработки Go содержит всего три инструмента командной строки: компилятор go, обеспечивающий построение объектных файлов, и вспомогательные утилиты godoc и gofmt, предназначенные, соответственно, для документирования программ и для форматирования исходного кода по стандартным правилам. Для отладки программ может использоваться отладчик gdb.

Единственная на текущий момент IDE, изначально ориентированная на язык Go, это LiteIDE[sourceforge.net/projects/liteide/] (ранее проект назывался GoLangIDE). Это небольшая по объёму оболочка, написанная с использованием qt4, с помощью которой можно выполнять весь базовый набор действий по разработке ПО на Go — создание кода (редактор поддерживает подсветку синтаксиса и автодополнение), компиляцию, отладку, форматирование кода, запуск инструментов.

Также Go поддерживается плагинами в универсальных IDE Eclipse, NetBeans, IntelliJ, Komodo, CodeBox IDE, Visual Studio, Zeus и других. Автоподсветка, автодополнение кода на Go и запуск утилит компиляции и обработки кода реализованы в виде плагинов к более чем двум десяткам распространённых текстовых редакторов под различные платформы, в том числе Emacs, Vim, Notepad++, jEdit.

Примеры

Ниже представлен пример программы «Hello, World!» на языке Go.

package main

import "fmt"

func main() {
	fmt.Println("Hello, World!")
}

Пример реализации команды Unix echo:

package main

import (
	"os"
	"flag" // парсер параметров командной строки
)

var omitNewLine = flag.Bool("n", false, "не печатать знак новой строки")

const (
	Space = " "
	NewLine = "\n"
)

func main() {
	flag.Parse() // Сканирование списка аргументов и установка флагов
	var s string
	for i := 0; i < flag.NArg(); i++ {
		if i > 0 {
			s += Space
		}
		s += flag.Arg(i)
	}
	if !*omitNewLine {
		s += NewLine
	}
	os.Stdout.WriteString(s)
}

Напишите отзыв о статье "Go"

Примечания

  1. [www.techcrunch.com/2009/11/10/google-go-language/ Google-go-language]
  2. 1 2 3 4 [golang.org/doc/faq Language Design FAQ]
  3. [golang.org/doc/install.html#environment Getting Started — The Go Programming Language]
  4. 1 2 [code.google.com/p/go/issues/detail?id=9 Сообщение о конфликте имён в системе отслеживания ошибок]
  5. [blog.golang.org/defer-panic-and-recover Andrew Gerrand. Defer, Panic, and Recover на GoBlog]
  6. golang.org/doc/devel/release.html Версии Go.
  7. [golang.org/doc/faq#Implementation Go FAQ: Implementation]
  8. gcc.gnu.org/gcc-4.6/changes.html «Support for the Go programming language has been added to GCC. It is not enabled by default when you build GCC»
  9. [github.com/go-llvm/llgo go-llvm/llgo · GitHub]

Ссылки

  • [golang.org/ Официальный сайт Go]  (англ.)
  • [tour.golang.org/ A Tour of Go]  (англ.)
  • [netsago.org/ru/docs/1/16/ Сравнение Go с C++ (из официальной документации)]  (рус.)
  • [golang.org/doc/faq Вопросы и ответы по языку Go]  (англ.)
  • [miek.nl/downloads/Go/ Learning Go] (PDF)  (англ.), свободная Creative Commons книга о языке от [www.miek.nl/ Miek Gieben], доступны еженочные PDF-сборки и git-репозиторий с LATEX-исходниками.
  • [www.golang-book.com/ An Introduction to Programming in Go]  (англ.) — учебник для начинающих. Книга доступна онлайн и в виде [www.golang-book.com/assets/pdf/gobook.pdf PDF-файла] бесплатно; на Amazon.com доступны [www.amazon.com/An-Introduction-Programming-Go-ebook/dp/B0095MCNAO/ версия для Kindle] и [www.amazon.com/An-Introduction-Programming-Caleb-Doxsey/dp/1478355824 печатная версия].
  • [www.ibm.com/developerworks/ru/library/l-go_01/index.html Язык программирования go: Часть 1. Краткий обзор и основы программирования]  (рус.), Дмитрий Выкочко, IBM developerWorks
    • [www.ibm.com/developerworks/ru/library/l-go_02/index.html Часть 2. Разработка Web-приложений]  (рус.)
    • [www.ibm.com/developerworks/ru/library/l-go_03/index.html Часть 3. Работа с базами данных]  (рус.)
    • [www.ibm.com/developerworks/ru/library/l-go_04/index.html Часть 4. Создание GUI-приложений]  (рус.)
  • [youtube.com/watch?v=rKnDgT73v8s The Go Programming Language] на YouTube  (англ.)
  • [youtube.com/watch?v=bqtN6XViejE HighLoad++ 2012. Язык программирования Go от Google] на YouTube  (рус.)
  • [youtube.com/watch?v=OtRf5WC4qoE Digital October. Доклад конференции Golang Moscow] на YouTube  (рус.)
  • [gobyexample.com Go By Example] — практическое введение в язык с помощью аннотированных примеров программ  (англ.)
  • [github.com/avelino/awesome-go Awesome Go] — отборный список фреймворков, библиотек и программного обеспечения на языке Go с открытым исходным кодом  (англ.)
  • IRC : irc://irc.freenode.net/go-nuts на irc.freenode.net
  • Подписка на рассылки : [groups.google.com/group/golang-nuts groups.google.com/group/golang-nuts]  (англ.) и [groups.google.com/group/golang-ru groups.google.com/group/golang-ru]  (рус.)
  • Группы в Google+ : plus.google.com/u/1/+golang/about  (англ.) и plus.google.com/communities/100750770323291642539  (рус.)
  • [golangshow.com Подкаст GolangShow] — первый и единственный подкаст о языке Go

Отрывок, характеризующий Go

– Il faut que vous sachiez que c'est une femme, [Знай, что это женщина,] – сказал Андрей Пьеру.
– Andre, au nom de Dieu! [Андрей, ради Бога!] – повторила княжна Марья.
Видно было, что насмешливое отношение князя Андрея к странникам и бесполезное заступничество за них княжны Марьи были привычные, установившиеся между ними отношения.
– Mais, ma bonne amie, – сказал князь Андрей, – vous devriez au contraire m'etre reconaissante de ce que j'explique a Pierre votre intimite avec ce jeune homme… [Но, мой друг, ты должна бы быть мне благодарна, что я объясняю Пьеру твою близость к этому молодому человеку.]
– Vraiment? [Правда?] – сказал Пьер любопытно и серьезно (за что особенно ему благодарна была княжна Марья) вглядываясь через очки в лицо Иванушки, который, поняв, что речь шла о нем, хитрыми глазами оглядывал всех.
Княжна Марья совершенно напрасно смутилась за своих. Они нисколько не робели. Старушка, опустив глаза, но искоса поглядывая на вошедших, опрокинув чашку вверх дном на блюдечко и положив подле обкусанный кусочек сахара, спокойно и неподвижно сидела на своем кресле, ожидая, чтобы ей предложили еще чаю. Иванушка, попивая из блюдечка, исподлобья лукавыми, женскими глазами смотрел на молодых людей.
– Где, в Киеве была? – спросил старуху князь Андрей.
– Была, отец, – отвечала словоохотливо старуха, – на самое Рожество удостоилась у угодников сообщиться святых, небесных тайн. А теперь из Колязина, отец, благодать великая открылась…
– Что ж, Иванушка с тобой?
– Я сам по себе иду, кормилец, – стараясь говорить басом, сказал Иванушка. – Только в Юхнове с Пелагеюшкой сошлись…
Пелагеюшка перебила своего товарища; ей видно хотелось рассказать то, что она видела.
– В Колязине, отец, великая благодать открылась.
– Что ж, мощи новые? – спросил князь Андрей.
– Полно, Андрей, – сказала княжна Марья. – Не рассказывай, Пелагеюшка.
– Ни… что ты, мать, отчего не рассказывать? Я его люблю. Он добрый, Богом взысканный, он мне, благодетель, рублей дал, я помню. Как была я в Киеве и говорит мне Кирюша юродивый – истинно Божий человек, зиму и лето босой ходит. Что ходишь, говорит, не по своему месту, в Колязин иди, там икона чудотворная, матушка пресвятая Богородица открылась. Я с тех слов простилась с угодниками и пошла…
Все молчали, одна странница говорила мерным голосом, втягивая в себя воздух.
– Пришла, отец мой, мне народ и говорит: благодать великая открылась, у матушки пресвятой Богородицы миро из щечки каплет…
– Ну хорошо, хорошо, после расскажешь, – краснея сказала княжна Марья.
– Позвольте у нее спросить, – сказал Пьер. – Ты сама видела? – спросил он.
– Как же, отец, сама удостоилась. Сияние такое на лике то, как свет небесный, а из щечки у матушки так и каплет, так и каплет…
– Да ведь это обман, – наивно сказал Пьер, внимательно слушавший странницу.
– Ах, отец, что говоришь! – с ужасом сказала Пелагеюшка, за защитой обращаясь к княжне Марье.
– Это обманывают народ, – повторил он.
– Господи Иисусе Христе! – крестясь сказала странница. – Ох, не говори, отец. Так то один анарал не верил, сказал: «монахи обманывают», да как сказал, так и ослеп. И приснилось ему, что приходит к нему матушка Печерская и говорит: «уверуй мне, я тебя исцелю». Вот и стал проситься: повези да повези меня к ней. Это я тебе истинную правду говорю, сама видела. Привезли его слепого прямо к ней, подошел, упал, говорит: «исцели! отдам тебе, говорит, в чем царь жаловал». Сама видела, отец, звезда в ней так и вделана. Что ж, – прозрел! Грех говорить так. Бог накажет, – поучительно обратилась она к Пьеру.
– Как же звезда то в образе очутилась? – спросил Пьер.
– В генералы и матушку произвели? – сказал князь Aндрей улыбаясь.
Пелагеюшка вдруг побледнела и всплеснула руками.
– Отец, отец, грех тебе, у тебя сын! – заговорила она, из бледности вдруг переходя в яркую краску.
– Отец, что ты сказал такое, Бог тебя прости. – Она перекрестилась. – Господи, прости его. Матушка, что ж это?… – обратилась она к княжне Марье. Она встала и чуть не плача стала собирать свою сумочку. Ей, видно, было и страшно, и стыдно, что она пользовалась благодеяниями в доме, где могли говорить это, и жалко, что надо было теперь лишиться благодеяний этого дома.
– Ну что вам за охота? – сказала княжна Марья. – Зачем вы пришли ко мне?…
– Нет, ведь я шучу, Пелагеюшка, – сказал Пьер. – Princesse, ma parole, je n'ai pas voulu l'offenser, [Княжна, я право, не хотел обидеть ее,] я так только. Ты не думай, я пошутил, – говорил он, робко улыбаясь и желая загладить свою вину. – Ведь это я, а он так, пошутил только.
Пелагеюшка остановилась недоверчиво, но в лице Пьера была такая искренность раскаяния, и князь Андрей так кротко смотрел то на Пелагеюшку, то на Пьера, что она понемногу успокоилась.


Странница успокоилась и, наведенная опять на разговор, долго потом рассказывала про отца Амфилохия, который был такой святой жизни, что от ручки его ладоном пахло, и о том, как знакомые ей монахи в последнее ее странствие в Киев дали ей ключи от пещер, и как она, взяв с собой сухарики, двое суток провела в пещерах с угодниками. «Помолюсь одному, почитаю, пойду к другому. Сосну, опять пойду приложусь; и такая, матушка, тишина, благодать такая, что и на свет Божий выходить не хочется».
Пьер внимательно и серьезно слушал ее. Князь Андрей вышел из комнаты. И вслед за ним, оставив божьих людей допивать чай, княжна Марья повела Пьера в гостиную.
– Вы очень добры, – сказала она ему.
– Ах, я право не думал оскорбить ее, я так понимаю и высоко ценю эти чувства!
Княжна Марья молча посмотрела на него и нежно улыбнулась. – Ведь я вас давно знаю и люблю как брата, – сказала она. – Как вы нашли Андрея? – спросила она поспешно, не давая ему времени сказать что нибудь в ответ на ее ласковые слова. – Он очень беспокоит меня. Здоровье его зимой лучше, но прошлой весной рана открылась, и доктор сказал, что он должен ехать лечиться. И нравственно я очень боюсь за него. Он не такой характер как мы, женщины, чтобы выстрадать и выплакать свое горе. Он внутри себя носит его. Нынче он весел и оживлен; но это ваш приезд так подействовал на него: он редко бывает таким. Ежели бы вы могли уговорить его поехать за границу! Ему нужна деятельность, а эта ровная, тихая жизнь губит его. Другие не замечают, а я вижу.
В 10 м часу официанты бросились к крыльцу, заслышав бубенчики подъезжавшего экипажа старого князя. Князь Андрей с Пьером тоже вышли на крыльцо.
– Это кто? – спросил старый князь, вылезая из кареты и угадав Пьера.
– AI очень рад! целуй, – сказал он, узнав, кто был незнакомый молодой человек.
Старый князь был в хорошем духе и обласкал Пьера.
Перед ужином князь Андрей, вернувшись назад в кабинет отца, застал старого князя в горячем споре с Пьером.
Пьер доказывал, что придет время, когда не будет больше войны. Старый князь, подтрунивая, но не сердясь, оспаривал его.
– Кровь из жил выпусти, воды налей, тогда войны не будет. Бабьи бредни, бабьи бредни, – проговорил он, но всё таки ласково потрепал Пьера по плечу, и подошел к столу, у которого князь Андрей, видимо не желая вступать в разговор, перебирал бумаги, привезенные князем из города. Старый князь подошел к нему и стал говорить о делах.
– Предводитель, Ростов граф, половины людей не доставил. Приехал в город, вздумал на обед звать, – я ему такой обед задал… А вот просмотри эту… Ну, брат, – обратился князь Николай Андреич к сыну, хлопая по плечу Пьера, – молодец твой приятель, я его полюбил! Разжигает меня. Другой и умные речи говорит, а слушать не хочется, а он и врет да разжигает меня старика. Ну идите, идите, – сказал он, – может быть приду, за ужином вашим посижу. Опять поспорю. Мою дуру, княжну Марью полюби, – прокричал он Пьеру из двери.
Пьер теперь только, в свой приезд в Лысые Горы, оценил всю силу и прелесть своей дружбы с князем Андреем. Эта прелесть выразилась не столько в его отношениях с ним самим, сколько в отношениях со всеми родными и домашними. Пьер с старым, суровым князем и с кроткой и робкой княжной Марьей, несмотря на то, что он их почти не знал, чувствовал себя сразу старым другом. Они все уже любили его. Не только княжна Марья, подкупленная его кроткими отношениями к странницам, самым лучистым взглядом смотрела на него; но маленький, годовой князь Николай, как звал дед, улыбнулся Пьеру и пошел к нему на руки. Михаил Иваныч, m lle Bourienne с радостными улыбками смотрели на него, когда он разговаривал с старым князем.
Старый князь вышел ужинать: это было очевидно для Пьера. Он был с ним оба дня его пребывания в Лысых Горах чрезвычайно ласков, и велел ему приезжать к себе.
Когда Пьер уехал и сошлись вместе все члены семьи, его стали судить, как это всегда бывает после отъезда нового человека и, как это редко бывает, все говорили про него одно хорошее.


Возвратившись в этот раз из отпуска, Ростов в первый раз почувствовал и узнал, до какой степени сильна была его связь с Денисовым и со всем полком.
Когда Ростов подъезжал к полку, он испытывал чувство подобное тому, которое он испытывал, подъезжая к Поварскому дому. Когда он увидал первого гусара в расстегнутом мундире своего полка, когда он узнал рыжего Дементьева, увидал коновязи рыжих лошадей, когда Лаврушка радостно закричал своему барину: «Граф приехал!» и лохматый Денисов, спавший на постели, выбежал из землянки, обнял его, и офицеры сошлись к приезжему, – Ростов испытывал такое же чувство, как когда его обнимала мать, отец и сестры, и слезы радости, подступившие ему к горлу, помешали ему говорить. Полк был тоже дом, и дом неизменно милый и дорогой, как и дом родительский.
Явившись к полковому командиру, получив назначение в прежний эскадрон, сходивши на дежурство и на фуражировку, войдя во все маленькие интересы полка и почувствовав себя лишенным свободы и закованным в одну узкую неизменную рамку, Ростов испытал то же успокоение, ту же опору и то же сознание того, что он здесь дома, на своем месте, которые он чувствовал и под родительским кровом. Не было этой всей безурядицы вольного света, в котором он не находил себе места и ошибался в выборах; не было Сони, с которой надо было или не надо было объясняться. Не было возможности ехать туда или не ехать туда; не было этих 24 часов суток, которые столькими различными способами можно было употребить; не было этого бесчисленного множества людей, из которых никто не был ближе, никто не был дальше; не было этих неясных и неопределенных денежных отношений с отцом, не было напоминания об ужасном проигрыше Долохову! Тут в полку всё было ясно и просто. Весь мир был разделен на два неровные отдела. Один – наш Павлоградский полк, и другой – всё остальное. И до этого остального не было никакого дела. В полку всё было известно: кто был поручик, кто ротмистр, кто хороший, кто дурной человек, и главное, – товарищ. Маркитант верит в долг, жалованье получается в треть; выдумывать и выбирать нечего, только не делай ничего такого, что считается дурным в Павлоградском полку; а пошлют, делай то, что ясно и отчетливо, определено и приказано: и всё будет хорошо.
Вступив снова в эти определенные условия полковой жизни, Ростов испытал радость и успокоение, подобные тем, которые чувствует усталый человек, ложась на отдых. Тем отраднее была в эту кампанию эта полковая жизнь Ростову, что он, после проигрыша Долохову (поступка, которого он, несмотря на все утешения родных, не мог простить себе), решился служить не как прежде, а чтобы загладить свою вину, служить хорошо и быть вполне отличным товарищем и офицером, т. е. прекрасным человеком, что представлялось столь трудным в миру, а в полку столь возможным.
Ростов, со времени своего проигрыша, решил, что он в пять лет заплатит этот долг родителям. Ему посылалось по 10 ти тысяч в год, теперь же он решился брать только две, а остальные предоставлять родителям для уплаты долга.

Армия наша после неоднократных отступлений, наступлений и сражений при Пултуске, при Прейсиш Эйлау, сосредоточивалась около Бартенштейна. Ожидали приезда государя к армии и начала новой кампании.
Павлоградский полк, находившийся в той части армии, которая была в походе 1805 года, укомплектовываясь в России, опоздал к первым действиям кампании. Он не был ни под Пултуском, ни под Прейсиш Эйлау и во второй половине кампании, присоединившись к действующей армии, был причислен к отряду Платова.
Отряд Платова действовал независимо от армии. Несколько раз павлоградцы были частями в перестрелках с неприятелем, захватили пленных и однажды отбили даже экипажи маршала Удино. В апреле месяце павлоградцы несколько недель простояли около разоренной до тла немецкой пустой деревни, не трогаясь с места.
Была ростепель, грязь, холод, реки взломало, дороги сделались непроездны; по нескольку дней не выдавали ни лошадям ни людям провианта. Так как подвоз сделался невозможен, то люди рассыпались по заброшенным пустынным деревням отыскивать картофель, но уже и того находили мало. Всё было съедено, и все жители разбежались; те, которые оставались, были хуже нищих, и отнимать у них уж было нечего, и даже мало – жалостливые солдаты часто вместо того, чтобы пользоваться от них, отдавали им свое последнее.
Павлоградский полк в делах потерял только двух раненых; но от голоду и болезней потерял почти половину людей. В госпиталях умирали так верно, что солдаты, больные лихорадкой и опухолью, происходившими от дурной пищи, предпочитали нести службу, через силу волоча ноги во фронте, чем отправляться в больницы. С открытием весны солдаты стали находить показывавшееся из земли растение, похожее на спаржу, которое они называли почему то машкин сладкий корень, и рассыпались по лугам и полям, отыскивая этот машкин сладкий корень (который был очень горек), саблями выкапывали его и ели, несмотря на приказания не есть этого вредного растения.
Весною между солдатами открылась новая болезнь, опухоль рук, ног и лица, причину которой медики полагали в употреблении этого корня. Но несмотря на запрещение, павлоградские солдаты эскадрона Денисова ели преимущественно машкин сладкий корень, потому что уже вторую неделю растягивали последние сухари, выдавали только по полфунта на человека, а картофель в последнюю посылку привезли мерзлый и проросший. Лошади питались тоже вторую неделю соломенными крышами с домов, были безобразно худы и покрыты еще зимнею, клоками сбившеюся шерстью.
Несмотря на такое бедствие, солдаты и офицеры жили точно так же, как и всегда; так же и теперь, хотя и с бледными и опухлыми лицами и в оборванных мундирах, гусары строились к расчетам, ходили на уборку, чистили лошадей, амуницию, таскали вместо корма солому с крыш и ходили обедать к котлам, от которых вставали голодные, подшучивая над своею гадкой пищей и своим голодом. Также как и всегда, в свободное от службы время солдаты жгли костры, парились голые у огней, курили, отбирали и пекли проросший, прелый картофель и рассказывали и слушали рассказы или о Потемкинских и Суворовских походах, или сказки об Алеше пройдохе, и о поповом батраке Миколке.
Офицеры так же, как и обыкновенно, жили по двое, по трое, в раскрытых полуразоренных домах. Старшие заботились о приобретении соломы и картофеля, вообще о средствах пропитания людей, младшие занимались, как всегда, кто картами (денег было много, хотя провианта и не было), кто невинными играми – в свайку и городки. Об общем ходе дел говорили мало, частью оттого, что ничего положительного не знали, частью оттого, что смутно чувствовали, что общее дело войны шло плохо.
Ростов жил, попрежнему, с Денисовым, и дружеская связь их, со времени их отпуска, стала еще теснее. Денисов никогда не говорил про домашних Ростова, но по нежной дружбе, которую командир оказывал своему офицеру, Ростов чувствовал, что несчастная любовь старого гусара к Наташе участвовала в этом усилении дружбы. Денисов видимо старался как можно реже подвергать Ростова опасностям, берег его и после дела особенно радостно встречал его целым и невредимым. На одной из своих командировок Ростов нашел в заброшенной разоренной деревне, куда он приехал за провиантом, семейство старика поляка и его дочери, с грудным ребенком. Они были раздеты, голодны, и не могли уйти, и не имели средств выехать. Ростов привез их в свою стоянку, поместил в своей квартире, и несколько недель, пока старик оправлялся, содержал их. Товарищ Ростова, разговорившись о женщинах, стал смеяться Ростову, говоря, что он всех хитрее, и что ему бы не грех познакомить товарищей с спасенной им хорошенькой полькой. Ростов принял шутку за оскорбление и, вспыхнув, наговорил офицеру таких неприятных вещей, что Денисов с трудом мог удержать обоих от дуэли. Когда офицер ушел и Денисов, сам не знавший отношений Ростова к польке, стал упрекать его за вспыльчивость, Ростов сказал ему:
– Как же ты хочешь… Она мне, как сестра, и я не могу тебе описать, как это обидно мне было… потому что… ну, оттого…
Денисов ударил его по плечу, и быстро стал ходить по комнате, не глядя на Ростова, что он делывал в минуты душевного волнения.
– Экая дуг'ацкая ваша пог'ода Г'остовская, – проговорил он, и Ростов заметил слезы на глазах Денисова.


В апреле месяце войска оживились известием о приезде государя к армии. Ростову не удалось попасть на смотр который делал государь в Бартенштейне: павлоградцы стояли на аванпостах, далеко впереди Бартенштейна.
Они стояли биваками. Денисов с Ростовым жили в вырытой для них солдатами землянке, покрытой сучьями и дерном. Землянка была устроена следующим, вошедшим тогда в моду, способом: прорывалась канава в полтора аршина ширины, два – глубины и три с половиной длины. С одного конца канавы делались ступеньки, и это был сход, крыльцо; сама канава была комната, в которой у счастливых, как у эскадронного командира, в дальней, противуположной ступеням стороне, лежала на кольях, доска – это был стол. С обеих сторон вдоль канавы была снята на аршин земля, и это были две кровати и диваны. Крыша устраивалась так, что в середине можно было стоять, а на кровати даже можно было сидеть, ежели подвинуться ближе к столу. У Денисова, жившего роскошно, потому что солдаты его эскадрона любили его, была еще доска в фронтоне крыши, и в этой доске было разбитое, но склеенное стекло. Когда было очень холодно, то к ступеням (в приемную, как называл Денисов эту часть балагана), приносили на железном загнутом листе жар из солдатских костров, и делалось так тепло, что офицеры, которых много всегда бывало у Денисова и Ростова, сидели в одних рубашках.
В апреле месяце Ростов был дежурным. В 8 м часу утра, вернувшись домой, после бессонной ночи, он велел принести жару, переменил измокшее от дождя белье, помолился Богу, напился чаю, согрелся, убрал в порядок вещи в своем уголке и на столе, и с обветрившимся, горевшим лицом, в одной рубашке, лег на спину, заложив руки под голову. Он приятно размышлял о том, что на днях должен выйти ему следующий чин за последнюю рекогносцировку, и ожидал куда то вышедшего Денисова. Ростову хотелось поговорить с ним.
За шалашом послышался перекатывающийся крик Денисова, очевидно разгорячившегося. Ростов подвинулся к окну посмотреть, с кем он имел дело, и увидал вахмистра Топчеенко.
– Я тебе пг'иказывал не пускать их жг'ать этот ког'ень, машкин какой то! – кричал Денисов. – Ведь я сам видел, Лазаг'чук с поля тащил.
– Я приказывал, ваше высокоблагородие, не слушают, – отвечал вахмистр.
Ростов опять лег на свою кровать и с удовольствием подумал: «пускай его теперь возится, хлопочет, я свое дело отделал и лежу – отлично!» Из за стенки он слышал, что, кроме вахмистра, еще говорил Лаврушка, этот бойкий плутоватый лакей Денисова. Лаврушка что то рассказывал о каких то подводах, сухарях и быках, которых он видел, ездивши за провизией.
За балаганом послышался опять удаляющийся крик Денисова и слова: «Седлай! Второй взвод!»
«Куда это собрались?» подумал Ростов.
Через пять минут Денисов вошел в балаган, влез с грязными ногами на кровать, сердито выкурил трубку, раскидал все свои вещи, надел нагайку и саблю и стал выходить из землянки. На вопрос Ростова, куда? он сердито и неопределенно отвечал, что есть дело.
– Суди меня там Бог и великий государь! – сказал Денисов, выходя; и Ростов услыхал, как за балаганом зашлепали по грязи ноги нескольких лошадей. Ростов не позаботился даже узнать, куда поехал Денисов. Угревшись в своем угле, он заснул и перед вечером только вышел из балагана. Денисов еще не возвращался. Вечер разгулялся; около соседней землянки два офицера с юнкером играли в свайку, с смехом засаживая редьки в рыхлую грязную землю. Ростов присоединился к ним. В середине игры офицеры увидали подъезжавшие к ним повозки: человек 15 гусар на худых лошадях следовали за ними. Повозки, конвоируемые гусарами, подъехали к коновязям, и толпа гусар окружила их.
– Ну вот Денисов всё тужил, – сказал Ростов, – вот и провиант прибыл.
– И то! – сказали офицеры. – То то радешеньки солдаты! – Немного позади гусар ехал Денисов, сопутствуемый двумя пехотными офицерами, с которыми он о чем то разговаривал. Ростов пошел к нему навстречу.
– Я вас предупреждаю, ротмистр, – говорил один из офицеров, худой, маленький ростом и видимо озлобленный.
– Ведь сказал, что не отдам, – отвечал Денисов.
– Вы будете отвечать, ротмистр, это буйство, – у своих транспорты отбивать! Наши два дня не ели.
– А мои две недели не ели, – отвечал Денисов.
– Это разбой, ответите, милостивый государь! – возвышая голос, повторил пехотный офицер.
– Да вы что ко мне пристали? А? – крикнул Денисов, вдруг разгорячась, – отвечать буду я, а не вы, а вы тут не жужжите, пока целы. Марш! – крикнул он на офицеров.
– Хорошо же! – не робея и не отъезжая, кричал маленький офицер, – разбойничать, так я вам…
– К чог'ту марш скорым шагом, пока цел. – И Денисов повернул лошадь к офицеру.
– Хорошо, хорошо, – проговорил офицер с угрозой, и, повернув лошадь, поехал прочь рысью, трясясь на седле.
– Собака на забог'е, живая собака на забог'е, – сказал Денисов ему вслед – высшую насмешку кавалериста над верховым пехотным, и, подъехав к Ростову, расхохотался.
– Отбил у пехоты, отбил силой транспорт! – сказал он. – Что ж, не с голоду же издыхать людям?
Повозки, которые подъехали к гусарам были назначены в пехотный полк, но, известившись через Лаврушку, что этот транспорт идет один, Денисов с гусарами силой отбил его. Солдатам раздали сухарей в волю, поделились даже с другими эскадронами.
На другой день, полковой командир позвал к себе Денисова и сказал ему, закрыв раскрытыми пальцами глаза: «Я на это смотрю вот так, я ничего не знаю и дела не начну; но советую съездить в штаб и там, в провиантском ведомстве уладить это дело, и, если возможно, расписаться, что получили столько то провианту; в противном случае, требованье записано на пехотный полк: дело поднимется и может кончиться дурно».
Денисов прямо от полкового командира поехал в штаб, с искренним желанием исполнить его совет. Вечером он возвратился в свою землянку в таком положении, в котором Ростов еще никогда не видал своего друга. Денисов не мог говорить и задыхался. Когда Ростов спрашивал его, что с ним, он только хриплым и слабым голосом произносил непонятные ругательства и угрозы…
Испуганный положением Денисова, Ростов предлагал ему раздеться, выпить воды и послал за лекарем.
– Меня за г'азбой судить – ох! Дай еще воды – пускай судят, а буду, всегда буду подлецов бить, и госудаг'ю скажу. Льду дайте, – приговаривал он.
Пришедший полковой лекарь сказал, что необходимо пустить кровь. Глубокая тарелка черной крови вышла из мохнатой руки Денисова, и тогда только он был в состоянии рассказать все, что с ним было.
– Приезжаю, – рассказывал Денисов. – «Ну, где у вас тут начальник?» Показали. Подождать не угодно ли. «У меня служба, я зa 30 верст приехал, мне ждать некогда, доложи». Хорошо, выходит этот обер вор: тоже вздумал учить меня: Это разбой! – «Разбой, говорю, не тот делает, кто берет провиант, чтоб кормить своих солдат, а тот кто берет его, чтоб класть в карман!» Так не угодно ли молчать. «Хорошо». Распишитесь, говорит, у комиссионера, а дело ваше передастся по команде. Прихожу к комиссионеру. Вхожу – за столом… Кто же?! Нет, ты подумай!…Кто же нас голодом морит, – закричал Денисов, ударяя кулаком больной руки по столу, так крепко, что стол чуть не упал и стаканы поскакали на нем, – Телянин!! «Как, ты нас с голоду моришь?!» Раз, раз по морде, ловко так пришлось… «А… распротакой сякой и… начал катать. Зато натешился, могу сказать, – кричал Денисов, радостно и злобно из под черных усов оскаливая свои белые зубы. – Я бы убил его, кабы не отняли.
– Да что ж ты кричишь, успокойся, – говорил Ростов: – вот опять кровь пошла. Постой же, перебинтовать надо. Денисова перебинтовали и уложили спать. На другой день он проснулся веселый и спокойный. Но в полдень адъютант полка с серьезным и печальным лицом пришел в общую землянку Денисова и Ростова и с прискорбием показал форменную бумагу к майору Денисову от полкового командира, в которой делались запросы о вчерашнем происшествии. Адъютант сообщил, что дело должно принять весьма дурной оборот, что назначена военно судная комиссия и что при настоящей строгости касательно мародерства и своевольства войск, в счастливом случае, дело может кончиться разжалованьем.
Дело представлялось со стороны обиженных в таком виде, что, после отбития транспорта, майор Денисов, без всякого вызова, в пьяном виде явился к обер провиантмейстеру, назвал его вором, угрожал побоями и когда был выведен вон, то бросился в канцелярию, избил двух чиновников и одному вывихнул руку.
Денисов, на новые вопросы Ростова, смеясь сказал, что, кажется, тут точно другой какой то подвернулся, но что всё это вздор, пустяки, что он и не думает бояться никаких судов, и что ежели эти подлецы осмелятся задрать его, он им ответит так, что они будут помнить.
Денисов говорил пренебрежительно о всем этом деле; но Ростов знал его слишком хорошо, чтобы не заметить, что он в душе (скрывая это от других) боялся суда и мучился этим делом, которое, очевидно, должно было иметь дурные последствия. Каждый день стали приходить бумаги запросы, требования к суду, и первого мая предписано было Денисову сдать старшему по себе эскадрон и явиться в штаб девизии для объяснений по делу о буйстве в провиантской комиссии. Накануне этого дня Платов делал рекогносцировку неприятеля с двумя казачьими полками и двумя эскадронами гусар. Денисов, как всегда, выехал вперед цепи, щеголяя своей храбростью. Одна из пуль, пущенных французскими стрелками, попала ему в мякоть верхней части ноги. Может быть, в другое время Денисов с такой легкой раной не уехал бы от полка, но теперь он воспользовался этим случаем, отказался от явки в дивизию и уехал в госпиталь.


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