Context
I am currently working with Protocols and encountered a problem. My Protocol has a Static Type and I would like to access it from an Instance of a Struct conforming to this Protocol. However, this results in the following Compiler Error:
Compiler Error: Value of type 'any Component' has no member 'Self'
Code
protocol Component {
static var name: String { get set }
}
struct ComponentA: Component { static var name: String = "Component A" }
struct ComponentB: Component { static var name: String = "Component B" }
struct MainView: View {
var body: some View {
Text(component.Self.name) // Compiler Error (see Context)
}
private var component: any Component {
// Returns any component (ComponentA or ComponentB).
}
}
Question
How can I access the Type of the Instance conforming to the Protocol, e.g. ComponentA or ComponentB with the Self Syntax?
Note: I also tried
type(of: component).namewhich works. However, I am wondering why theSelf Syntaxis giving me aCompiler Error.
CodePudding user response:
The reason why component.Self doesn't work is because Self is a type, and you are using it like a member of component. component.Self doesn't make sense for the same reason that 1.Int, or "foo".String doesn't make sense. component doesn't have a member called Self.
You can, however, add a member called Self to Component using an extension:
extension Component {
var Self: Self.Type { type(of: self) }
}
Now your component.Self.name would work.
But I don't quite see much point in doing this, when just writing type(of: component).name works as well.
Side note: unlike component.Self that doesn't make sense, type(of: component) is an expression (a function call to be specific) of type any Component.Type. This is what allows you to access name, because any Component.Type does have a member called name.
See also: Self Types in the Swift Language Reference
