Fix Go tutorial, especially ru translation

This commit is contained in:
Qumeric 2014-04-16 18:06:58 +04:00
parent b2a47cf123
commit 07b229a425
2 changed files with 107 additions and 79 deletions

View File

@ -171,10 +171,10 @@ func learnFlowControl() {
} }
// Function literals are closures. // Function literals are closures.
xBig := func() bool { xBig := func() bool {
return x > 100 // References x declared above switch statement. return x > 10000 // References x declared above switch statement.
} }
fmt.Println("xBig:", xBig()) // true (we last assigned 1e6 to x). fmt.Println("xBig:", xBig()) // true (we last assigned e^10 to x).
x /= m.Exp(9) // This makes x == e. x = 1.3e3 // This makes x == 1300
fmt.Println("xBig:", xBig()) // false now. fmt.Println("xBig:", xBig()) // false now.
// When you need it, you'll love it. // When you need it, you'll love it.
@ -185,13 +185,11 @@ love:
learnInterfaces() // Good stuff coming up! learnInterfaces() // Good stuff coming up!
} }
func learnDefer() (ok bool) { func learnDefer() (ok bool) {
// deferred statements are executed just before the function returns. // Deferred statements are executed just before the function returns.
defer fmt.Println("deferred statements execute in reverse (LIFO) order.") defer fmt.Println("deferred statements execute in reverse (LIFO) order.")
defer fmt.Println("\nThis line is being printed first because") defer fmt.Println("\nThis line is being printed first because")
// defer is commonly used to close a file, so the function closing the file // Defer is commonly used to close a file, so the function closing the file
// stays close to the function opening the file // stays close to the function opening the file
return true return true
} }

View File

@ -3,8 +3,12 @@ language: Go
filename: learngo-ru.go filename: learngo-ru.go
contributors: contributors:
- ["Sonia Keys", "https://github.com/soniakeys"] - ["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: translators:
- ["Artem Medeusheyev", "https://github.com/armed"] - ["Artem Medeusheyev", "https://github.com/armed"]
- ["Valery Cherepanov", "https://github.com/qumeric"]
lang: ru-ru lang: ru-ru
--- ---
@ -31,8 +35,9 @@ package main
// Import предназначен для указания зависимостей этого файла. // Import предназначен для указания зависимостей этого файла.
import ( import (
"fmt" // Пакет в стандартной библиотеке Go "fmt" // Пакет в стандартной библиотеке Go
"net/http" // Да, это web server! "net/http" // Да, это веб-сервер!
"strconv" // Конвертирование типов в строки и обратно "strconv" // Конвертирование типов в строки и обратно
m "math" // Импортировать math под локальным именем m.
) )
// Объявление функции. Main это специальная функция, служащая точкой входа для // Объявление функции. Main это специальная функция, служащая точкой входа для
@ -40,7 +45,7 @@ import (
// скобки. // скобки.
func main() { func main() {
// Println выводит строку в stdout. // Println выводит строку в stdout.
// В данном случае фигурирует вызов функции из пакета fmt. // Данная функция находится в пакете fmt.
fmt.Println("Hello world!") fmt.Println("Hello world!")
// Вызов другой функции из текущего пакета. // Вызов другой функции из текущего пакета.
@ -55,57 +60,57 @@ func beyondHello() {
// Краткое определение := позволяет объявить перменную с автоматической // Краткое определение := позволяет объявить перменную с автоматической
// подстановкой типа из значения. // подстановкой типа из значения.
y := 4 y := 4
sum, prod := learnMultiple(x, y) // функция возвращает два значения sum, prod := learnMultiple(x, y) // Функция возвращает два значения.
fmt.Println("sum:", sum, "prod:", prod) // простой вывод fmt.Println("sum:", sum, "prod:", prod) // Простой вывод.
learnTypes() // < y minutes, learn more! learnTypes() // < y minutes, learn more!
} }
// Функция имеющая входные параметры и возврат нескольких значений. // Функция имеющая входные параметры и возврат нескольких значений.
func learnMultiple(x, y int) (sum, prod int) { func learnMultiple(x, y int) (sum, prod int) {
return x + y, x * y // возврат двух результатов return x + y, x * y // Возврат двух значений.
} }
// Некотрые встроенные типы и литералы. // Некотрые встроенные типы и литералы.
func learnTypes() { func learnTypes() {
// Краткое определение переменной говорит само за себя. // Краткое определение переменной говорит само за себя.
s := "Learn Go!" // тип string s := "Learn Go!" // Тип string.
s2 := `"Чистый" строковой литерал s2 := `"Чистый" строковой литерал
может содержать переносы строк` // тоже тип данных string может содержать переносы строк` // Тоже тип данных string
// символ не из ASCII. Исходный код Go в кодировке UTF-8. // Символ не из ASCII. Исходный код Go в кодировке UTF-8.
g := 'Σ' // тип rune, это алиас для типа uint32, содержит юникод символ g := 'Σ' // тип rune, это алиас для типа uint32, содержит символ юникода.
f := 3.14195 // float64, 64-х битное число с плавающей точкой (IEEE-754) f := 3.14195 // float64, 64-х битное число с плавающей точкой (IEEE-754).
c := 3 + 4i // complex128, внутри себя содержит два float64 c := 3 + 4i // complex128, внутри себя содержит два float64.
// Синтаксис var с инициализациями // Синтаксис var с инициализациями.
var u uint = 7 // беззнаковое, но размер зависит от реализации, как и у int var u uint = 7 // Беззнаковое, но размер зависит от реализации, как и у int.
var pi float32 = 22. / 7 var pi float32 = 22. / 7
// Синтаксис приведения типа с кратким определением // Синтаксис приведения типа с кратким определением
n := byte('\n') // byte алиас для uint8 n := byte('\n') // byte это алиас для uint8.
// Массивы (Array) имеют фиксированный размер на момент компиляции. // Массивы имеют фиксированный размер на момент компиляции.
var a4 [4]int // массив из 4-х int, проинициализирован нулями var a4 [4]int // массив из 4-х int, инициализирован нулями.
a3 := [...]int{3, 1, 5} // массив из 3-х int, ручная инициализация a3 := [...]int{3, 1, 5} // массив из 3-х int, ручная инициализация.
// Slice имеют динамическую длину. И массивы и slice-ы имеют каждый свои // Слайсы (slices) имеют динамическую длину. И массивы, и слайсы имеют свои
// преимущества, но slice-ы используются гораздо чаще. // преимущества, но слайсы используются гораздо чаще.
s3 := []int{4, 5, 9} // по сравнению с a3 тут нет троеточия s3 := []int{4, 5, 9} // Сравните с a3. Тут нет троеточия.
s4 := make([]int, 4) // выделение памяти для slice из 4-х int (нули) s4 := make([]int, 4) // Выделение памяти для слайса из 4-х int (нули).
var d2 [][]float64 // только объявление, память не выделяется var d2 [][]float64 // Только объявление, память не выделяется.
bs := []byte("a slice") // конвертирование строки в slice байтов bs := []byte("a slice") // Синтаксис приведения типов.
p, q := learnMemory() // объявление p и q как указателей на int. p, q := learnMemory() // Объявление p и q как указателей на int.
fmt.Println(*p, *q) // * извлекает указатель. Печатает два int-а. fmt.Println(*p, *q) // * извлекает указатель. Печатает два int-а.
// Map как словарь или хеш теблица из других языков является ассоциативным // Map, также как и словарь или хеш из некоторых других языков, является
// массивом с динамически изменяемым размером. // ассоциативным массивом с динамически изменяемым размером.
m := map[string]int{"three": 3, "four": 4} m := map[string]int{"three": 3, "four": 4}
m["one"] = 1 m["one"] = 1
delete(m, "three") // встроенная функция, удаляет элемент из map-а. delete(m, "three") // Встроенная функция, удаляет элемент из map-а.
// Неиспользуемые переменные в Go являются ошибкой. // Неиспользуемые переменные в Go являются ошибкой.
// Нижнее подчеркивание позволяет игнорировать такие переменные. // Нижнее подчеркивание позволяет игнорировать такие переменные.
@ -113,79 +118,91 @@ func learnTypes() {
// Вывод считается использованием переменной. // Вывод считается использованием переменной.
fmt.Println(s, c, a4, s3, d2, m) fmt.Println(s, c, a4, s3, d2, m)
learnFlowControl() // идем далее learnFlowControl() // Идем дальше.
} }
// У Go есть полноценный сборщик мусора. В нем есть указатели но нет арифметики // У Go есть полноценный сборщик мусора. В нем есть указатели но нет арифметики
// указатеей. Вы можете допустить ошибку с указателем на nil, но не с его // указатеей. Вы можете допустить ошибку с указателем на nil, но не с
// инкрементацией. // инкрементацией указателя.
func learnMemory() (p, q *int) { func learnMemory() (p, q *int) {
// Именованные возвращаемые значения p и q являются указателями на int. // Именованные возвращаемые значения p и q являются указателями на int.
p = new(int) // встроенная функция new выделяет память. p = new(int) // Встроенная функция new выделяет память.
// Выделенный int проинициализирован нулем, p больше не содержит nil. // Выделенный int проинициализирован нулем, p больше не содержит nil.
s := make([]int, 20) // Выделение единого блока памяти под 20 int-ов, s := make([]int, 20) // Выделение единого блока памяти под 20 int-ов.
s[3] = 7 // назначение одному из них, s[3] = 7 // Присвоить значение одному из них.
r := -2 // опредление еще одной локальной переменной, r := -2 // Опредление еще одну локальную переменную.
return &s[3], &r // амперсанд обозначает получение адреса переменной. return &s[3], &r // Амперсанд(&) обозначает получение адреса переменной.
} }
func expensiveComputation() int { func expensiveComputation() float64 {
return 1e6 return m.Exp(10)
} }
func learnFlowControl() { func learnFlowControl() {
// If-ы всегда требуют наличине фигурных скобок, но круглые скобки // If-ы всегда требуют наличине фигурных скобок, но не круглых.
// необязательны.
if true { if true {
fmt.Println("told ya") fmt.Println("told ya")
} }
// Форматирование кода стандартизировано утилитой "go fmt". // Форматирование кода стандартизировано утилитой "go fmt".
if false { if false {
// все тлен // Будущего нет.
} else { } else {
// жизнь прекрасна // Жизнь прекрасна.
} }
// Использоване switch на замену нескольким if-else // Используйте switch вместо нескольких if-else.
x := 1 x := 42.0
switch x { switch x {
case 0: case 0:
case 1: case 1:
// case-ы в Go не проваливаются, т.е. break по умолчанию case 42:
case 2: // Case-ы в Go не "проваливаются" (неявный break).
// не выполнится case 43:
// Не выполнится.
} }
// For, как и if не требует круглых скобок // For, как и if не требует круглых скобок
for x := 0; x < 3; x++ { // ++ это операция // Переменные, объявленные в for и if являются локальными.
for x := 0; x < 3; x++ { // ++ это операция.
fmt.Println("итерация", x) fmt.Println("итерация", x)
} }
// тут x == 1. // Здесь x == 42.
// For это единственный цикл в Go, но у него несколько форм. // For это единственный цикл в Go, но у него есть альтернативные формы.
for { // бесконечный цикл for { // Бесконечный цикл.
break // не такой уж и бесконечный break // Не такой уж и бесконечный.
continue // не выполнится continue // Не выполнится.
} }
// Как и в for, := в if-е означает объявление и присвоение значения y, // Как и в for, := в if-е означает объявление и присвоение значения y,
// затем проверка y > x. // проверка y > x происходит после.
if y := expensiveComputation(); y > x { if y := expensiveComputation(); y > x {
x = y x = y
} }
// Функции являются замыканиями. // Функции являются замыканиями.
xBig := func() bool { xBig := func() bool {
return x > 100 // ссылается на x, объявленый выше switch. return x > 10000 // Ссылается на x, объявленый выше switch.
} }
fmt.Println("xBig:", xBig()) // true (т.к. мы присвоили x = 1e6) fmt.Println("xBig:", xBig()) // true (т.к. мы присвоили x = e^10).
x /= 1e5 // тут х == 10 x = 1.3e3 // Тут х == 1300
fmt.Println("xBig:", xBig()) // теперь false fmt.Println("xBig:", xBig()) // Теперь false.
// Метки, куда же без них, их все любят. // Метки, куда же без них, их все любят.
goto love goto love
love: love:
learnDefer() // Быстрый обзор важного ключевого слова.
learnInterfaces() // О! Интерфейсы, идем далее. learnInterfaces() // О! Интерфейсы, идем далее.
} }
// Объявление Stringer как интерфейса с одним мметодом, String. 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 { type Stringer interface {
String() string String() string
} }
@ -196,35 +213,48 @@ type pair struct {
} }
// Объявление метода для типа pair. Теперь pair реализует интерфейс Stringer. // Объявление метода для типа pair. Теперь pair реализует интерфейс Stringer.
func (p pair) String() string { // p в данном случае называют receiver-ом func (p pair) String() string { // p в данном случае называют receiver-ом.
// Sprintf - еще одна функция из пакета fmt. // Sprintf еще одна функция из пакета fmt.
// Обращение к полям p через точку. // Обращение к полям p через точку.
return fmt.Sprintf("(%d, %d)", p.x, p.y) return fmt.Sprintf("(%d, %d)", p.x, p.y)
} }
func learnInterfaces() { func learnInterfaces() {
// Синтаксис с фигурными скобками это "литерал структуры". Он возвращает // Синтаксис с фигурными скобками это "литерал структуры". Он возвращает
// проинициализированную структуру, а оператор := присваивает ее в p. // проинициализированную структуру, а оператор := присваивает её p.
p := pair{3, 4} p := pair{3, 4}
fmt.Println(p.String()) // вызов метода String у p, типа pair. fmt.Println(p.String()) // Вызов метода String у p.
var i Stringer // объявление i как типа с интерфейсом Stringer. var i Stringer // Объявление i как типа с интерфейсом Stringer.
i = p // валидно, т.к. pair реализует Stringer. i = p // Валидно, т.к. pair реализует Stringer.
// Вызов метода String у i, типа Stringer. Вывод такой же что и выше. // Вызов метода String у i, типа Stringer. Вывод такой же, что и выше.
fmt.Println(i.String()) fmt.Println(i.String())
// Функции в пакете fmt сами всегда вызывают метод String у объектов для // Функции в пакете fmt сами всегда вызывают метод String у объектов для
// получения строкового представления о них. // получения строкового представления о них.
fmt.Println(p) // Вывод такой же что и выше. Println вызывает метод String. fmt.Println(p) // Вывод такой же, что и выше. Println вызывает метод String.
fmt.Println(i) // тоже самое fmt.Println(i) // Вывод такой же, что и выше.
learnVariadicParams("Учиться", "учиться", "и еще раз учиться!")
}
// Функции могут иметь варьируемое количество параметров.
func learnVariadicParams(myStrings ...interface{}) {
// Вывести все параметры с помощью итерации.
for _, param := range myStrings {
fmt.Println("param:", param)
}
// Передать все варьируемые параметры.
fmt.Println("params:", fmt.Sprintln(myStrings...))
learnErrorHandling() learnErrorHandling()
} }
func learnErrorHandling() { func learnErrorHandling() {
// Идиома ", ok" служит для обозначения сработало что-то или нет. // Идиома ", ok" служит для обозначения корректного срабатывания чего-либо.
m := map[int]string{3: "three", 4: "four"} m := map[int]string{3: "three", 4: "four"}
if x, ok := m[1]; !ok { // ok будет false, потому что 1 нет в map-е. if x, ok := m[1]; !ok { // ok будет false, потому что 1 нет в map-е.
fmt.Println("тут никого") fmt.Println("тут никого нет")
} else { } else {
fmt.Print(x) // x содержал бы значение, если бы 1 был в map-е. fmt.Print(x) // x содержал бы значение, если бы 1 был в map-е.
} }
@ -237,7 +267,7 @@ func learnErrorHandling() {
learnConcurrency() learnConcurrency()
} }
// c это тип данных channel (канал), объект для конкуррентного взаимодействия. // c это тип данных channel (канал), объект для конкуррентного взаимодействия.
func inc(i int, c chan int) { func inc(i int, c chan int) {
c <- i + 1 // когда channel слева, <- являтся оператором "отправки". c <- i + 1 // когда channel слева, <- являтся оператором "отправки".
} }