Menu
Coddy logo textTech

Пустой интерфейс (any)

Часть раздела Объектно-ориентированное программирование путешествия по GO на Coddy. Урок 28 из 107.

Пустой интерфейс — это interface с нулём методов. Поскольку каждый тип в Go имеет как минимум ноль методов, любой тип автоматически удовлетворяет пустому interface. Благодаря этому он способен хранить значения любого типа.

var anything interface{}

anything = 42
anything = "hello"
anything = true
anything = []int{1, 2, 3}

Начиная с Go 1.18, ключевое слово any было введено как псевдоним для interface{}. Они полностью взаимозаменяемы, но any легче читать.

var value any = "Go is awesome"

Пустой interface полезен, когда вам нужно обрабатывать значения неизвестных типов или типов, которые могут изменяться. Такие функции, как fmt.Println, используют его, чтобы принимать аргументы любого типа:

func PrintAnything(v any) {
    fmt.Println("Value:", v)
}

func main() {
    PrintAnything(100)
    PrintAnything("text")
    PrintAnything(3.14)
}

Однако здесь есть компромисс. Когда значение хранится в пустом interface, вы теряете доступ к информации о его конкретном типе.

Нельзя напрямую вызывать methods или обращаться к field, не извлекая сначала базовый type. В следующих уроках будет рассмотрено, как получить конкретный type из пустого interface с помощью утверждений типа и переключателей типов.

challenge icon

Задание

Легко

Давайте создадим гибкий контейнер для хранения, который может содержать значения любого типа, используя пустой interface. Вы создадите простую коробку, демонстрирующую, как any позволяет хранить разные типы в одной и той же структуре.

Вы организуете свой код в двух файлах:

  • box.go: Define структуру Box с одним полем Content типа any. Create конструктор NewBox, который accepts значение любого типа и returns pointer на Box, содержащий это значение. Add method Describe, который returns string с описанием того, что хранится в коробке.
  • main.go: Read разные значения из ввода, создайте коробки, содержащие integer, string и boolean, затем выведите описание каждой коробки, чтобы показать, как один и тот же тип Box может содержать совершенно разные значения.

Будут предоставлены следующие входные данные:

  • Строка 1: значение integer
  • Строка 2: значение string
  • Строка 3: значение boolean (true или false)

Ваш method Describe должен возвращать string в следующем формате:

Box contains: [value]

Например, если заданы 42, hello и true, результатом должно быть:

Box contains: 42
Box contains: hello
Box contains: true

Главная идея заключается в том, что ваша единственная структура Box может хранить integer, string или boolean: всё благодаря тому, что тип any accepts значения любого типа. Каждая коробка хранит что-то своё, но все они имеют один и тот же тип Box.

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

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func main() {
	reader := bufio.NewReader(os.Stdin)

	// Прочитать целочисленное значение
	line1, _ := reader.ReadString('\n')
	intVal, _ := strconv.Atoi(strings.TrimSpace(line1))

	// Прочитать строковое значение
	line2, _ := reader.ReadString('\n')
	strVal := strings.TrimSpace(line2)

	// Прочитать логическое значение
	line3, _ := reader.ReadString('\n')
	boolVal, _ := strconv.ParseBool(strings.TrimSpace(line3))

	// TODO: Создать боксы для каждого значения с помощью NewBox
	// TODO: Вывести описание каждого бокса с помощью метода Describe

	// Использовать переменные, чтобы избежать ошибок компиляции (удалите эти строки при реализации)
	_ = intVal
	_ = strVal
	_ = boolVal

	// Пример формата вывода:
	// fmt.Println(box.Describe())
}
quiz iconПроверьте себя

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

Все уроки раздела Объектно-ориентированное программирование

Потренируйтесь самостоятельно: Онлайн-компилятор Go