Прогулка шестая. Заглядываем за горизонт

Идем дальше в GOру. Настало время рассказать вам всю правду про функции в go и про другие его интересные особенности.

Функции могут возвращать несколько значений

Да, возвращаемое значение функции может быть далеко не одно. Например:

func minmax(a []int) (int, int) {
	max := a[0]
	min := a[0]
	for i := 0; i<len(a); i++ {
		if a[i] > max { max = a[i] }
		if a[i] < min { min = a[i] }
	}
	return max, min
}

func main() {
	a := []int{1, 5, 3, 4, 2} // Опишем слайс
	x, y := minmax(a)
	fmt.Printf("max=%d, min=%d\n", x, y)
}

Как быть, если одно из возвращаемых значений нам не нужно? Не выделять же для него отдельную переменную (тем более, что вы уже заметили — go не любит неиспользуемые переменные или модули).

Для игнорирования значения используйте специальную переменную «_» (подчеркивание):

a := []int{1, 5, 3, 4, 2}
x, _ := minmax(a)
_, y := minmax(a)

Функции могут возвращать именованные значения. Например, нашу функцию minmax() можно переписать вот так:

func minmax(a []int) (min, max int) {
    max, min = a[0], a[0]
    for i := 0; i<len(a); i++ {
        if a[i] > max { max = a[i] }
        if a[i] < min { min = a[i] }
    }
    return
}

Это удобно, если значения возвращаемых переменных устанавливаются во многих местах функции и функция имеет несколько точек выхода (операторов return).

В условных операторах можно указывать не только условие

Рассмотрим гипотетическую функцию consume, которая возвращает количество полученных байт. Если это количество положительно, то данные следует обработать.

Знание других языков программирования подсказывает нам:

n := foo()
if n > 0 { .. }

Однако go позволяет сократить эту запись:

if n := foo(); n > 0 { .. }

Так код получается немного лаконичнее.

Помимо массивов и слайсов, есть еще и мапы

Map — это хэш-таблица, в которой хранятся данные и их ключи.
Создаются мапы очень похоже на массивы и слайсы:

// Тип ключа указывается в квадратных скобках, значение - за скобками.
// Например, ключи типа int, значения типа string:
m := map[int]string 

// Мапы можно сразу инициализировать (как и массивы/слайсы):
days := map[string] bool {
"Mon" : false
"Tue" : false
"Wed" : false
"Thu" : false
"Fri" : false
"Sat" : true
"Sun" : true
} // Ключи - строковые (дни недели), значение - булевы (выходной/не выходной).

Так же как и слайсы, мапы — это указатели, а потому нет ничего страшного в передаче их по значению.

Получить значение по ключу можно очень просто. И для этого есть два способа:

var weekend bool, ok
// Способ первый:
weekend = days["Mon"] // Вернет false
weekend = days["Sun"] // Вернет true
weekend = days["NoSuchDay"] // Вернет значние типа по умолчанию. Для bool это falsе
// Способ второй - проверять, есть ли такой ключ в мапе:
weekend, ok = days["Mon"] // Вернет (false, true)
weekend, ok = days["NoSuchDay"] // Вернет (false, false)

Интересным образом можно удалять элементы из мапы:

// Убираем понедельник:
days["Mon"] = false, false // Второе значение false обозначает удаление
days["NoSuchDay"] = false, false // Ключа может и не быть в мапе

Табель о рангах — удобная итерация

Если вы еще итерируете массивы с помощью индексов, то мы идем к вам.

В go есть интересная конструкция — `range` позволит сэкономить вам очередную строчку кода.
Итерировать с её помощью можно мапы (порядок индексов для них не определен), слайсы, массивы и строки.
`range`возвращает значение элемента массивы и его индекс одновременно:

a := []int {5, 3, 4, 2, 1}
// Индексы будут: 0,1,2,3,4
// Значения будут: 5,3,4,2,1
for index, value := range a {
    fmt.Println("Index = ", index, "; value = ", value);
}

В общем-то все прозрачно, отмечу только, что для строк значениями являются не байты, а руны (те самые юникодные символы), а для мапов значениями являются именно значения, не ключи.

Все. До следующих шаGoв!

Реклама

2 comments on “Прогулка шестая. Заглядываем за горизонт

  1. Женя:

    Индексьі будут начінаться с нуля все же

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s