Ожидание и тикеры
Часть раздела Логика и управление потоком путешествия по GO на Coddy. Урок 64 из 68.
Иногда нужно контролировать время выполнения программы. В Go для этого в пакете time есть две важные функции: time.Sleep для приостановки выполнения и time.NewTicker для выполнения действий через равные промежутки времени.
Функция time.Sleep приостанавливает выполнение программы на заданное время. Она принимает time.Duration в качестве параметра и блокирует выполнение, пока это время не истечёт:
fmt.Println("Starting...")
time.Sleep(2 * time.Second)
fmt.Println("Two seconds have passed!")Для повторяющихся действий через регулярные интервалы time.NewTicker создаёт тикер, который отправляет значения в канал с заданными интервалами. Это полезно для задач, которые нужно выполнять периодически:
ticker := time.NewTicker(1 * time.Second)
for i := 0; i < 3; i++ {
<-ticker.C // Подождать следующего тика
fmt.Println("Tick", i+1)
}Эти функции времени необходимы для создания задержек, реализации тайм-аутов и планирования повторяющихся операций в программах на Go.
Задание
ЛегкоСоздайте таймер сеанса медитации, который использует time.Sleep для создания пауз между инструкциями и демонстрирует базовое управление временем в программах на Go.
Вы получите два входных значения:
- Строку с этапами медитации в формате
"step1:duration,step2:duration,step3:duration"(например,"Breathe in:3,Hold:2,Breathe out:4") - Строку с числом повторений цикла (например,
"5")
Ваша задача:
- Разобрать первое входное значение, разделив его по запятым, чтобы получить отдельные этапы медитации
- Для каждого этапа разделить строку по двоеточиям, чтобы извлечь инструкцию и длительность (в секундах)
- Преобразовать строки с длительностью в целые числа с помощью пакета
strconv - Преобразовать второе входное значение в целое число, чтобы получить количество циклов
- Вывести заголовок сеанса:
"=== MEDITATION TIMER ===" - Вывести информацию о начале сеанса:
"Starting meditation session with [number_of_cycles] cycles" - Для каждого цикла (начиная с цикла 1):
- Вывести:
"--- Cycle [cycle_number] ---" - Для каждого этапа медитации:
- Вывести:
"[instruction]..." - Использовать
time.Sleep, чтобы сделать паузу на указанную длительность (умножить длительность наtime.Millisecond, как вtime.Duration(duration) * time.Millisecond, чтобы проверки завершались быстро; в выводе по-прежнему указываются секунды) - После паузы вывести:
"[instruction] complete ([duration] seconds)"
- Вывести:
- После выполнения всех этапов цикла вывести:
"Cycle [cycle_number] finished"
- Вывести:
- После завершения всех циклов вывести сводку сеанса:
"=== SESSION COMPLETE ===""Total cycles completed: [number_of_cycles]""Steps per cycle: [number_of_steps]""Total meditation time: [total_seconds] seconds"(сумма длительностей всех этапов, умноженная на количество циклов)
- Вывести сообщение о завершении:
"Meditation session finished - well done!"
Используйте пакет time для операций приостановки, пакет strings для разделения входных строк, пакет strconv для преобразования строк в целые числа и пакет fmt для вывода. Помните, что time.Sleep принимает параметр типа time.Duration, поэтому сначала преобразуйте целое число: time.Duration(duration) * time.Millisecond. В настоящем таймере использовался бы time.Second, но паузы длительностью в целые секунды приводят к превышению времени ожидания проверок. Это задание показывает, как использовать time.Sleep для создания пауз с заданной длительностью во время выполнения программы в таких практических приложениях, как управляемая медитация или таймеры для упражнений.
Попробуйте сами
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
"time"
)
func main() {
// Считайте ввод с помощью bufio.Scanner, чтобы корректно обрабатывать пробелы
scanner := bufio.NewScanner(os.Stdin)
scanner.Scan()
stepsInput := scanner.Text()
scanner.Scan()
cyclesInput := scanner.Text()
// Разберите этапы медитации и количество циклов
steps := strings.Split(stepsInput, ",")
cycles, _ := strconv.Atoi(cyclesInput)
// TODO: Напишите свой код ниже
// Разберите каждый этап, чтобы извлечь инструкцию и длительность
// Перед обращением к элементам среза parts проверьте, что их достаточно
// Выведите заголовок сеанса и подготовительную информацию
// Пройдите по циклам и этапам
// Для пауз используйте time.Sleep: time.Duration(duration) * time.Millisecond
// Выведите сообщения о завершении и итоговую сводку
}В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Логика и управление потоком
1Продвинутое управление потоком выполнения
Switch с использованием `fallthrough`Выход из вложенных цикловПродолжение конкретного циклаОператор `goto`Итоги: Продвинутое управление циклами4Проект: Простой список задач
Настройка проектаДобавление задачи2Структуры и методы
Определение методов для структурПолучатели по значениюПолучатели по указателюВыбор типа получателяМетоды против функцийИтоги: поведение структур5Карты: подробный разбор
Карты структурУказатели как значения картПроверка карт на nilСравнение картИтоги: счетчик частоты слов3Интерфейсы (Основы)
Что такое интерфейс?Определение интерфейсаРеализация интерфейсаИспользование интерфейсных типовПустой интерфейсУтверждение типаПереключатель типовИтоги: Фигуры и поведениеПотренируйтесь самостоятельно: Онлайн-компилятор Go