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).name
which works. However, I am wondering why theSelf Syntax
is 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