Why is "required" not a valid keyword for class functions in Swift?

There seem to be several situations where the required

Swift class function keyword would be extremely useful, especially because of the ability of the class functions to return Self

.

When returning Self

from class func

, unfortunately, there are two limitations that make the implementation of the said function very difficult / forbidden:

  • You cannot use Self

    as type checking inside a function implementation, that is:

    class Donut {
        class func gimmeOne() -> Self {
            // Compiler error, 'Self' is only available in a protocol or as the result of a class method
            return Donut() as Self
        }
    }
    
          

  • You cannot return the actual type of the class itself, that is:

    class Donut {
        class func gimmeOne() -> Self {
            // Compiler error, 'Donut' is not convertible to 'Self'
            return Donut() 
        }
    }
    
          

The reason for these compiler errors is valid. If you have a subclass GlazedDonut

that does not override that class function, it is possible that the call GlazedDonut.gimmeOne()

will return you Donut

which is not Self

.

It seems that this situation can be mitigated by allowing classes to define these functions using required

. This would ensure that any subclasses override this method and complete their own round of type checking, making sure that a is GlazedDonut

returned in all cases, excluding the possibility of returning Donut

.

Is there a technical, authoritative reason why this was not added? I would like to suggest this as an improvement for the Swift team, but I want to make sure there is no obvious reason why it has been omitted or cannot be followed.

The idea behind this question comes up here:

stack overflow

+3


source to share


2 answers


required

usually only used for initializers, since initializers are not always inherited in Swift. Therefore, to allow you to call an initializer on a variable class (i.e., a metaclass type value, for example Foo.Type

), you need to know that this class Foo

and all possible subclasses have this initializer.

However, methods (both instance methods and class methods) are always inherited. Therefore required

it is not required.



By the way, your statement that "you cannot return the actual type of the class itself" is not correct. (In fact, the "Self" error is only available in the protocol or as a result of a class method "itself says that you can return the type of the class itself.) As in Objective-C, you can do:

class Donut {
  required init() { }
  class func gimmeOne() -> Self {
    return self()
  }
}

      

+1


source


You can use a protocol to make the method "required"



protocol IDonut{
    class func gimmeOne()->Donut;
}

class Donut:IDonut {
    class func gimmeOne() -> Donut {
        return Donut();
    }
}

class GlazedDonut: Donut, IDonut{
    override class func gimmeOne()->Donut{
        return GlazedDonut();
    }
}

      

+1


source







All Articles