我有以下我无法触及的结构:
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 有足够的数据来创建该功能时,我的功能的价值才可用...... 不管怎样,一切都对我来说是类型擦除,但我不知道该怎么做,或者我是否采取了正确的方法。
任何建议将不胜感激!
这是我对您的问题的建议修复:
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
}
}