How to return instancetype?

I have a class A that has a subclass B.
B inherits a method foo from A, and foo is a function that returns the instance itself.
Because foo is inherited however, it is defined as returning type A, not B.
How can I write it so that every subclass of A that inherits foo will have a foo that returns the subclass's type of object?

1 Like

Declare the function as returning Self in A:

class A {
    func foo() -> Self { return self }
}

class B: A {}

let a = A()
let a2: A = a.foo()
let b = B()
let b2: B = b.foo()
4 Likes

The code still compiles if the return type is the more specific type. However, Self feels more natural, and saves you from typing long class names.

@main
enum Latest {
    static func main () throws {
        let a = A()
        use (a)
        
        let b = B()
        use (b)
        
        let b2: A = b.foo ()
        use (b2)
    }
}

class A {
    func foo() -> A {
        print (type (of:self), #function)
        return self
    }
}

class B: A {
    override func foo() -> B {
        print (type (of:self), #function)
        return self
    }
}

func use (_ it: A) {
    _ = it.foo ()
}

// Prints
A foo()
B foo()
B foo()
B foo()

1 Like

Interesting. What if I wanted to do the same with a closure/block? Suppose I want to pass into it self and then return self. Is it necessary to put self in brackets i.e. { [self], parameter1, parameter2 in ...} even if it is just one of several parameters?