I have a protocol
protocol doSomethingProtocol {
associatedtype someType
}
then i have class that is implementing this protocol
class doSomethingClass : doSomethingProtocol {
typealias someType = Int
}
Now i want to use this protocol as a reference in some other class
class someClass : ObservableObject {
private var reference : doSomethingProtocol
}
Now i cannot do this as doSomethingProtocol has an associatedtype. So i decide to use some
class someClass : ObservableObject {
private var reference : some doSomethingProtocol
init(){
reference = doSomethingClass()
}
}
However this doesn't work. I get the error Property declares an opaque return type, but has no initializer expression from which to infer an underlying type. Why ? I am giving it initializer expression in the class init.
However when i do something like this
class someClass : ObservableObject {
private var reference : some doSomethingProtocol = doSomethingClass()
init(){}
}
I get no error messages and it compiles. Why, what is the difference between the two.
This is where you went wrong. Opaque (
some) types solve a completely different problem than protocols with associated types. An opaque type is concrete. It is one, specific type, known at compile time, returned by a function. It just is not known to the caller of the function. It is completely known to the compiler.Given this information, what concrete type is
reference? It's not known. It's hinted at by the behavior ofinit, but it's not known to always be that. (Even more so since this is a class that could override itsinitand assign some other type.)What you're trying to do is done this way:
This defines SomeType == DoSomethingClass, and allows DoSomethingClass to conform to DoSomethingProtocol.
If you're trying to avoid nailing down the type that DoSomethingClass uses here, that's not possible. To conform to a protocol with an associated type, you must provide a concrete type that can be determined at compile time.
Given the problems your running into, I suspect that DoSomethingClass is incorrectly designed, and you don't really want a PAT (protocol with associated type) here. You probably want a generic, or composition, or possibly closures. It is possible (though unlikely) that you want a type eraser. But you don't want opaque types.
(Please capitalize your types. Having leading lowercase for a type is very confusing in Swift.)