在 swift 中存储通用闭包

问题描述 投票:0回答:1

我有以下我无法触及的结构:

struct MyFeature<Value> {
    let id: UUID
    let startDate: Date
    let expirationDate: Date
    let value: Value?

    typealias Transform<RawJsonType> = ((RawJsonType) -> Value?)

    init?<RawJsonType>(json: [String: Any],
                       startDate: Date,
                       expirationDate: Date,
                       transform: Transform<RawJsonType>) {
        self.id = UUID()
        self.startDate = startDate
        self.expirationDate = expirationDate
        self.value = Self.parseValue(json: json, transform: transform)
    }

    private static func parseValue<RawJsonType>(json: [String: Any], transform: Transform<RawJsonType>) -> Value? {
        // Oversimplified logic
        guard let someJson = json as? RawJsonType else {
            return nil
        }
        return transform(someJson)
    }
}

我想“存储”变换闭包以便稍后使用。 我想将它存储在内存中,但有时拥有一个静态变量(如下所示)也很好,我可以用它来实例化给定值类型的

Feature

这就是我想做的:

struct MyFeatureMetadata<Value> {
    typealias Transform<RawJsonType> = ((RawJsonType) -> Value?)
    let name: String
    let id: UUID
    let startDate: Date
    let endDate: Date
    let transform: Transform<Any> // !

    init<RawJsonType> (
        name: String,
        id: UUID = UUID(),
        startDate: Date = .distantPast,
        endDate: Date = .distantFuture,
        transform: @escaping Transform<RawJsonType>
    ) {
        self.name = name
        self.id = id
        self.startDate = startDate
        self.endDate = endDate
        self.transform = transform // ! Cannot assign value of type...
    }
}

显然我不能只是“存储”关闭。

这就是我想要的使用方式:

enum SomeFeature: String {
    case basic
    case expert
}

extension MyFeatureMetadata<SomeFeature> {
    static var someFeature = Self(name: "some") { (rawJson: String) in
        SomeFeature(rawValue: rawJson) ?? .expert
    }
}

// At some random point I want to be able to instantiate my Feature:
let myFeature: MyFeature<SomeFeature> = MyFeature(
    json: ["": ""], // Someone else is going to provide the json
    startDate: MyFeatureMetadata.someFeature.startDate,
    expirationDate: MyFeatureMetadata.someFeature.endDate,
    transform: MyFeature.someFeature.transform
)

只有当提供的 json 有足够的数据来创建该功能时,我的功能的价值才可用...... 不管怎样,一切都对我来说是类型擦除,但我不知道该怎么做,或者我是否采取了正确的方法。

任何建议将不胜感激!

swift generics
1个回答
0
投票

这是我对您的问题的建议修复:

struct MyFeatureMetadata<Value, RawJsonType> {
    typealias Transform = ((RawJsonType) -> Value?)
    let name: String
    let id: UUID
    let startDate: Date
    let endDate: Date
    let transform: Transform // !

    init(
        name: String,
        id: UUID = UUID(),
        startDate: Date = .distantPast,
        endDate: Date = .distantFuture,
        transform: @escaping Transform
    ) {
        self.name = name
        self.id = id
        self.startDate = startDate
        self.endDate = endDate
        self.transform = transform
    }
}

enum SomeFeature: String {
    case basic
    case expert
}

extension MyFeatureMetadata where Value == SomeFeature, RawJsonType == String {
    static var someFeature = Self(name: "some") { rawJson in
        SomeFeature(rawValue: rawJson) ?? .expert
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.