Как в Swift создать коллекцию для хранения элементов разных типов?

«Как в Swift создать коллекцию для хранения элементов разных типов?» — вопрос из категории Swift Core, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Типизированный массив [Element] в Swift хранит элементы одного типа. Для гетерогенных коллекций используйте следующие подходы, от наиболее к наименее предпочтительному:

1. Enum с ассоциированными значениями (типобезопасный и рекомендуемый)

enum HeterogeneousValue {
    case integer(Int)
    case text(String)
    case floatingPoint(Double)
    case boolean(Bool)
}

let collection: [HeterogeneousValue] = [
    .integer(42),
    .text("Hello"),
    .floatingPoint(3.14),
    .boolean(true)
]

for item in collection {
    switch item {
    case .integer(let value): print("Int: (value)")
    case .text(let value): print("String: (value)")
    case .floatingPoint(let value): print("Double: (value)")
    case .boolean(let value): print("Bool: (value)")
    }
}

2. Протоколы (когда у элементов общая функциональность)

protocol Renderable {
    func render() -> String
}

struct Label: Renderable { func render() -> String { "Label" } }
struct Button: Renderable { func render() -> String { "Button" } }

let uiElements: [Renderable] = [Label(), Button()]
uiElements.forEach { print($0.render()) }

3. Тип Any (используйте с осторожностью)

let mixedArray: [Any] = [1, "Text", 3.14, true]

for element in mixedArray {
    switch element {
    case let intValue as Int: print("Integer: (intValue)")
    case let stringValue as String: print("String: (stringValue)")
    case let doubleValue as Double: print("Double: (doubleValue)")
    case let boolValue as Bool: print("Bool: (boolValue)")
    default: print("Unknown type")
    }
}

Рекомендации:

  • Предпочитайте enum для фиксированного набора типов — это обеспечивает безопасность типов и исчерпывающую обработку в switch.
  • Используйте протоколы, когда важна общая поведенческая контракт.
  • Избегайте Any — он обходит систему типов Swift, требует ручных проверок и подвержен ошибкам времени выполнения.