Menu
Coddy logo textTech

Переключатель типов

Часть раздела Логика и управление потоком путешествия по GO на Coddy — урок 18 из 68.

Хотя утверждения типа (type assertions) хорошо работают для проверки одного типа, вам часто нужно обрабатывать несколько возможных типов для переменной интерфейса. Именно здесь переключатель типов (type switch) становится невероятно полезным — он предоставляет чистый способ выполнения различных действий в зависимости от конкретного типа.

Переключатель типов использует этот специальный синтаксис: switch v := i.(type). Обратите внимание на ключевое слово (type) вместо конкретного типа. Переменная v будет содержать фактическое значение со своим конкретным типом в каждом случае:

func describe(data interface{}) {
    switch v := data.(type) {
    case int:
        fmt.Printf("Integer: %d\n", v)
    case string:
        fmt.Printf("String: %s\n", v)
    case bool:
        fmt.Printf("Boolean: %t\n", v)
    default:
        fmt.Printf("Unknown type: %T\n", v)
    }
}

В каждом случае v автоматически имеет правильный тип — дополнительное утверждение типа не требуется. Это делает переключатели типов гораздо чище, чем создание цепочек из нескольких утверждений типов с помощью операторов if-else, особенно когда вам нужно обработать несколько различных типов в одном месте.

quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

challenge icon

Задание

Легко

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

Вы получите два входных значения:

  • Строка, представляющая тип уведомления (например, "email", "sms", "push" или "alert")
  • Строка, представляющая содержимое или значение уведомления

Ваша задача:

  1. Создать функцию с именем processNotification, которая принимает параметр типа interface{}
  2. На основе входного типа уведомления преобразовать содержимое в соответствующий тип Go и сохранить его в переменной типа interface{}:
    • Для "email": использовать содержимое как строку
    • Для "sms": преобразовать содержимое в целое число (представляющее количество символов)
    • Для "push": преобразовать содержимое в логическое значение (true для "enabled", false для всего остального)
    • Для "alert": преобразовать содержимое в float64 (представляющее уровень приоритета)
  3. Вызвать функцию processNotification с преобразованным значением
  4. Внутри processNotification использовать переключатель типов (type switch) для обработки каждого типа и вывода соответствующего сообщения:
    • Для string: "Email notification: [value]"
    • Для int: "SMS notification with [value] characters"
    • Для bool: "Push notifications: [value]"
    • Для float64: "Alert with priority: [value]"
    • Для любого другого типа: "Unknown notification type"

Используйте пакет strconv для преобразования строк. Для логического преобразования только значение "enabled" должно приводить к true. Это испытание демонстрирует, как переключатели типов обеспечивают чистый способ обработки нескольких типов в одной структуре управления, автоматически предоставляя вам правильно типизированное значение в каждом случае.

Шпаргалка

Переключатель типов (type switch) предоставляет чистый способ обработки нескольких возможных типов для переменной интерфейса, используя синтаксис switch v := i.(type):

func describe(data interface{}) {
    switch v := data.(type) {
    case int:
        fmt.Printf("Integer: %d\n", v)
    case string:
        fmt.Printf("String: %s\n", v)
    case bool:
        fmt.Printf("Boolean: %t\n", v)
    default:
        fmt.Printf("Unknown type: %T\n", v)
    }
}

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

Попробуйте сами

package main

import (
	"fmt"
	"strconv"
)

func main() {
	// Чтение входных данных
	var notificationType string
	var content string
	fmt.Scanln(&notificationType)
	fmt.Scanln(&content)
	
	// TODO: Напишите свой код ниже
	// 1. Создайте функцию processNotification, которая принимает параметр типа interface{}
	// 2. Преобразуйте content в соответствующий тип на основе notificationType
	// 3. Вызовите processNotification с преобразованным значением
	// 4. Используйте переключатель типов (type switch) внутри processNotification для обработки различных типов
	
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Логика и управление потоком