[英]How to override computed property of protocol extension in Swift
I want to implement a theming in a way, that a feature can add its needed colors to a Theme protocol, so that any actual theme implementation must provide colors for every feature. 我想以某种方式实现主题化,即功能可以将其所需的颜色添加到主题协议中,以便任何实际的主题实现都必须为每个功能提供颜色。 I also want to have the theme implementation and feature theme requirements in separate files.
我还希望在单独的文件中具有主题实现和功能主题要求。 I don't want to remove lines of code manually, if I move either theming or feature into another project.
如果将主题或功能部件移动到另一个项目中,我不想手动删除代码行。
import UIKit
protocol Theme {
static var genericColor: UIColor { get }
}
protocol FeatureTheme {
static var featureColor: UIColor { get }
}
extension Theme {
static var feature: FeatureTheme.Type! {
return nil
}
}
struct LightTheme: Theme {
static var genericColor: UIColor { return .white }
static var feature: FeatureTheme.Type! { return Feature.self }
struct Feature: FeatureTheme {
static var featureColor: UIColor { return UIColor.red }
}
}
let currentTheme: Theme.Type = LightTheme.self
print(currentTheme) // LightTheme
print(currentTheme.feature.featureColor) // error, because feature is nil
So, I wanted to add the FeatureTheme requirement to the Theme protocol via extension. 因此,我想通过扩展将FeatureTheme需求添加到主题协议中。 Swift wants to see a default implementation in a protocol extension.
Swift希望在协议扩展中看到默认的实现。 I wanted to 'override' it in the actual LightTheme implementation, but that does not work.
我想在实际的LightTheme实现中“覆盖”它,但这不起作用。 The property still returns nil.
该属性仍然返回nil。 How can I solve this?
我该如何解决?
You have done is correct but if you observe your code 您所做的是正确的,但是如果您遵守自己的代码
let currentTheme: Theme.Type = LightTheme.self
currentTheme
is type of Theme
however you have assigned LightTheme
which is now Theme
and in your protocol currentTheme
是Theme
类型,但是您已将LightTheme
分配为Theme
并且已在您的协议中
extension Theme {
static var feature: FeatureTheme.Type! {
return nil
}
}
You have nil
returned as default implementation which is executing because currentTheme
is Theme
Type not LightTheme
and it is not required properly as well 您已返回
nil
作为正在执行的默认实现,因为currentTheme
是Theme
类型而不是LightTheme
,并且也没有正确要求
With current implementation Solution is simple again is to declare currentTheme
as LightTheme
See below answer 使用当前实现,解决方案很简单,就是将
currentTheme
声明为LightTheme
参见以下答案
let currentTheme: LightTheme.Type = LightTheme.self
OR 要么
Keep currentTheme
to simply assign LightTheme
Like below 保持
currentTheme
即可像下面那样简单分配LightTheme
let currentTheme = LightTheme.self
Hope it is helpful to you 希望对您有帮助
Output :
输出:
LightTheme UIExtendedSRGBColorSpace 1 0 0 1
LightTheme UIExtendedSRGBColorSpace 1 0 0 1
The extension of Theme
does not add any requirements to the protocol, it just adds a computed static property to anything of type Theme.Type
. Theme
的扩展不会对协议添加任何要求,它只是将计算出的静态属性添加到Theme.Type
类型的任何内容中。 You therefore don't override the default implementation of feature
for anything that is a Theme.Type
. 因此,对于任何
Theme.Type
,您都不会覆盖feature
的默认实现。 That would only be the case if feature
were an actual requirement of the protocol. 只有
feature
是协议的实际要求时,情况才会如此。 Maybe something like this: 也许是这样的:
protocol Theme {
static var feature: FeatureTheme.Type { get }
static var genericColor: UIColor { get }
}
protocol FeatureTheme {
static var featureColor: UIColor { get }
}
struct LightTheme: Theme {
static var genericColor: UIColor { return .white }
static var feature: FeatureTheme.Type { return Feature.self }
struct Feature: FeatureTheme {
static var featureColor: UIColor { return UIColor.red }
}
}
let currentTheme: Theme.Type = LightTheme.self
print(currentTheme) // "LightTheme"
print(currentTheme.feature.featureColor) // "UIExtendedSRGBColorSpace 1 0 0 1"
Then there would also be no need for feature
to be optional and force unwrapped. 然后,也就不需要
feature
是可选的并强制展开。
Sorry for misunderstand in comments. 很抱歉在评论中有误解。
Here are two solutions: 这是两个解决方案:
1. It's @Prashant Tukadiya 's answer. 1.这是@Prashant Tukadiya的答案。 Declare
currentTheme
as LightTheme
. 将
currentTheme
声明为LightTheme
。
2. I think, however, you need to make it have to be Theme.type
for some reason. 2.但是,我认为由于某种原因,您必须将其设置为
Theme.type
。 So declare feature
as Theme
protocol's property that can(should) be overridden. 因此,将
feature
声明为Theme
协议的属性,可以(应该)将其重写。
protocol Theme {
static var genericColor: UIColor { get }
static var feature: FeatureTheme.Type! { get }
}
If you didn't do this, the definition of Theme.feature
is just a static property of Theme
. 如果您不这样做,则
Theme.feature
的定义只是Theme
的静态属性。 Then LightTheme.feature
isn't inherited from Theme
. 然后
LightTheme.feature
不会从Theme
继承。 And If you did this, Theme.feature
can(should) be implemented in subclass. 如果这样做,
Theme.feature
可以(应该)在子类中实现Theme.feature
。 You defined a default implementation in Theme
's extension and can also override it. 您在
Theme
的扩展中定义了默认实现,也可以覆盖它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.