Есть такой ресурс для новичков в языке Go — «A Tour of Go«. Там в самом начале забавный пример под номером 7:
If и else
Переменные, объявленные внутри короткого оператора if
, также доступны в любом из блоков else
.
(Оба вызова pow
возвращают свои результаты до начала вызова fmt.Println
в main
).
package main import ( "fmt" "math" ) func pow(x, n, lim float64) float64 { if v := math.Pow(x, n); v < lim { return v } else { fmt.Printf("%g >= %g\n", v, lim) } // can't use v here, though return lim } func main() { fmt.Println( pow(3, 2, 10), pow(3, 3, 20), ) }
Это дает результат:
27 >= 20
9 20
но по логике (на первый взгляд) оно должно выдать следующее:
9
27 >= 20
20
Почему так? Есть комментарий сбоку: (Оба вызова pow возвращают свои результаты до начала вызова fmt.Println в main). … но понять что тут как новичку в Го может быть нелегко…
Секрет в том… что последняя строка кода, которая выводит на печать — fmt.Println
не печатает, пока не будут вычислены обе другие функции pow
… а сама функция pow
в начале как раз печатает fmt.Printf
. Таким образом, порядок выполнения программы следующий:
1. pow(3, 2, 10) — ничего пока не печатает, но возвращает значение
2. pow(3, 3, 20) — печатает через fmt.Printf
, а затем возвращает значение
3. fmt.Println(…) — печатает два значение, которые получает..
Итого:
Первый вызов возвращает 9
(но ничего не печатает!)
Второй вызов печатает 27 >= 20
, а затем возвращает 20
Последний вызов печатает 9 20
Вуаля!