Создать массив структур с обобщениями - PullRequest
0 голосов
/ 10 июня 2019

Я пытаюсь создать структуру, которая использует обобщенные значения для установки типа свойства.

Это работает нормально, как показано ниже, однако я хотел бы иметь возможность перебрать коллекцию этих структур и проверить реквизит expiry, чтобы я мог действовать, если срок его действия истек.

enum ContainerExpiryType {

    case seconds(_ seconds: Int), minutes(_ minutes: Int), hours(_ hours: Int), days(_ days: Int), date(_ date: Date)

    private var calender: Calendar {
        return Calendar.current
    }

    var date: Date? {
        switch self {
        case .seconds(let seconds):
            return calender.date(byAdding: .second, value: seconds, to: Date())
        case .minutes(let minutes):
            return calender.date(byAdding: .minute, value: minutes, to: Date())
        case .hours(let hours):
            return calender.date(byAdding: .hour, value: hours, to: Date())
        case .days(let days):
            return calender.date(byAdding: .day, value: days, to: Date())
        case .date(let date):
            return date
        }
    }
}

struct CacheWrapper<T: Codable>: Codable {
    var id: UUID
    var expiry: Date
    var object: T

    init(object: T, expiry: ContainerExpiryType) {
        self.id = UUID()
        self.expiry = expiry.date ?? Date()
        self.object = object
    }
}

let a = CacheWrapper<String>(object: "foo", expiry: .days(1))
let b = CacheWrapper<String>(object: "bar", expiry: .days(2))
let c = CacheWrapper<Int>(object: 5, expiry: .days(-100))

let foo: [CacheWrapper<Codable>] = [a, b, c]

foo.forEach { print($0.expiry) }

Однако при этом выдается ошибка

ошибка: CacheExp.playground: 45: 11: ошибка: тип протокола 'Codable' (он же) «Decodable & Encodable») не может соответствовать «Decodable», потому что только конкретные типы могут соответствовать протоколам let foo: [CacheWrapper] = [a, b, c]

Как мне этого добиться?

1 Ответ

0 голосов
/ 10 июня 2019

Общий аргумент CacheWrapper должен быть конкретным типом, соответствующим Codable.Протокол не может соответствовать самому себе.

Решение состоит в том, чтобы создать протокол с требованием реализовать expiryid при необходимости)

protocol Wrappable {
    var id: UUID { get }
    var expiry: Date { get }
}

Принять Wrappable

struct CacheWrapper<T: Codable>: Codable, Wrappable { ...

и аннотировать

let foo: [Wrappable] = [a, b, c]

Затем вы можете напечатать

foo.forEach { print($0.expiry) }
...