Swift 5.1 Released
Swift 5.1 builds on the strengths of Swift 5 by extending the stable features of the language to compile time with the introduction of module stability. With module stability it’s now possible to create and share binary frameworks that will work with future releases of Swift. Swift 5.1 also extends the capabilities of the language and the standard library with new features such as property wrappers, opaque result types, key path member lookup, diffing for appropriate collection types, and new APIs for String. Altogether the new features of Swift 5.1 make it easier to design better APIs and reduce the amount of common boilerplate code.
While that’s still possible, the scope of
Self
has now been extended to also include concrete types — like enums, structs and classes — enabling us to useSelf
as a sort of alias referring to a method or property’s enclosing type, like this[…]
Note that this is just syntactic sugar. It’s not like instancetype
in Objective-C.
Previously:
Update (2019-09-24): As Joe Groff notes, I misinterpreted Sundell’s comments about Self
. It doesn’t refer to the lexically enclosing type, but rather to the dynamic type. So, when used in an expression, it’s like type(of: self)
:
class Base { class func printClass() { print("Base") } func selfPrintClass() { Self.printClass() } } class Derived: Base { override class func printClass() { print("Derived") } } Derived().selfPrintClass() // prints Derived
This will be useful when calling helper functions from initializers.
His comment that it’s “purely syntactic sugar” only applies to this use of Self
. When used to specify the return type, Self
is not a mere substitution of the current class name. Instead, it refers to the type of the object (not the type that the method was defined on). So it’s just like instanceof
in Objective-C. And you can similarly use it to declare factory methods, in which case Swift will require you to implement them in terms of required
initializers:
class Base { required init() {} // must be provided unless Base is final class func make() -> Self { return Self.init() } } class Derived: Base {} Base.make() // makes a Base Derived.make() // makes a Derived
So, Self
is really cool, and it can now be used in many more places than before. It’s still not allowed as a parameter type, though. I have a case where I want to ensure that a method has a parameter of the receiver’s own type. I wasn’t able to do this with Self
, but I found a workaround using a protocol with an associated type.
1 Comment RSS · Twitter
Self
in Swift is exactly like instancetype
in Objective-C. What's changed in Swift 5.1 is that you can also use Self
to refer to the dynamic type inside method and property bodies, when previously it was only allowed as the return type for methods.