我需要实现TypeConverter,然后将其用作变量类型。受ObjectMapper的启发,我定义了以下协议:
df[grep( "de[a-zA-Z0-9]{3}", df$code),]
具体实施是:
protocol TypeConverter {
associatedtype A
associatedtype B
func transformFrom(fromType: A?) -> B?
func transformTo(toType: B?) -> A?
}
因为协议TypeConverter有关联类型,我不能将它声明为变量,例如:var converter:TypeConverter,但我需要这样的功能。这种情况的解决方案是使用typeErasure。通过这个链接https://medium.com/@NilStack/swift-world-type-erasure-5b720bc0318a它应该是可能的,但我不知道如何。
这是我的尝试,但它不对:):这是否能以这种方式解决?或者我应该使用这个:https://appventure.me/2017/12/10/patterns-for-working-with-associated-types?
class IntToStringTypeConverter: TypeConverter {
typealias A = Int
typealias B = String
func transformFrom(fromType: Int?) -> String? {
guard let fromType = fromType else { return nil }
return String(fromType)
}
func transformTo(toType: String?) -> Int? {
guard let toType = toType else { return nil }
return Int(toType)
}
}
答案 0 :(得分:3)
对于具有关联类型的协议,这不是很好用。 PAT是非常复杂的工具,在这种情况下根本没有理由。你甚至不需要类型橡皮擦,只需要一个结构:
struct TypeConverter<Model, Form> {
let transformFrom: (Model) -> Form?
let transformTo: (Form) -> Model?
}
let stringToInt = TypeConverter(transformFrom:String.init,
transformTo:Int.init)
stringToInt.transformFrom(123)
stringToInt.transformTo("x")
如果你愿意,你当然可以使这符合TypeConverter
(我可以更新添加),但我建议完全删除协议,只使用结构。这与Formatter
的工作方式非常接近。
答案 1 :(得分:0)
在实现了两个单元格之后,我发现我可以简化这一点,并且只使用一个相关类型:)。单元格中使用的类型实际上是由UI组件定义的 - 如果有UITextField,那么type将是String,如果我实现自定义步进器,它将是Int(例如)。如果我想让我的单元格通用,那么它应该适用于任何类型,我可以在模型和(预)定义的cellType之间编写转换器。
protocol FormTypeConverter {
associatedtype FormType
func fromModelToForm(_ value: Any?) -> FormType?
func fromFormToModel(_ value: FormType?) -> Any?
}
我可以使用如下的简单类型擦除(第一篇文章中的链接源)
struct AnyFormTypeConverter<T>: FormTypeConverter {
// MARK: - Variables
private let fromModelToFormWrapper: (Any?) -> T?
private let fromFormToModelWrapper: (T?) -> Any?
init<Y: FormTypeConverter>(_ formTypeConverter: Y) where Y.FormType == T {
self.fromModelToFormWrapper = formTypeConverter.fromModelToForm
self.fromFormToModelWrapper = formTypeConverter.fromFormToModel
}
func fromModelToForm(_ value: Any?) -> T? {
return fromModelToFormWrapper(value)
}
func fromFormToModel(_ value: T?) -> Any? {
return fromFormToModel(value)
}
}
此案例实施非常适合。已经实现了两种完全不同的形式:)