Can only return, not assign, Self?

2019-07-29 05:34发布

问题:

Consider this pattern

extension UIViewController
{
    class func make(sb: String, id: String) -> Self
    {
        return helper(sb:sb, id:id)
    }

    private class func helper<T>(sb: String,id: String) -> T
    {
        let s = UIStoryboard(name: storyboardName, bundle: nil)
        let c = s.instantiateViewControllerWithIdentifier(id) as! T
        return c
    }
}

that works fine, so

let s = SomeViewControllerClass.make( ... )

does in fact return the subclass "SomeViewControllerClass". (Not just a UIViewController.)

That's all fine BUT,

say in make you want to do some setup:

    class func make(sb: String, id: String) -> Self
    {
        let h = helper(sb:sb, id:id)
        // some setup, m.view = blah etc
        return h
    }

in fact it appears you cannot do that.

You can only

        return helper(sb:sb, id:id)

you cannot

        let h = helper(sb:sb, id:id)
        return h

is there a solution?

回答1:

Of course there is a solution. That's exactly what the helper function is doing.

Why don't you put the code into helper?

To invoke helper, which is a generic type, you have to specify the type somehow, e.g.

let h: Self = helper(...)

or

let h = helper(...) as Self

but neither of those expressions would actually accept Self. Therefore, you need to infer the type from the return value -> Self. That's why return is the only thing that works.

Also note that you can use a second helper function.

class func make(sb: String, id: String) -> Self {
    let instance = helper2(sb: sb, id: id)        
    return instance
}

class func helper2(sb: String, id: String) -> Self {
    return helper(sb:sb, id:id)
}