【问题标题】:Create array of structs with generics使用泛型创建结构数组
【发布时间】:2019-10-24 17:15:33
【问题描述】:

我正在尝试创建一个使用泛型设置属性类型的结构。

这工作正常,如下所示,但是我希望能够遍历这些结构的集合并检查 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:错误:协议类型“可编码”(又名 'Decodable & Encodable') 不能符合 'Decodable' 因为只有 具体类型可以符合让 foo 的协议: [CacheWrapper] = [a,b,c]

我怎样才能做到这一点?

【问题讨论】:

    标签: swift generics codable


    【解决方案1】:

    CacheWrapper 的泛型参数必须是符合Codable 的具体类型。协议不能符合自己。

    一种解决方案是创建一个协议,要求实现expiry(如果需要,还可以实现id

    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) }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-10
      • 1970-01-01
      • 2015-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-26
      • 2013-09-06
      相关资源
      最近更新 更多