Reputation: 36317
I've read the In swift, why can't I instantiate a protocol when it has an initialiser?
My question is focused on why the compiler can't look into your default implementation and initialize an object based on that?
protocol ViewModel {
var radius: Int { get }
init()
}
extension ViewModel {
var radius: Int { return 2}
init() {}
}
let v = ViewModel() // ERROR:
Protocol type 'ViewModel' cannot be instantiated
Question1:
Why doesn't Swift allow a vanilla initialization of a protocol? Why does it have to be tied to a concrete type?
I get it that it's not a concrete type. But why doesn't the compiler allow you to just create a type that is nothing but the protocol in its default value?! Is it because the compiler is like hey listen while I can either think of you as an interface/protocol or as an actual type. I can't think of you as both!? You're either something real in memory or just a blue-print.
If the language could have checked to see if an extension has provided implementation for all requirements then would it have made sense to allow initializing that as a special case? (I understand that it doesn't, but wondering is that the only thing needed to get this to work) Or even then this would have not made sense. If so why?
Additionally I tried do this instead:
protocol ViewModel {
var radius: Int { get }
init()
}
extension ViewModel {
var radius: Int { return 2}
init() {
self.init() // Line A:
}
}
struct ReallyNothing: ViewModel {}
let v = ReallyNothing()
If I comment out LineA then I'll get an error of
'self.init' isn't called on all paths before returning from initializer
Question2:
WHY? why does the init
have to call self.init()
it seems a bit like a recursive loop.
Upvotes: 0
Views: 1843
Reputation: 535557
This has nothing to do with what whether ViewModel has an init
. It has to do with what ViewModel is. It is a protocol.
A protocol is not an object. There is no such thing as an instance of a protocol. What would it mean to "instantiate" a protocol? Nothing. You can make an instance of:
A protocol is none of those. You cannot make an instance of a protocol.
ViewModel is a protocol. So you cannot make an instance of it. The phrase ViewModel()
is meaningless. And the compiler tells you so.
Upvotes: 1
Reputation: 54745
A protocol is not a concrete type, so when you would call Protocol.init()
, the compiler wouldn't know what concrete type to initialise. It would only know that the type you want to initialise has the interface described by Protocol
.
The compiler has to know the concrete type because of the memory allocation. A protocol only defines a subset of required properties (and methods) that its conformant types must have, but doesn't define the whole set of properties its conformant types will have, since that actually differs type-by-type. Due to this, if you were to able to initialise a protocol type, the compiler and the runtime would have no idea about how much memory to allocate for that particular object, which is a piece of information without which no object can be initialised.
Upvotes: 2
Reputation: 413
https://docs.swift.org/swift-book/LanguageGuide/Protocols.html
Protocols are blueprints and don't contain implementation- so you can't initialize them.
A class agrees to protocol and must provide the actual implementation.
Upvotes: 0