A/c to Apple Doc,
A function or method with an opaque return type hides its return value’s type information. Instead of providing a concrete type as the function’s return type, the return value is described in terms of the protocols it supports
EDIT: Cutting the whole question short
/* PROTOCOLS */
protocol MyPros {}
/* STRUCT */
struct MyStruct {}
/* CLASSES */
class ClassA : MyPros {}
class ClassB : ClassA {}
class ClassC : ClassB {}
Now I using Opaque return type, 1. with struct 2. with class
/* FUNCTIONS */
func getOpaqueStruct() -> some MyStruct { // ERROR: An 'opaque' type must specify only 'Any', 'AnyObject', protocols, and/or a base class
return MyStruct()
}
func getOpaqueClass() -> some ClassC {
return ClassC()
}
getOpaqueStruct
returns error which is understandable, if you check getOpaqueClass
, getOpaqueClass also not returning protocols, and/or a base class so why class object able to return any class object in the inheritance chain. It also must be returns the baseclass i.e. classA or protocol i.e. MyPros.
ClassC
can be in future be superclass of ClassD but base class of these chain is ClassA
.
I think you are misunderstanding what the phrase "base class" in the error message means. It doesn't mean "a class that doesn't inherit from anything, and can have subclasses". It just means "a class that can have subclasses" or in other words, "a class that other classes can inherit from".
Why only limit the feature to classes that doesn't inherit from anything, when anything that could have subclasses can benefit from this feature.
Old answer (to revision 3 of the question):
You can't do some StructType
because structs don't have subclasses. They whole point of opaque return types is to allow you to tell the caller that:
I'm returning a definite type, but you don't need to know what type this is. You just need to know it is a subclass of
XXXClass
/confomer ofYYYProtocol
.
No other types can inherit from structs, so if you have a method that is said to return some StructType
, then it can only return StructType
, nothing else. This defeats the purpose of opaque return types.
From the name of your method, writing:
func getPlanet() -> some Planet {
return Earth(name: "Earth", creatures: "Humans")
}
would make more sense in my opinion.
The caller knows that getPlanet
will return a definite type, that is a conformer of Planet
.