Swift泛型:使用泛型类型的属性扩展非泛型类型,其中泛型参数是扩展类型

时间:2020-05-18 13:40:57

标签: swift generics

问题

我有一个类型,该类型带有一个从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作为扩展属性的通用参数?

1 个答案:

答案 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()
}

输出:

demo

相关问题