Swift Extensions, care and feeding

Extensions in Swift seem to have a lot of promise, but I've not really found a way of using them to structure large/complex types that feels just right. I'd like to know how others are using extensions and maybe get some ideas to help structure my code.


Here are some of the obvious uses for extensions (some of these are even recommended in "The Swift Programming Language"), and some of the issues I've run into when using them:


Use Case: separate logical or semantic sections of code

Problems:

  1. Since extensions can only contain functions or computed properties, any stored properties that otherwise relate to this section of code still have to go in the "main" declaration of the type.
  2. If the class is intended for extending, any vars or functions intended for overriding cannot be placed in the extension

Result: Code organized into logical & semantic sections... Except when it isn't


Use Case: separating large types into multiple files

Problems:

  1. Since the 'private' visibility modifier is file- not type-specific, there is no way to hide internal implementations from other code (and autocomplete) within a large application.
  2. see #1 from previous use-case

Result: Otherwise 'private' implementation details of the type are instead effectively 'public' (in application code, there's no practical difference between 'public' and 'internal')

Use Case: separating protocol conformance

Problems:

This generally works fine, unless your implementation happen to run afoul of the above problems.

Result: Fine... unless your protocol conformance needs a stored property for its implementation, then... Oh well.


Anyway, this post isn't intended to be just a gripe list... I'm genuinely seeking ideas on how to better utilize this language feature, and/or how others get around some of the limitations described above.

Replies

Swift extensions are like ObjC categories I take it. I haven't done much Swift, but from what you describe they seem to be pretty much the same thing and I use categories a lot.


You don't get ivars in ObjC categories either (no storage). That has always been the intended behavior. I guess it'd be too messy to worry about adding properties on objects which may already have those properties that are private...


Normally I use them to add utility methods that I think are missing. Also a property like: isEntireStringWhitespace, which is of course computed. isStringAValidURL. Another common use case is to add your own NSColor factory methods for custom colors you use a lot in your app, so you don't have to type ugly RGB values in a million places.


self.waterView.backgroundColor = [NSColor waterColor];


There is no waterColor method on NSColor, it has been added in a category. Scrit like that...is typically how you use categories. Much nicer to see waterColor than r g b a params.


In ObjC if you really need to add a property that isn't computed... you normally get around this by using associated objects but you should only do this if you really need to do this. If you do really need to do this, you should be able to do it with the Swift, I'd imagine. Google something like: "properties in Objective-C categories"... see if you can do it in Swift.


Dropping the Elbow from the Top Turnbuckle.

>I've not really found a way of using them to structure large/complex types that feels just right.


Be careful of mis-calibrating expectations... Swift is still young, still being fleshed out, still finding itself - it won't turn the corner where the new wears off for some time yet, so if you're expecting comfort similar to other, time-worn langs, it might be too early to hope for that kind of relationship just yet.


In the mean time, file bugs and be patient.