Вдохновленный подходом RxSwift, вот решение, которое предоставляет доступ как к экземпляру, так и к статическим членам расширения my
.
Прежде всего, давайте объявим основу для расширения:
struct MyExtension<Target> {
let target: Target
init(_ target: Target) {
self.target = target
}
}
Давайте позволим типам соответствовать:
protocol MyExtensionCompatible { }
extension MyExtensionCompatible {
// instance extension
var my: MyExtension<Self> { return MyExtension(self) }
// static extension
static var my: MyExtension<Self>.Type { return MyExtension<Self>.self }
}
Теперь давайте начнем играть и добавим соответствие UIColor
:
extension UIColor: MyExtensionCompatible { }
extension MyExtension where Target == UIColor {
static var customColor: UIColor { return UIColor.blue }
func toImage() -> UIImage {
return UIImage()
}
}
Наконец, давайте использовать все, что мы создаливыше:
// the static property
let color = UIColor.my.customColor
// the instance function
let colorImage = color.my.toImage()
// foldoesn't compile, compile, we haven't declared UILabel as compatible
let color2 = UILabel.my
Что хорошо в вышеупомянутом подходе, так это то, что методы, объявленные как статические, будут доступны через свойство статического протокола, а экземпляры - через свойство протокола экземпляра.