How can I return instancetype in Swift [duplicate]
You can do it. Playground code below. It's self() that niceObject() has to return. Additionally, you must have a required
init on the base class.
class A {
required init() {
}
func whatClassAmI() -> String {
return "Class A"
}
}
class B: A {
required init() {
super.init()
}
override func whatClassAmI() -> String {
return "Class B"
}
}
let a = A()
let sa = a.whatClassAmI() // "Class A", of course
let b = B()
let sb = b.whatClassAmI() // "Class B", of course
extension A {
class func niceObject() -> Self {
return self.init()
}
}
let aa = A.niceObject()
let saa = aa.whatClassAmI() // "Class A"
let bb = B.niceObject()
let sbb = bb.whatClassAmI() // "Class B", as required
There is a keyword Self
which is allowed in two places - in protocols (see Jean-Philippe Pellet's answer) and as a result of class
methods:
extension A {
class func niceObject() -> Self? {
return nil
}
}
Unfortunately, this won't help you because the following is invalid
extension A {
class func niceObject() -> Self? {
//A can't be converted to Self
return A()
}
}
The error is caused by the fact that when you inherit from A
class B : A {
}
then
var b = B.niceObject()
would actually return an A
instance which is not convertible to Self
(Self
is B
)
@Grimxn found the correct solution (See his answer):
You have to add a required initializer to the base class, e.g.
class A {
@required init() {
}
}
and then you can call the initialiser using self()
extension A {
class func niceObject() -> Self {
return self()
}
}
At least in procotols, you can use Self
. This represents the actual type of self
. Not sure about extensions, though...
For instance, see the definition of Equatable
:
protocol Equatable {
func ==(lhs: Self, rhs: Self) -> Bool
}