我有一个类型,该类型带有一个从UIView
继承的通用参数:
class Handler<View: UIView> {
...
}
现在,我想编写一个UIView extension
来提供一个返回Handler
并使用Self
作为通用参数的属性,以便在UIView
的子类中总是获取类型为Handler<UIViewSubclass>
的处理程序:
extension UIView {
var handler: Handler<Self>? { return nil }
}
但是这不能编译:
协变“自我”只能出现在属性类型的顶层
我还尝试过首先定义协议HandlerProvider
:
public protocol HandlerProvider {
associatedtype View: UIView
var handler: Handler<View>? { get }
}
(到目前为止很好),然后使用该协议扩展UIView
:
extension UIView: HandlerProvider {
public typealias View = Self
public var handler: Handler<View>? { return nil }
}
但这也不编译:
协变“ Self”只能作为属性,下标或方法结果的类型出现;你是说'UIView'吗?
Swift中是否可以使用Self
作为扩展属性的通用参数?
答案 0 :(得分:1)
这里是可行的方法(与泛型思考的方向有所不同)。
已通过Xcode 11.4 / swift 5.2测试
// base handling protocol
protocol Handling {
associatedtype V: UIView
var view: V { get }
init(_ view: V)
func handle()
}
// extension for base class, will be called by default for any
// UIView instance that does not have explicit extension
extension Handling where V: UIView {
func handle() {
print(">> base: \(self.view)")
}
}
// extension for specific view (any more you wish)
extension Handling where V: UIImageView {
func handle() {
print(">> image: \(self.view)")
}
}
// concrete implementer
class Handler<V: UIView>: Handling {
let view: V
required init(_ view: V) {
self.view = view
}
}
// testing function
func fooBar() {
// handlers created in place of handling where type of
// handling view is know, so corresponding handle function
// is used
Handler(UIView()).handle()
Handler(UIImageView()).handle()
}
输出: