День 16 · Срезы: много значений в одной переменной · страница 4 из 7

Трассировка цикла по срезу

Теперь в клетке таблицы может оказаться целый срез, а строка for работает без счётчика — нужны правила 25 и 26. Правила 1–24 действуют; все вместе они в памятке блока 3: course page 15 2.


Два новых правила

25. Срез в клетке таблицы пишется так, как его печатает fmt.Println: элементы через пробел в квадратных скобках — [12 40 5]. Пустой срез — [], а не прочерк: срез уже есть, элементов в нём нет. Изменился один элемент или добавился новый — в клетку идёт весь срез целиком, уже с изменением.

26. Строка for i, v := range s — шаг в начале каждого прохода: на нём i уже получила индекс, а v — копию элемента. После последнего прохода программа ещё раз приходит на эту строку и узнаёт, что элементов больше нет, — это тоже шаг, и на нём i и v уже прочерк.

Это правила 11–13 из дня 08 для range: у него нет значения «за границей», поэтому на последнем шаге сразу прочерк.


Разбор на примере

Ситуация. Программа отбирает номера ячеек, где остаток от 10 штук.

Код для чтения · разбираем, набирать не нужно
package main

import "fmt"

func main() {
	stock := []int{12, 3}
	big := []int{}
	for i, qty := range stock {
		if qty >= 10 {
			big = append(big, i+1)
		}
	}
	fmt.Println(big)
}

Номера строк считаются от первой строки файла: stock — строка 6, for — строка 8, append — строка 10, печать — строка 13.

Что увидите.

Вывод · это печатает программа, набирать не нужно
[1]

Как это читать — таблица.

Образец · набирать не нужно
# шаг | строка | stock  | big | i | qty
1     | 6      | [12 3] | -   | - | -
2     | 7      | [12 3] | []  | - | -
3     | 8      | [12 3] | []  | 0 | 12
4     | 9      | [12 3] | []  | 0 | 12
5     | 10     | [12 3] | [1] | 0 | 12
6     | 8      | [12 3] | [1] | 1 | 3
7     | 9      | [12 3] | [1] | 1 | 3
8     | 8      | [12 3] | [1] | - | -
9     | 13     | [12 3] | [1] | - | -

По шагам:

Шаг Что происходит Какое правило
1 stock объявлен — в клетке весь срез 25
2 big пустой — [], не прочерк 25
3 первый проход: i — 0, qty — копия stock[0] 26
4 условие 12 >= 10 верно; строка if только читает 7
5 append дописал i+1, то есть 1: в клетке уже [1] 25
6 второй проход: i — 1, qty — 3 26
7 условие 3 >= 10 ложно — строки 10 в пути нет 7, 9
8 элементов больше нет: последний шаг строки for, i и qty — прочерк 26
9 печать: значения переписаны без изменений 1, 4

Строки 11 и 12 — одинокие }, они не шаги (правило 8).

Две самопроверки. Строка for встречается на один раз больше, чем элементов в срезе: здесь элементов два, строк с номером 8 — три. И номер в big — это i+1, а не i: в колонке i на том же шаге число на единицу меньше.


Попробуйте сейчас: трассировка trace.

Цель: заполнить table.txt для своей программы program.go.

1. Откройте программу и заготовку таблицы — числа у вас свои:

▶ Выполните
cd ~/gocourse/day16/trace
cat program.go
cat table.txt

2. Заполните table.txt, не запуская программу. Шаги и первые номера строк уже стоят; остальные номера строк — тоже ваша работа: какая строка выполнится следующей, зависит от условия if. Меняйте только ?, прочерки не трогайте, строк не добавляйте.

Образец одной заполненной строки — формат, числа у вас другие:

Образец · набирать не нужно
5 | 12 | [8 25 3 40] | [1] | 0 | 8

3. Проверьте себя последней строкой таблицы: запустите программу — она печатает длину и содержимое low после цикла.

▶ Выполните
go run .

4. Закоммитьте:

▶ Выполните
cd ~/gocourse/day16
git add .
git commit -m "trace: таблица"

Готово, когда: пункт trace в course check 16 зелёный. program.go не меняйте — номера строк считаются по нему.


Что может пойти не так

Что видите Что это значит Что делать
trace красный, подсказка «осталось знаков ?» где-то не заменён ? — чаще всего в номере строки grep -n '?' table.txt покажет, где
trace красный, подсказка «строк с шагами …» строка удалена или добавлена число строк в заготовке уже верное
на шаге 2 в колонке low стоит - или 0 пустой срез записан как «нет переменной» или как число пустой срез — [] (правило 25)
в low стоят индексы 0, 2 в срез идёт i+1, а записали i номер ячейки на единицу больше индекса
на последнем шаге строки for остались последние i и qty после последнего прохода переменных цикла нет прочерк (правило 26)
после ложного if в пути есть строка с append ветка не выполнилась — её строки не шаги правило 9: номера идут с пропуском

Дальше: сумма, максимум и отчёт по ячейкам — course next