Reputation: 4373
Take this code:
protocol P: class {
static var hello: String { get }
}
class A: P {
class var hello: String {
return "Hello"
}
}
class B: A {
override static var hello: String {
return "Hello World"
}
}
class C: A {}
class D: C {
override static var hello: String {
return "Hello D"
}
}
func sayHello(elements: P.Type...) {
for p in elements {
print(p.hello)
}
}
func sayHelloAgain(elements: A.Type...) {
for p in elements {
print(p.hello)
}
}
func sayHelloThe3rd(elements: [A.Type]) {
for p in elements {
print(p.hello)
}
}
sayHello(A.self, B.self, C.self)
sayHelloAgain(A.self, B.self, C.self)
Compare it to this (taken from this presentation)
func register<T: UITableViewCell where T: ReusableView, T: NibLoadableView>(_: T.Type) { ... }
tableView.register(FoodTableViewCell)
Why do I have to use A.self in one case, but not in the other? And also, don't need to use .self when calling with one argument.
sayHello(A)
sayHello(A, B) //doesn't compile
Upvotes: 4
Views: 114
Reputation: 63167
The .self
is syntactic salt. It's not necessary from a technical perspective, but it exists to cause errors in code that's often a result of a typo, such as:
struct Foo { }
let foo = Foo
This code will give you a compiler error, telling you that either you need to complete the initializer/function/method call, or append .self
if you meant to refer to the type.
In the latter example, the context deals exclusively with types and not values, so there's no chance of confusing one with the other, thus, .self
isn't necessary.
Perhaps there's a way to modify the function declaration in your example so as to not require the .self
, but I'm not aware of such a feature. I'd be interested to find out.
Upvotes: 2