summaryrefslogtreecommitdiffhomepage
path: root/ru-ru/go-ru.html.markdown
diff options
context:
space:
mode:
Diffstat (limited to 'ru-ru/go-ru.html.markdown')
-rw-r--r--ru-ru/go-ru.html.markdown336
1 files changed, 336 insertions, 0 deletions
diff --git a/ru-ru/go-ru.html.markdown b/ru-ru/go-ru.html.markdown
new file mode 100644
index 00000000..e06ae9bd
--- /dev/null
+++ b/ru-ru/go-ru.html.markdown
@@ -0,0 +1,336 @@
+---
+language: Go
+filename: learngo-ru.go
+contributors:
+ - ["Sonia Keys", "https://github.com/soniakeys"]
+ - ["Christopher Bess", "https://github.com/cbess"]
+ - ["Jesse Johnson", "https://github.com/holocronweaver"]
+ - ["Quint Guvernator", "https://github.com/qguv"]
+translators:
+ - ["Artem Medeusheyev", "https://github.com/armed"]
+ - ["Valery Cherepanov", "https://github.com/qumeric"]
+lang: ru-ru
+---
+
+Go - это язык общего назначения, целью которого является удобство, простота,
+конкурентность. Это не тренд в компьютерных науках, а новейший и быстрый
+способ решать насущные проблемы.
+
+Концепции Go схожи с другими императивными статически типизированными языками.
+Быстро компилируется и быстро исполняется, имеет лёгкие в понимании конструкции
+для создания масштабируемых и многопоточных программ.
+
+Может похвастаться отличной стандартной библиотекой и большим комьюнити, полным
+энтузиастов.
+
+```go
+// Однострочный комментарий
+/* Многострочный
+ комментарий */
+
+// Ключевое слово package присутствует в начале каждого файла.
+// Main это специальное имя, обозначающее исполняемый файл, нежели библиотеку.
+package main
+
+// Import предназначен для указания зависимостей этого файла.
+import (
+ "fmt" // Пакет в стандартной библиотеке Go
+ "net/http" // Да, это веб-сервер!
+ "strconv" // Конвертирование типов в строки и обратно
+ m "math" // Импортировать math под локальным именем m.
+)
+
+// Объявление функции. Main это специальная функция, служащая точкой входа для
+// исполняемой программы. Нравится вам или нет, но Go использует фигурные
+// скобки.
+func main() {
+ // Println выводит строку в stdout.
+ // Данная функция находится в пакете fmt.
+ fmt.Println("Hello world!")
+
+ // Вызов другой функции из текущего пакета.
+ beyondHello()
+}
+
+// Функции содержат входные параметры в круглых скобках.
+// Пустые скобки все равно обязательны, даже если параметров нет.
+func beyondHello() {
+ var x int // Переменные должны быть объявлены до их использования.
+ x = 3 // Присвоение значения переменной.
+ // Краткое определение := позволяет объявить переменную с автоматической
+ // подстановкой типа из значения.
+ y := 4
+ sum, prod := learnMultiple(x, y) // Функция возвращает два значения.
+ fmt.Println("sum:", sum, "prod:", prod) // Простой вывод.
+ learnTypes() // < y minutes, learn more!
+}
+
+// Функция, имеющая входные параметры и возвращающая несколько значений.
+func learnMultiple(x, y int) (sum, prod int) {
+ return x + y, x * y // Возврат двух значений.
+}
+
+// Некоторые встроенные типы и литералы.
+func learnTypes() {
+ // Краткое определение переменной говорит само за себя.
+ s := "Learn Go!" // Тип string.
+
+ s2 := `"Чистый" строковой литерал
+может содержать переносы строк` // Тоже тип данных string
+
+ // Символ не из ASCII. Исходный код Go в кодировке UTF-8.
+ g := 'Σ' // тип rune, это алиас для типа int32, содержит символ юникода.
+
+ f := 3.14195 // float64, 64-х битное число с плавающей точкой (IEEE-754).
+ c := 3 + 4i // complex128, внутри себя содержит два float64.
+
+ // Синтаксис var с инициализациями.
+ var u uint = 7 // Беззнаковое, но размер зависит от реализации, как и у int.
+ var pi float32 = 22. / 7
+
+ // Синтаксис приведения типа с кратким определением
+ n := byte('\n') // byte – это алиас для uint8.
+
+ // Массивы имеют фиксированный размер на момент компиляции.
+ var a4 [4]int // массив из 4-х int, инициализирован нулями.
+ a3 := [...]int{3, 1, 5} // массив из 3-х int, ручная инициализация.
+
+ // Слайсы (slices) имеют динамическую длину. И массивы, и слайсы имеют свои
+ // преимущества, но слайсы используются гораздо чаще.
+ s3 := []int{4, 5, 9} // Сравните с a3, тут нет троеточия.
+ s4 := make([]int, 4) // Выделение памяти для слайса из 4-х int (нули).
+ var d2 [][]float64 // Только объявление, память не выделяется.
+ bs := []byte("a slice") // Синтаксис приведения типов.
+
+ p, q := learnMemory() // Объявление p и q как указателей на int.
+ fmt.Println(*p, *q) // * извлекает указатель. Печатает два int-а.
+
+ // Map, также как и словарь или хеш из некоторых других языков, является
+ // ассоциативным массивом с динамически изменяемым размером.
+ m := map[string]int{"three": 3, "four": 4}
+ m["one"] = 1
+
+ delete(m, "three") // Встроенная функция, удаляет элемент из map-а.
+
+ // Неиспользуемые переменные в Go являются ошибкой.
+ // Нижнее подчёркивание позволяет игнорировать такие переменные.
+ _, _, _, _, _, _, _, _, _ = s2, g, f, u, pi, n, a3, s4, bs
+ // Вывод считается использованием переменной.
+ fmt.Println(s, c, a4, s3, d2, m)
+
+ learnFlowControl() // Идем дальше.
+}
+
+// У Go есть полноценный сборщик мусора. В нем есть указатели, но нет арифметики
+// указателей. Вы можете допустить ошибку с указателем на nil, но не с
+// инкрементацией указателя.
+func learnMemory() (p, q *int) {
+ // Именованные возвращаемые значения p и q являются указателями на int.
+ p = new(int) // Встроенная функция new выделяет память.
+ // Выделенный int проинициализирован нулём, p больше не содержит nil.
+ s := make([]int, 20) // Выделение единого блока памяти под 20 int-ов.
+ s[3] = 7 // Присвоить значение одному из них.
+ r := -2 // Определить ещё одну локальную переменную.
+ return &s[3], &r // Амперсанд(&) обозначает получение адреса переменной.
+}
+
+func expensiveComputation() float64 {
+ return m.Exp(10)
+}
+
+func learnFlowControl() {
+ // If-ы всегда требуют наличие фигурных скобок, но не круглых.
+ if true {
+ fmt.Println("told ya")
+ }
+ // Форматирование кода стандартизировано утилитой "go fmt".
+ if false {
+ // Будущего нет.
+ } else {
+ // Жизнь прекрасна.
+ }
+ // Используйте switch вместо нескольких if-else.
+ x := 42.0
+ switch x {
+ case 0:
+ case 1:
+ case 42:
+ // Case-ы в Go не "проваливаются" (неявный break).
+ case 43:
+ // Не выполнится.
+ }
+ // For, как и if не требует круглых скобок
+ // Переменные, объявленные в for и if являются локальными.
+ for x := 0; x < 3; x++ { // ++ – это операция.
+ fmt.Println("итерация", x)
+ }
+ // Здесь x == 42.
+
+ // For – это единственный цикл в Go, но у него есть альтернативные формы.
+ for { // Бесконечный цикл.
+ break // Не такой уж и бесконечный.
+ continue // Не выполнится.
+ }
+ // Как и в for, := в if-е означает объявление и присвоение значения y,
+ // проверка y > x происходит после.
+ if y := expensiveComputation(); y > x {
+ x = y
+ }
+ // Функции являются замыканиями.
+ xBig := func() bool {
+ return x > 10000 // Ссылается на x, объявленный выше switch.
+ }
+ fmt.Println("xBig:", xBig()) // true (т.к. мы присвоили x = e^10).
+ x = 1.3e3 // Тут х == 1300
+ fmt.Println("xBig:", xBig()) // Теперь false.
+
+ // Метки, куда же без них, их все любят.
+ goto love
+love:
+
+ learnDefer() // Быстрый обзор важного ключевого слова.
+ learnInterfaces() // О! Интерфейсы, идём далее.
+}
+
+func learnDefer() (ok bool) {
+ // Отложенные(deferred) выражения выполняются сразу перед тем, как функция
+ // возвратит значение.
+ defer fmt.Println("deferred statements execute in reverse (LIFO) order.")
+ defer fmt.Println("\nThis line is being printed first because")
+ // defer широко используется для закрытия файлов, чтобы закрывающая файл
+ // функция находилась близко к открывающей.
+ return true
+}
+
+// Объявление Stringer как интерфейса с одним методом, String.
+type Stringer interface {
+ String() string
+}
+
+// Объявление pair как структуры с двумя полями x и y типа int.
+type pair struct {
+ x, y int
+}
+
+// Объявление метода для типа pair. Теперь pair реализует интерфейс Stringer.
+func (p pair) String() string { // p в данном случае называют receiver-ом.
+ // Sprintf – ещё одна функция из пакета fmt.
+ // Обращение к полям p через точку.
+ return fmt.Sprintf("(%d, %d)", p.x, p.y)
+}
+
+func learnInterfaces() {
+ // Синтаксис с фигурными скобками это "литерал структуры". Он возвращает
+ // проинициализированную структуру, а оператор := присваивает её p.
+ p := pair{3, 4}
+ fmt.Println(p.String()) // Вызов метода String у переменной p типа pair.
+ var i Stringer // Объявление i как типа с интерфейсом Stringer.
+ i = p // Валидно, т.к. pair реализует Stringer.
+ // Вызов метода String у i типа Stringer. Вывод такой же, что и выше.
+ fmt.Println(i.String())
+
+ // Функции в пакете fmt сами всегда вызывают метод String у объектов для
+ // получения строкового представления о них.
+ fmt.Println(p) // Вывод такой же, что и выше. Println вызывает метод String.
+ fmt.Println(i) // Вывод такой же, что и выше.
+
+ learnVariadicParams("Учиться", "учиться", "и ещё раз учиться!")
+}
+
+// Функции могут иметь варьируемое количество параметров.
+func learnVariadicParams(myStrings ...interface{}) {
+ // Вывести все параметры с помощью итерации.
+ for _, param := range myStrings {
+ fmt.Println("param:", param)
+ }
+
+ // Передать все варьируемые параметры.
+ fmt.Println("params:", fmt.Sprintln(myStrings...))
+
+ learnErrorHandling()
+}
+
+func learnErrorHandling() {
+ // Идиома ", ok" служит для обозначения корректного срабатывания чего-либо.
+ m := map[int]string{3: "three", 4: "four"}
+ if x, ok := m[1]; !ok { // ok будет false, потому что 1 нет в map-е.
+ fmt.Println("тут никого нет")
+ } else {
+ fmt.Print(x) // x содержал бы значение, если бы 1 был в map-е.
+ }
+ // Идиома ", err" служит для обозначения была ли ошибка или нет.
+ if _, err := strconv.Atoi("non-int"); err != nil { // _ игнорирует значение
+ // выведет "strconv.ParseInt: parsing "non-int": invalid syntax"
+ fmt.Println(err)
+ }
+ // Мы ещё обратимся к интерфейсам чуть позже, а пока...
+ learnConcurrency()
+}
+
+// c – это тип данных channel (канал), объект для конкурентного взаимодействия.
+func inc(i int, c chan int) {
+ c <- i + 1 // когда channel слева, <- являтся оператором "отправки".
+}
+
+// Будем использовать функцию inc для конкурентной инкрементации чисел.
+func learnConcurrency() {
+ // Тот же make, что и в случае со slice. Он предназначен для выделения
+ // памяти и инициализации типов slice, map и channel.
+ c := make(chan int)
+ // Старт трех конкурентных goroutine. Числа будут инкрементированы
+ // конкурентно и, может быть параллельно, если машина правильно
+ // сконфигурирована и позволяет это делать. Все они будут отправлены в один
+ // и тот же канал.
+ go inc(0, c) // go начинает новую горутину.
+ go inc(10, c)
+ go inc(-805, c)
+ // Считывание всех трех результатов из канала и вывод на экран.
+ // Нет никакой гарантии в каком порядке они будут выведены.
+ fmt.Println(<-c, <-c, <-c) // канал справа, <- обозначает "получение".
+
+ cs := make(chan string) // другой канал, содержит строки.
+ cc := make(chan chan string) // канал каналов со строками.
+ go func() { c <- 84 }() // пуск новой горутины для отправки значения
+ go func() { cs <- "wordy" }() // ещё раз, теперь для cs
+ // Select тоже что и switch, но работает с каналами. Он случайно выбирает
+ // готовый для взаимодействия канал.
+ select {
+ case i := <-c: // полученное значение можно присвоить переменной
+ fmt.Printf("это %T", i)
+ case <-cs: // либо значение можно игнорировать
+ fmt.Println("это строка")
+ case <-cc: // пустой канал, не готов для коммуникации.
+ fmt.Println("это не выполнится.")
+ }
+ // В этой точке значение будет получено из c или cs. Одна горутина будет
+ // завершена, другая останется заблокированной.
+
+ learnWebProgramming() // Да, Go это может.
+}
+
+// Всего одна функция из пакета http запускает web-сервер.
+func learnWebProgramming() {
+ // У ListenAndServe первый параметр это TCP адрес, который нужно слушать.
+ // Второй параметр это интерфейс типа http.Handler.
+ err := http.ListenAndServe(":8080", pair{})
+ fmt.Println(err) // не игнорируйте сообщения об ошибках
+}
+
+// Реализация интерфейса http.Handler для pair, только один метод ServeHTTP.
+func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+ // Обработка запроса и отправка данных методом из http.ResponseWriter
+ w.Write([]byte("You learned Go in Y minutes!"))
+}
+```
+
+## Что дальше
+
+Основа всех основ в Go это [официальный веб сайт](http://golang.org/).
+Там можно пройти туториал, поиграться с интерактивной средой Go и почитать
+объёмную документацию.
+
+Для живого ознакомления рекомендуется почитать исходные коды [стандартной
+библиотеки Go](http://golang.org/src/pkg/). Отлично задокументированная, она
+является лучшим источником для чтения и понимания Go, его стиля и идиом. Либо
+можно, кликнув на имени функции в [документации](http://golang.org/pkg/),
+перейти к ее исходным кодам.